From 1a475f737311065fd4351303db2853649e027a9a Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 18 Oct 2022 19:31:26 +0200 Subject: [PATCH] Next level elevation - Added the Contraption Controls - Added the Elevator Pulley - Pulley ropes are now climbable - Lowered hitbox of seats for improved traversability inside contraptions - Improved safety for players standing on vertically moving contraptions - Fixed seated entities on controlled contraptions not rendering at the correct location - Multiple pulleys can now attach to contraptions in a synchronised group - Display Boards now update text instantaneously at high input rpm --- src/generated/resources/.cache/cache | 51 +-- .../blockstates/contraption_controls.json | 124 +++++++ .../create/blockstates/elevator_contact.json | 212 ++++++++++++ .../create/blockstates/elevator_pulley.json | 19 ++ .../resources/assets/create/lang/en_ud.json | 3 + .../resources/assets/create/lang/en_us.json | 12 + .../assets/create/lang/unfinished/de_de.json | 14 +- .../assets/create/lang/unfinished/es_cl.json | 14 +- .../assets/create/lang/unfinished/es_es.json | 14 +- .../assets/create/lang/unfinished/fr_fr.json | 14 +- .../assets/create/lang/unfinished/it_it.json | 14 +- .../assets/create/lang/unfinished/ja_jp.json | 14 +- .../assets/create/lang/unfinished/ko_kr.json | 14 +- .../assets/create/lang/unfinished/nl_nl.json | 14 +- .../assets/create/lang/unfinished/pl_pl.json | 14 +- .../assets/create/lang/unfinished/pt_br.json | 14 +- .../assets/create/lang/unfinished/pt_pt.json | 14 +- .../assets/create/lang/unfinished/ro_ro.json | 14 +- .../assets/create/lang/unfinished/ru_ru.json | 14 +- .../assets/create/lang/unfinished/uk_ua.json | 14 +- .../assets/create/lang/unfinished/zh_cn.json | 14 +- .../assets/create/lang/unfinished/zh_tw.json | 14 +- .../models/item/contraption_controls.json | 3 + .../create/models/item/elevator_contact.json | 3 + .../create/models/item/elevator_pulley.json | 3 + .../blocks/contraption_controls.json | 20 ++ .../loot_tables/blocks/elevator_contact.json | 20 ++ .../loot_tables/blocks/elevator_pulley.json | 20 ++ .../data/minecraft/tags/blocks/climbable.json | 4 +- .../minecraft/tags/blocks/mineable/axe.json | 3 + .../tags/blocks/mineable/pickaxe.json | 3 + .../com/simibubi/create/AllBlockPartials.java | 9 + .../java/com/simibubi/create/AllBlocks.java | 58 +++- .../create/AllMovementBehaviours.java | 2 +- .../java/com/simibubi/create/AllShapes.java | 12 +- .../com/simibubi/create/AllSpriteShifts.java | 7 +- .../com/simibubi/create/AllTileEntities.java | 31 +- .../actors/DrillMovementBehaviour.java | 5 +- .../actors/HarvesterActorInstance.java | 31 +- .../actors/HarvesterMovementBehaviour.java | 5 +- .../actors/PloughMovementBehaviour.java | 5 +- .../actors/SawMovementBehaviour.java | 5 +- .../components/actors/SeatBlock.java | 5 +- .../controls/ContraptionControlsBlock.java | 65 ++++ .../controls/ContraptionControlsMovement.java | 239 +++++++++++++ .../ContraptionControlsMovingInteraction.java | 127 +++++++ .../controls/ContraptionControlsRenderer.java | 52 +++ .../ContraptionControlsTileEntity.java | 152 +++++++++ .../ContraptionDisableActorPacket.java | 74 ++++ .../deployer/DeployerActorInstance.java | 4 +- .../deployer/DeployerMovingInteraction.java | 28 +- .../components/deployer/DeployerRenderer.java | 3 +- .../AbstractContraptionEntity.java | 2 +- .../structureMovement/Contraption.java | 77 ++++- .../ContraptionCollider.java | 84 ++++- .../structureMovement/ContraptionType.java | 4 +- .../ControlledContraptionEntity.java | 16 +- .../structureMovement/MovementBehaviour.java | 19 +- .../structureMovement/MovementContext.java | 4 + .../TranslatingContraption.java | 33 +- .../StabilizedBearingMovementBehaviour.java | 6 + .../elevator/ElevatorColumn.java | 226 ++++++++++++ .../elevator/ElevatorContactBlock.java | 217 ++++++++++++ .../elevator/ElevatorContactEditPacket.java | 40 +++ .../elevator/ElevatorContactScreen.java | 171 ++++++++++ .../elevator/ElevatorContactTileEntity.java | 154 +++++++++ .../elevator/ElevatorContraption.java | 180 ++++++++++ .../elevator/ElevatorControlsHandler.java | 117 +++++++ .../elevator/ElevatorFloorListPacket.java | 103 ++++++ .../elevator/ElevatorPulleyBlock.java | 74 ++++ .../elevator/ElevatorPulleyInstance.java | 25 ++ .../elevator/ElevatorPulleyRenderer.java | 123 +++++++ .../elevator/ElevatorPulleyTileEntity.java | 316 +++++++++++++++++ .../elevator/ElevatorTargetFloorPacket.java | 73 ++++ .../piston/LinearActuatorTileEntity.java | 25 +- .../pulley/AbstractPulleyRenderer.java | 4 +- .../pulley/PulleyContraption.java | 6 +- .../pulley/PulleyRenderer.java | 20 +- .../pulley/PulleyTileEntity.java | 158 +++++++-- .../pulley/RopePulleyInstance.java | 2 +- .../burner/BlazeBurnerMovementBehaviour.java | 6 + .../deco/SlidingDoorMovementBehaviour.java | 12 +- .../source/CurrentFloorDisplaySource.java | 29 ++ .../redstone/ContactMovementBehaviour.java | 33 +- .../block/redstone/NixieTubeRenderer.java | 10 +- .../block/redstone/RedstoneContactBlock.java | 18 +- .../block/redstone/RedstoneContactItem.java | 43 +++ .../trains/entity/CarriageContraption.java | 4 +- .../display/FlapDisplaySection.java | 11 +- .../display/FlapDisplayTileEntity.java | 3 +- .../ChangeThrottleInstruction.java | 2 +- .../simibubi/create/events/InputEvents.java | 4 +- .../foundation/command/AllCommands.java | 2 +- .../data/recipe/StandardRecipeGen.java | 2 +- .../create/foundation/gui/AllGuiTextures.java | 2 + .../foundation/networking/AllPackets.java | 10 + .../ponder/content/PonderIndex.java | 6 +- .../tileEntity/behaviour/ValueBox.java | 11 +- .../behaviour/ValueBoxRenderer.java | 46 ++- .../filtering/FilteringRenderer.java | 6 +- .../assets/create/lang/default/interface.json | 10 + .../block/contraption_controls/block.json | 104 ++++++ .../block/contraption_controls/button.json | 56 +++ .../contraption_controls/indicator_0.json | 52 +++ .../contraption_controls/indicator_1.json | 52 +++ .../contraption_controls/indicator_2.json | 52 +++ .../contraption_controls/indicator_3.json | 52 +++ .../contraption_controls/indicator_4.json | 52 +++ .../contraption_controls/indicator_5.json | 52 +++ .../contraption_controls/indicator_6.json | 52 +++ .../contraption_controls/indicator_7.json | 52 +++ .../block/contraption_controls/item.json | 124 +++++++ .../models/block/elevator_contact/block.json | 82 +++++ .../block/elevator_contact/block_dim.json | 8 + .../block/elevator_contact/block_powered.json | 8 + .../models/block/elevator_pulley/block.json | 151 ++++++++ .../models/block/elevator_pulley/item.json | 250 ++++++++++++++ .../block/elevator_pulley/pulley_magnet.json | 41 +++ .../models/block/elevator_pulley/rope.json | 31 ++ .../block/elevator_pulley/rope_coil.json | 42 +++ .../block/elevator_pulley/rope_half.json | 39 +++ .../models/block/mechanical_drill/item.json | 10 +- .../block/mechanical_harvester/item.json | 323 +++++++++--------- .../models/block/mechanical_plough.json | 7 +- .../models/block/mechanical_saw/item.json | 197 +++++------ .../textures/block/contraption_controls.png | Bin 0 -> 7358 bytes .../block/contraption_controls_frame.png | Bin 0 -> 3408 bytes .../block/contraption_controls_indicator.png | Bin 0 -> 2945 bytes .../textures/block/elevator_contact_side.png | Bin 0 -> 330 bytes .../block/elevator_contact_side_dim.png | Bin 0 -> 361 bytes .../block/elevator_contact_side_powered.png | Bin 0 -> 357 bytes .../create/textures/block/elevator_pulley.png | Bin 0 -> 795 bytes .../textures/block/elevator_pulley_belt.png | Bin 0 -> 394 bytes .../block/elevator_pulley_belt_scroll.png | Bin 0 -> 409 bytes .../textures/block/elevator_pulley_coil.png | Bin 0 -> 306 bytes .../block/elevator_pulley_coil_scroll.png | Bin 0 -> 277 bytes .../textures/block/rose_quartz_lamp_dim.png | Bin 0 -> 320 bytes .../create/textures/gui/display_link.png | Bin 1164 -> 2037 bytes 138 files changed, 5615 insertions(+), 466 deletions(-) create mode 100644 src/generated/resources/assets/create/blockstates/contraption_controls.json create mode 100644 src/generated/resources/assets/create/blockstates/elevator_contact.json create mode 100644 src/generated/resources/assets/create/blockstates/elevator_pulley.json create mode 100644 src/generated/resources/assets/create/models/item/contraption_controls.json create mode 100644 src/generated/resources/assets/create/models/item/elevator_contact.json create mode 100644 src/generated/resources/assets/create/models/item/elevator_pulley.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/contraption_controls.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/elevator_contact.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/elevator_pulley.json create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlock.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovement.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovingInteraction.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsTileEntity.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionDisableActorPacket.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorColumn.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactEditPacket.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactScreen.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactTileEntity.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContraption.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorControlsHandler.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorFloorListPacket.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyBlock.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyInstance.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyRenderer.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyTileEntity.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/display/source/CurrentFloorDisplaySource.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneContactItem.java create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/block.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/button.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_0.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_1.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_2.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_3.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_4.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_5.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_6.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/indicator_7.json create mode 100644 src/main/resources/assets/create/models/block/contraption_controls/item.json create mode 100644 src/main/resources/assets/create/models/block/elevator_contact/block.json create mode 100644 src/main/resources/assets/create/models/block/elevator_contact/block_dim.json create mode 100644 src/main/resources/assets/create/models/block/elevator_contact/block_powered.json create mode 100644 src/main/resources/assets/create/models/block/elevator_pulley/block.json create mode 100644 src/main/resources/assets/create/models/block/elevator_pulley/item.json create mode 100644 src/main/resources/assets/create/models/block/elevator_pulley/pulley_magnet.json create mode 100644 src/main/resources/assets/create/models/block/elevator_pulley/rope.json create mode 100644 src/main/resources/assets/create/models/block/elevator_pulley/rope_coil.json create mode 100644 src/main/resources/assets/create/models/block/elevator_pulley/rope_half.json create mode 100644 src/main/resources/assets/create/textures/block/contraption_controls.png create mode 100644 src/main/resources/assets/create/textures/block/contraption_controls_frame.png create mode 100644 src/main/resources/assets/create/textures/block/contraption_controls_indicator.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_contact_side.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_contact_side_dim.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_contact_side_powered.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_pulley.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_pulley_belt.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_pulley_belt_scroll.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_pulley_coil.png create mode 100644 src/main/resources/assets/create/textures/block/elevator_pulley_coil_scroll.png create mode 100644 src/main/resources/assets/create/textures/block/rose_quartz_lamp_dim.png diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index c345e52681..4cb3fe1d5d 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -50,6 +50,7 @@ b59324f051f21d8ce1a48a08f4721a61a3c414d6 assets/create/blockstates/chute.json 1f33834c685e3243882acfe20183fe64dfa872be assets/create/blockstates/clutch.json e5e3757e99c139d67b2a70288466d8a74d818841 assets/create/blockstates/cogwheel.json 36f54136a7756c97f71bc6b47ef4e8e575e72879 assets/create/blockstates/content_observer.json +7ecbf72c0557d97514aadc5a794bd8720c2fc48b assets/create/blockstates/contraption_controls.json 7d11142092c89ccba3e74e0a3bdd0ccb446d63b5 assets/create/blockstates/controller_rail.json 80d71365995d4c2a61dd1c15e99cae18551af6e8 assets/create/blockstates/controls.json 961b615124ea9a5a5735e8a79f81a702de7da2cf assets/create/blockstates/copper_backtank.json @@ -199,6 +200,8 @@ ac85f55d82d96fc15750e6b954297cfd1e00d04d assets/create/blockstates/deployer.json 62cc543abb242836570d07d619fcdb4c79c75db4 assets/create/blockstates/display_board.json 6766818ea63026a3af2fb9d81110d3887c74b0f8 assets/create/blockstates/display_link.json 30b3422bfee9878c92521429b2536d3e0313cedb assets/create/blockstates/dripstone_pillar.json +8c3ab1fc1fa0f705145212c62bde4787be392ac0 assets/create/blockstates/elevator_contact.json +98eaeef191c52eaf0f08cf2251237d704a4fc9ad assets/create/blockstates/elevator_pulley.json 35fc68eb1d031d28ad09b7b603e64ae459634179 assets/create/blockstates/encased_chain_drive.json 7b2b836649e729feafa60972bf95e3afb2143131 assets/create/blockstates/encased_fan.json d13940ed213d7acbc6ebe3bdd21175ef89e4d613 assets/create/blockstates/encased_fluid_pipe.json @@ -558,24 +561,24 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo 5616dda664dd106d576848124fc0fc1de18d0fd3 assets/create/blockstates/yellow_valve_handle.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json -f85edc574ee6de0de7693ffb031266643db6724a assets/create/lang/en_ud.json -c219c77242e645f32704201dd80e279b3759b794 assets/create/lang/en_us.json -cf37534c3f98098f42b181083fd7cc1063ac2bbb assets/create/lang/unfinished/de_de.json -83d427726fdc38ec3c5b8c3c0f6f87f49d3e5ff3 assets/create/lang/unfinished/es_cl.json -d21caeb0cbe871e38dc101c34ab89ece3cbe2127 assets/create/lang/unfinished/es_es.json -2215688baa2b0beffe0c19f71a3238df1d01b0c1 assets/create/lang/unfinished/fr_fr.json -79484f2c3eba2b40f5d82ffdc3abeb3d2e6962d2 assets/create/lang/unfinished/it_it.json -d659570c9dc89653f03cd4cc82ed50db443638d8 assets/create/lang/unfinished/ja_jp.json -03c30521d9b1bc7a6eb85d2a59a4c4676dca581e assets/create/lang/unfinished/ko_kr.json -3a56d579d022cc1b20746e9d3a1483e6fa8fb4be assets/create/lang/unfinished/nl_nl.json -d5bfeacb442236c8b075fddb41364f85c8cb7feb assets/create/lang/unfinished/pl_pl.json -0f3f51d065d896a7e3b4abd8c2801fa3e8fbd8c3 assets/create/lang/unfinished/pt_br.json -9f2ec0b2f8fa9b380c7edb56bfb806bcce621cce assets/create/lang/unfinished/pt_pt.json -1f88f0d91bdf5c68224cb65249f77272771939c9 assets/create/lang/unfinished/ro_ro.json -928ac3ad2ab5e7fa3d582b8b956258c110bea868 assets/create/lang/unfinished/ru_ru.json -ed29ef4ae8f3633533485d56f7fa8cb77b790a0a assets/create/lang/unfinished/uk_ua.json -e5cf7b657be816bc15b331dd058f7ccdabee8c14 assets/create/lang/unfinished/zh_cn.json -316dae07f95fb65c984fe7c424b566eb8ddba5f9 assets/create/lang/unfinished/zh_tw.json +030897fc54ff8948c4f75c12fc0cb75b7533a7d3 assets/create/lang/en_ud.json +b1efd3b09b9b99864c62946609e2fda2b27289ca assets/create/lang/en_us.json +0674019c1a174515a411399f8072014c0262e9e3 assets/create/lang/unfinished/de_de.json +c97060d5ac1e4e1ec44e9c24ddfe981414c5d38c assets/create/lang/unfinished/es_cl.json +118ccd144daec81fd505cd09f97d55dc054a663b assets/create/lang/unfinished/es_es.json +26fc490f390650044c853be59d6b27e2bd0accc5 assets/create/lang/unfinished/fr_fr.json +d64bcf8740ef1c117148388399f332015b1a35c2 assets/create/lang/unfinished/it_it.json +cc277bc6cc78bf7c943b428321d685a64bc25ebd assets/create/lang/unfinished/ja_jp.json +0c9199e23e24af99b7878b9278308ebf63db1eb9 assets/create/lang/unfinished/ko_kr.json +086ca8f196d987b1bb0b7cfe2b285c173d46a499 assets/create/lang/unfinished/nl_nl.json +0ce3cc278b14d36493f48aeb221ce9f6e7153b3f assets/create/lang/unfinished/pl_pl.json +7ef6bb7a596f4d5ac9273a0f5e8424229ca457ee assets/create/lang/unfinished/pt_br.json +c93a7d9275c0cc755e859ad57e352b9f1e2ee2f9 assets/create/lang/unfinished/pt_pt.json +c4aaebf10dd4a94e64d0fc2f48e4242d63cc6f71 assets/create/lang/unfinished/ro_ro.json +2fddf07de6613c3d680a645325d83d925c82aebc assets/create/lang/unfinished/ru_ru.json +ab7e76507c58c93e2e0619bbf78dd1a7c6459b00 assets/create/lang/unfinished/uk_ua.json +46e97308f1bfe26232952139f99d902f7f465c1a assets/create/lang/unfinished/zh_cn.json +d0d72e70e30f7d3a02293f15acd31e042deda59b assets/create/lang/unfinished/zh_tw.json 487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json 3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json @@ -1675,6 +1678,7 @@ c1da21be9f1af4f7a2ef4ec9cd92195d65ada316 assets/create/models/item/clockwork_bea 0a2a0f0aafeab0088172f77afd40c1fa2cc1f2b8 assets/create/models/item/clutch.json dcb09deae110077bcddf090996b51cc66e9a7de3 assets/create/models/item/cogwheel.json 7717e3b21cff39f497f07687c70c1fa40eaa756d assets/create/models/item/content_observer.json +f5f1ad973341f8bebc474d5e65ff877ac6303b0d assets/create/models/item/contraption_controls.json 9dbd63c9e1b09a663fd4b83d76e3ab5967086167 assets/create/models/item/controller_rail.json 9a93b3ccef02cd0abd8106edec954dc0f2269229 assets/create/models/item/controls.json 10397036fc0bb1e18a767cfd7b19b10d805a83fe assets/create/models/item/copper_backtank.json @@ -1844,6 +1848,8 @@ df8cfe7e8eb527329094396e11222e9097e309d7 assets/create/models/item/diving_helmet 4b2af721dccfcf4e5b5a7b0f64f295d7cfd27f69 assets/create/models/item/dough.json c25cd4d5cdf67b0d7e15f5a56c63e6bf35fe2917 assets/create/models/item/dripstone_pillar.json 5c45bf31bc4b6d2c6482318f19a660ad949d796b assets/create/models/item/electron_tube.json +5958eae9379424b0bdaef0d4230185773aa351e0 assets/create/models/item/elevator_contact.json +485f89a600a98141a2826ecef5bf32a83060efbf assets/create/models/item/elevator_pulley.json 971be8e52e8dfef50c8329be83f9c5d5ea869279 assets/create/models/item/empty_blaze_burner.json 5312db341e777c79feeaec99e5cb85bb99bb76ff assets/create/models/item/empty_schematic.json cf34fd7e891a131d763126aa070d5b919e304a51 assets/create/models/item/encased_chain_drive.json @@ -3426,6 +3432,7 @@ bd4ed53c029fcd6e5da7e43ebe4d15030d3fd9de data/create/loot_tables/blocks/clockwor 8a5655e16f3da654e801cbfd81478c30180892a0 data/create/loot_tables/blocks/clutch.json 982a41e1bccd9a130a2874aff995d4f7da0f0316 data/create/loot_tables/blocks/cogwheel.json c2b075008849e152f20e8da946e89c9722325df6 data/create/loot_tables/blocks/content_observer.json +69b4b25d7d271458177fbbaeba2c797daccc38a2 data/create/loot_tables/blocks/contraption_controls.json 28856dc862efc6bcc421d035d26386740458f868 data/create/loot_tables/blocks/controller_rail.json 2c2785e39e1891dff2c50cba93e814b56d935154 data/create/loot_tables/blocks/controls.json 3abf04f6132955275ad490668cd28f481afb4ec2 data/create/loot_tables/blocks/copper_backtank.json @@ -3574,6 +3581,8 @@ b6118279802f1a27e6e0c3d0feca86f0792f85df data/create/loot_tables/blocks/depot.js 2a8d81a07e9d209349264787eee93a0b973d2510 data/create/loot_tables/blocks/display_board.json fd63effdc29cf565f561f8901a93c8ee3124bcaa data/create/loot_tables/blocks/display_link.json 7ab5f0aa32d6641999943636766c806a1d59e1d2 data/create/loot_tables/blocks/dripstone_pillar.json +5ef611585677ea3108fa034b2629434a98a9bb5c data/create/loot_tables/blocks/elevator_contact.json +3dd62aeec55972379dbf1b6a5033891cb190cbb2 data/create/loot_tables/blocks/elevator_pulley.json 2186860c4a0cb47a66bdfdefcde302c599cddeea data/create/loot_tables/blocks/encased_chain_drive.json 7fcc15674a7583b965441fb079b8997e4244a4ff data/create/loot_tables/blocks/encased_fan.json b4df9a8b28f29587e75ffe11ca26d85ddbe926da data/create/loot_tables/blocks/encased_fluid_pipe.json @@ -5720,13 +5729,13 @@ cfa16b75227c9bf4f245c97ac55999b3903e5471 data/forge/tags/items/stripped_logs.jso e002dfedc5e8762de0f97ea1f3fa546e92e748ae data/forge/tags/items/tools/wrench.json 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/azalea_root_replaceable.json 9f7a428085b1aac66da32a43e9d51c7efc1f0d81 data/minecraft/tags/blocks/beacon_base_blocks.json -dea0b54b33b1ae3b4fa8091dfcc4ad5687978ab1 data/minecraft/tags/blocks/climbable.json +f5cc2ea490ede338c9ea94a5775ad626b0ebc83b data/minecraft/tags/blocks/climbable.json e16d74571ae10007f06f3b86ddf05d3ca9b73559 data/minecraft/tags/blocks/doors.json 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/dripstone_replaceable_blocks.json 69f596fcb065e26b02ce246760432b5174191b76 data/minecraft/tags/blocks/impermeable.json 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/lush_ground_replaceable.json -71480793b5e5ac5eb33c5271118c62227a2769d8 data/minecraft/tags/blocks/mineable/axe.json -77511f0fca91aa40c8b2566bf9bfb78964a56db3 data/minecraft/tags/blocks/mineable/pickaxe.json +f1d3b91aab8ea3c59a06b8ccc1a469b3ef953220 data/minecraft/tags/blocks/mineable/axe.json +95508e50d0c11690a4a8938c731930cca3384c90 data/minecraft/tags/blocks/mineable/pickaxe.json 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/moss_replaceable.json e157c1d3af30e409e34bbefbe15a037e6e1c8daa data/minecraft/tags/blocks/needs_iron_tool.json a08f67865337f62601c5e333b4011382d10020e4 data/minecraft/tags/blocks/needs_stone_tool.json diff --git a/src/generated/resources/assets/create/blockstates/contraption_controls.json b/src/generated/resources/assets/create/blockstates/contraption_controls.json new file mode 100644 index 0000000000..c2c6be7bf4 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/contraption_controls.json @@ -0,0 +1,124 @@ +{ + "variants": { + "facing=north,open=false,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=false,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=false,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=false,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 90 + }, + "facing=north,open=true,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=true,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=true,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=true,virtual=false,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 90 + }, + "facing=north,open=false,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=false,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=false,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=false,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 90 + }, + "facing=north,open=true,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=true,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=true,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=true,virtual=true,waterlogged=false": { + "model": "create:block/contraption_controls/block", + "y": 90 + }, + "facing=north,open=false,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=false,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=false,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=false,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 90 + }, + "facing=north,open=true,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=true,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=true,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=true,virtual=false,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 90 + }, + "facing=north,open=false,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=false,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=false,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=false,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 90 + }, + "facing=north,open=true,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block" + }, + "facing=south,open=true,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 180 + }, + "facing=west,open=true,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 270 + }, + "facing=east,open=true,virtual=true,waterlogged=true": { + "model": "create:block/contraption_controls/block", + "y": 90 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/elevator_contact.json b/src/generated/resources/assets/create/blockstates/elevator_contact.json new file mode 100644 index 0000000000..33bbc03f6e --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/elevator_contact.json @@ -0,0 +1,212 @@ +{ + "variants": { + "calling=false,facing=down,powered=false,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 180 + }, + "calling=true,facing=down,powered=false,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 180 + }, + "calling=false,facing=up,powered=false,powering=false": { + "model": "create:block/elevator_contact/block" + }, + "calling=true,facing=up,powered=false,powering=false": { + "model": "create:block/elevator_contact/block_dim" + }, + "calling=false,facing=north,powered=false,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90 + }, + "calling=true,facing=north,powered=false,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90 + }, + "calling=false,facing=south,powered=false,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90, + "y": 180 + }, + "calling=true,facing=south,powered=false,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90, + "y": 180 + }, + "calling=false,facing=west,powered=false,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90, + "y": 270 + }, + "calling=true,facing=west,powered=false,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90, + "y": 270 + }, + "calling=false,facing=east,powered=false,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90, + "y": 90 + }, + "calling=true,facing=east,powered=false,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90, + "y": 90 + }, + "calling=false,facing=down,powered=true,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 180 + }, + "calling=true,facing=down,powered=true,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 180 + }, + "calling=false,facing=up,powered=true,powering=false": { + "model": "create:block/elevator_contact/block" + }, + "calling=true,facing=up,powered=true,powering=false": { + "model": "create:block/elevator_contact/block_dim" + }, + "calling=false,facing=north,powered=true,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90 + }, + "calling=true,facing=north,powered=true,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90 + }, + "calling=false,facing=south,powered=true,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90, + "y": 180 + }, + "calling=true,facing=south,powered=true,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90, + "y": 180 + }, + "calling=false,facing=west,powered=true,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90, + "y": 270 + }, + "calling=true,facing=west,powered=true,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90, + "y": 270 + }, + "calling=false,facing=east,powered=true,powering=false": { + "model": "create:block/elevator_contact/block", + "x": 90, + "y": 90 + }, + "calling=true,facing=east,powered=true,powering=false": { + "model": "create:block/elevator_contact/block_dim", + "x": 90, + "y": 90 + }, + "calling=false,facing=down,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 180 + }, + "calling=true,facing=down,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 180 + }, + "calling=false,facing=up,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered" + }, + "calling=true,facing=up,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered" + }, + "calling=false,facing=north,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90 + }, + "calling=true,facing=north,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90 + }, + "calling=false,facing=south,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 180 + }, + "calling=true,facing=south,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 180 + }, + "calling=false,facing=west,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 270 + }, + "calling=true,facing=west,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 270 + }, + "calling=false,facing=east,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 90 + }, + "calling=true,facing=east,powered=false,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 90 + }, + "calling=false,facing=down,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 180 + }, + "calling=true,facing=down,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 180 + }, + "calling=false,facing=up,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered" + }, + "calling=true,facing=up,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered" + }, + "calling=false,facing=north,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90 + }, + "calling=true,facing=north,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90 + }, + "calling=false,facing=south,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 180 + }, + "calling=true,facing=south,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 180 + }, + "calling=false,facing=west,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 270 + }, + "calling=true,facing=west,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 270 + }, + "calling=false,facing=east,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 90 + }, + "calling=true,facing=east,powered=true,powering=true": { + "model": "create:block/elevator_contact/block_powered", + "x": 90, + "y": 90 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/elevator_pulley.json b/src/generated/resources/assets/create/blockstates/elevator_pulley.json new file mode 100644 index 0000000000..b01fd9b7de --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/elevator_pulley.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=north": { + "model": "create:block/elevator_pulley/block" + }, + "facing=south": { + "model": "create:block/elevator_pulley/block", + "y": 180 + }, + "facing=west": { + "model": "create:block/elevator_pulley/block", + "y": 270 + }, + "facing=east": { + "model": "create:block/elevator_pulley/block", + "y": 90 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index d57821dd53..d25c3ca47b 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -51,6 +51,7 @@ "block.create.clutch": "\u0265\u0254\u0287n\u05DF\u0186", "block.create.cogwheel": "\u05DF\u01DD\u01DD\u0265\u028Dbo\u0186", "block.create.content_observer": "\u0279\u01DD\u028C\u0279\u01DDsqO \u0287u\u01DD\u0287uo\u0186", + "block.create.contraption_controls": "s\u05DFo\u0279\u0287uo\u0186 uo\u0131\u0287d\u0250\u0279\u0287uo\u0186", "block.create.controller_rail": "\u05DF\u0131\u0250\u1D1A \u0279\u01DD\u05DF\u05DFo\u0279\u0287uo\u0186", "block.create.controls": "s\u05DFo\u0279\u0287uo\u0186 u\u0131\u0250\u0279\u27D8", "block.create.copper_backtank": "\u029Eu\u0250\u0287\u029E\u0254\u0250\u15FA \u0279\u01DDddo\u0186", @@ -200,6 +201,8 @@ "block.create.display_board": "p\u0279\u0250o\u15FA \u028E\u0250\u05DFds\u0131\u15E1", "block.create.display_link": "\u029Eu\u0131\uA780 \u028E\u0250\u05DFds\u0131\u15E1", "block.create.dripstone_pillar": "\u0279\u0250\u05DF\u05DF\u0131\u0500 \u01DDuo\u0287sd\u0131\u0279\u15E1", + "block.create.elevator_contact": "\u0287\u0254\u0250\u0287uo\u0186 \u0279o\u0287\u0250\u028C\u01DD\u05DF\u018E", + "block.create.elevator_pulley": "\u028E\u01DD\u05DF\u05DFn\u0500 \u0279o\u0287\u0250\u028C\u01DD\u05DF\u018E", "block.create.encased_chain_drive": "\u01DD\u028C\u0131\u0279\u15E1 u\u0131\u0250\u0265\u0186 p\u01DDs\u0250\u0254u\u018E", "block.create.encased_fan": "u\u0250\u2132 p\u01DDs\u0250\u0254u\u018E", "block.create.encased_fluid_pipe": "\u01DDd\u0131\u0500 p\u0131n\u05DF\u2132 p\u01DDs\u0250\u0254u\u018E", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index f29227a7ae..f1be35b9cb 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -54,6 +54,7 @@ "block.create.clutch": "Clutch", "block.create.cogwheel": "Cogwheel", "block.create.content_observer": "Content Observer", + "block.create.contraption_controls": "Contraption Controls", "block.create.controller_rail": "Controller Rail", "block.create.controls": "Train Controls", "block.create.copper_backtank": "Copper Backtank", @@ -203,6 +204,8 @@ "block.create.display_board": "Display Board", "block.create.display_link": "Display Link", "block.create.dripstone_pillar": "Dripstone Pillar", + "block.create.elevator_contact": "Elevator Contact", + "block.create.elevator_pulley": "Elevator Pulley", "block.create.encased_chain_drive": "Encased Chain Drive", "block.create.encased_fan": "Encased Fan", "block.create.encased_fluid_pipe": "Encased Fluid Pipe", @@ -1423,6 +1426,10 @@ "create.boiler.via_one_engine": "via 1 engine", "create.boiler.via_engines": "via %1$s engines", + "create.elevator_contact.title": "Elevator Contact", + "create.elevator_contact.floor_identifier": "Floor Identifier", + "create.elevator_contact.floor_description": "Floor Description", + "create.gui.schedule.lmb_edit": "Left-Click to Edit", "create.gui.schedule.rmb_remove": "Right-Click to Remove", "create.gui.schedule.duplicate": "Duplicate", @@ -1628,6 +1635,10 @@ "create.contraption.controls.start_controlling": "Now controlling: %1$s", "create.contraption.controls.stop_controlling": "Stopped controlling contraption", "create.contraption.controls.approach_station": "Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "%1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "On", + "create.contraption.controls.actor_toggle.off": "Off", "create.display_link.set": "Targeted position selected", "create.display_link.success": "Successfully bound to targeted position", @@ -1690,6 +1701,7 @@ "create.display_source.max_enchant_level": "Max Enchanting Cost", "create.display_source.boiler_status": "Boiler Status", "create.display_source.entity_name": "Entity Name", + "create.display_source.current_floor": "Elevator Location", "create.display_source.kinetic_speed": "Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "Ignore Direction", "create.display_source.kinetic_speed.directional": "Include Direction", 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 ec0ab8c0d0..d567eac6b6 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: 842", + "_": "Missing Localizations: 853", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Kupplung", "block.create.cogwheel": "Zahnrad", "block.create.content_observer": "Inhaltsbeobachter", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Steuerungsschiene", "block.create.controls": "Zugsteuerung", "block.create.copper_backtank": "Kupferne Druckluftflasche", @@ -204,6 +205,8 @@ "block.create.display_board": "Anzeigetafel", "block.create.display_link": "Anzeige-Link", "block.create.dripstone_pillar": "Tropfstein-Säule", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Ummantelter Kettenriemen", "block.create.encased_fan": "Ummantelter Lüfter", "block.create.encased_fluid_pipe": "Ummanteltes Rohr", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "mit einer Dampfmaschine", "create.boiler.via_engines": "mit %1$s Dampfmaschinen", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "Links-Klick zum Bearbeiten", "create.gui.schedule.rmb_remove": "Rechts-Klick zum Entfernen", "create.gui.schedule.duplicate": "Duplizieren", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "Du steuerst jetzt: %1$s", "create.contraption.controls.stop_controlling": "Du steuerst den Zug nicht mehr", "create.contraption.controls.approach_station": "Halte %1$s gedrückt, um bei %2$s zu halten", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "Anvisierte Position ausgewählt", "create.display_link.success": "Erfolgreich mit ausgewählter Position gebunden", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "Max. Verzauberungskosten", "create.display_source.boiler_status": "Kesselstatus", "create.display_source.entity_name": "Entitätenname", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "Drehgeschwindigkeit (RPM)", "create.display_source.kinetic_speed.absolute": "Ignoriere Richtung", "create.display_source.kinetic_speed.directional": "Beachte Richtung", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_cl.json b/src/generated/resources/assets/create/lang/unfinished/es_cl.json index b1cb4225fa..78a7e6d2ba 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_cl.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_cl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 988", + "_": "Missing Localizations: 999", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Embrague", "block.create.cogwheel": "Engranaje", "block.create.content_observer": "Observador de Contenidos", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Raíl Controlador", "block.create.controls": "UNLOCALIZED: Train Controls", "block.create.copper_backtank": "Tanque-Mochila de Cobre", @@ -204,6 +205,8 @@ "block.create.display_board": "UNLOCALIZED: Display Board", "block.create.display_link": "UNLOCALIZED: Display Link", "block.create.dripstone_pillar": "UNLOCALIZED: Dripstone Pillar", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Conductor en Cadena Encubierto", "block.create.encased_fan": "Ventilador Encubierto", "block.create.encased_fluid_pipe": "Tubería de Fluidos Encubierta", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "UNLOCALIZED: via 1 engine", "create.boiler.via_engines": "UNLOCALIZED: via %1$s engines", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "UNLOCALIZED: Left-Click to Edit", "create.gui.schedule.rmb_remove": "UNLOCALIZED: Right-Click to Remove", "create.gui.schedule.duplicate": "UNLOCALIZED: Duplicate", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s", "create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption", "create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "UNLOCALIZED: Targeted position selected", "create.display_link.success": "UNLOCALIZED: Successfully bound to targeted position", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "UNLOCALIZED: Max Enchanting Cost", "create.display_source.boiler_status": "UNLOCALIZED: Boiler Status", "create.display_source.entity_name": "UNLOCALIZED: Entity Name", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "UNLOCALIZED: Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "UNLOCALIZED: Ignore Direction", "create.display_source.kinetic_speed.directional": "UNLOCALIZED: Include Direction", 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 9866e0ed43..3f5be979d4 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_es.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_es.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 8", + "_": "Missing Localizations: 19", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Embrague", "block.create.cogwheel": "Engranaje", "block.create.content_observer": "Observador de contenidos", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Raíl de control", "block.create.controls": "Controles de tren", "block.create.copper_backtank": "Depósito trasero de cobre", @@ -204,6 +205,8 @@ "block.create.display_board": "Pantalla de visualización", "block.create.display_link": "Enlace de pantalla", "block.create.dripstone_pillar": "Pilar de espeleotema", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Cadena de transmisión revestida", "block.create.encased_fan": "Ventilador revestido", "block.create.encased_fluid_pipe": "Tubería de fluidos de cobre reforzada", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "a través de 1 motor", "create.boiler.via_engines": "a través de %1$s motores", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "Clic izquierdo para editar", "create.gui.schedule.rmb_remove": "Clic derecho para eliminar", "create.gui.schedule.duplicate": "Duplicar", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "Controlando actualmente: %1$s", "create.contraption.controls.stop_controlling": "Se ha parado de controlar el artefacto móvil", "create.contraption.controls.approach_station": "Mantén %1$s para acercarte a %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "Posición objetivo seleccionada", "create.display_link.success": "Posición objetivo vinculada con éxito", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "Coste máximo de encantamiento", "create.display_source.boiler_status": "Estado de la caldera", "create.display_source.entity_name": "Nombre de la entidad", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "Velocidad de rotación (RPM)", "create.display_source.kinetic_speed.absolute": "Ignorar dirección", "create.display_source.kinetic_speed.directional": "Incluir dirección", 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 a40d4bfce4..5a4ee5f26c 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: 2139", + "_": "Missing Localizations: 2150", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Embrayage", "block.create.cogwheel": "Roue dentée", "block.create.content_observer": "Observateur de contenu", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Rails controlleurs", "block.create.controls": "UNLOCALIZED: Train Controls", "block.create.copper_backtank": "UNLOCALIZED: Copper Backtank", @@ -204,6 +205,8 @@ "block.create.display_board": "UNLOCALIZED: Display Board", "block.create.display_link": "UNLOCALIZED: Display Link", "block.create.dripstone_pillar": "UNLOCALIZED: Dripstone Pillar", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Chaine de transmission", "block.create.encased_fan": "Ventilateur enchâssé", "block.create.encased_fluid_pipe": "UNLOCALIZED: Encased Fluid Pipe", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "UNLOCALIZED: via 1 engine", "create.boiler.via_engines": "UNLOCALIZED: via %1$s engines", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "UNLOCALIZED: Left-Click to Edit", "create.gui.schedule.rmb_remove": "UNLOCALIZED: Right-Click to Remove", "create.gui.schedule.duplicate": "UNLOCALIZED: Duplicate", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s", "create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption", "create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "UNLOCALIZED: Targeted position selected", "create.display_link.success": "UNLOCALIZED: Successfully bound to targeted position", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "UNLOCALIZED: Max Enchanting Cost", "create.display_source.boiler_status": "UNLOCALIZED: Boiler Status", "create.display_source.entity_name": "UNLOCALIZED: Entity Name", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "UNLOCALIZED: Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "UNLOCALIZED: Ignore Direction", "create.display_source.kinetic_speed.directional": "UNLOCALIZED: Include Direction", 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 39c5e5ac92..9324ec9b68 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: 2", + "_": "Missing Localizations: 13", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Frizione", "block.create.cogwheel": "Ingranaggio", "block.create.content_observer": "Osservatore di contenuti", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Binario di controllo", "block.create.controls": "Comandi del treno", "block.create.copper_backtank": "Zaino serbatoio", @@ -204,6 +205,8 @@ "block.create.display_board": "Tabellone", "block.create.display_link": "Lettore di dati", "block.create.dripstone_pillar": "Pilastro di speleotema", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Trasmissione a catena", "block.create.encased_fan": "Ventilatore", "block.create.encased_fluid_pipe": "Tubo per fluidi rivestito", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "tramite 1 motore", "create.boiler.via_engines": "tramite %1$s motori", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "Click sinistro per modificare", "create.gui.schedule.rmb_remove": "Click destro per rimuovere", "create.gui.schedule.duplicate": "Duplica", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "Al comando di: %1$s", "create.contraption.controls.stop_controlling": "Hai smesso di guidare il macchinario", "create.contraption.controls.approach_station": "Tieni premuto %1$s per fermarti a %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "Bersaglio selezionato", "create.display_link.success": "Connesso con successo alla posizione selezionata", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "Livello massimo", "create.display_source.boiler_status": "Stato della Caldaia", "create.display_source.entity_name": "Nome entità", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "Velocità di rotazione", "create.display_source.kinetic_speed.absolute": "Ignora direzione", "create.display_source.kinetic_speed.directional": "Includi direzione", 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 29408f90f7..34fdc20ca7 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: 4", + "_": "Missing Localizations: 15", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "クラッチ", "block.create.cogwheel": "歯車", "block.create.content_observer": "コンテンツオブザーバー", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "コントローラーレール", "block.create.controls": "列車運転台", "block.create.copper_backtank": "銅のバックタンク", @@ -204,6 +205,8 @@ "block.create.display_board": "ディスプレイボード", "block.create.display_link": "ディスプレイリンク", "block.create.dripstone_pillar": "鍾乳石の柱", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "ケース入りチェーンドライブ", "block.create.encased_fan": "ケース入りファン", "block.create.encased_fluid_pipe": "ケース入り液体パイプ", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "1基のエンジン経由", "create.boiler.via_engines": "%1$s基のエンジン経由", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "左クリックで編集", "create.gui.schedule.rmb_remove": "右クリックで削除", "create.gui.schedule.duplicate": "複製", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "運転中: %1$s", "create.contraption.controls.stop_controlling": "運転終了", "create.contraption.controls.approach_station": "%1$sキーを長押しで%2$sに停車", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "対象の位置を選択しました", "create.display_link.success": "対象の位置と結び付けられました", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "最大エンチャントコスト", "create.display_source.boiler_status": "ボイラー状態", "create.display_source.entity_name": "エンティティ名", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "回転速度(RPM)", "create.display_source.kinetic_speed.absolute": "回転方向を無視", "create.display_source.kinetic_speed.directional": "回転方向を含める", 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 92e403ed6f..80394cd5a5 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: 8", + "_": "Missing Localizations: 19", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "클러치", "block.create.cogwheel": "톱니바퀴", "block.create.content_observer": "정보 감지기", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "방향 레일", "block.create.controls": "기차 조종기", "block.create.copper_backtank": "구리 산소통", @@ -204,6 +205,8 @@ "block.create.display_board": "디스플레이 화면", "block.create.display_link": "디스플레이 링크", "block.create.dripstone_pillar": "점적석 기둥", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "체인 드라이브", "block.create.encased_fan": "선풍기", "block.create.encased_fluid_pipe": "구리 케이스를 씌운 파이프", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "엔진 1개", "create.boiler.via_engines": "엔진 %1$s개", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "좌클릭으로 수정", "create.gui.schedule.rmb_remove": "우클릭으로 삭제", "create.gui.schedule.duplicate": "복제", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "%1$s를 조종합니다", "create.contraption.controls.stop_controlling": "구조물 조종을 멈췄습니다", "create.contraption.controls.approach_station": "%1$s을(를) 눌러 %2$s에 접근합니다", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "표시할 대상을 선택했습니다", "create.display_link.success": "성공적으로 대상과 연결되었습니다", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "최대 마법부여 수치", "create.display_source.boiler_status": "보일러 상태", "create.display_source.entity_name": "엔티티 이름", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "회전 속도 (RPM)", "create.display_source.kinetic_speed.absolute": "방향 무시", "create.display_source.kinetic_speed.directional": "방향 포함", 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 319e3974f6..207b4ac505 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: 2487", + "_": "Missing Localizations: 2498", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Koppeling", "block.create.cogwheel": "Tandwiel", "block.create.content_observer": "UNLOCALIZED: Content Observer", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "UNLOCALIZED: Controller Rail", "block.create.controls": "UNLOCALIZED: Train Controls", "block.create.copper_backtank": "UNLOCALIZED: Copper Backtank", @@ -204,6 +205,8 @@ "block.create.display_board": "UNLOCALIZED: Display Board", "block.create.display_link": "UNLOCALIZED: Display Link", "block.create.dripstone_pillar": "UNLOCALIZED: Dripstone Pillar", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "UNLOCALIZED: Encased Chain Drive", "block.create.encased_fan": "Omhulsde Ventilator", "block.create.encased_fluid_pipe": "UNLOCALIZED: Encased Fluid Pipe", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "UNLOCALIZED: via 1 engine", "create.boiler.via_engines": "UNLOCALIZED: via %1$s engines", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "UNLOCALIZED: Left-Click to Edit", "create.gui.schedule.rmb_remove": "UNLOCALIZED: Right-Click to Remove", "create.gui.schedule.duplicate": "UNLOCALIZED: Duplicate", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s", "create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption", "create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "UNLOCALIZED: Targeted position selected", "create.display_link.success": "UNLOCALIZED: Successfully bound to targeted position", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "UNLOCALIZED: Max Enchanting Cost", "create.display_source.boiler_status": "UNLOCALIZED: Boiler Status", "create.display_source.entity_name": "UNLOCALIZED: Entity Name", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "UNLOCALIZED: Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "UNLOCALIZED: Ignore Direction", "create.display_source.kinetic_speed.directional": "UNLOCALIZED: Include Direction", diff --git a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json index be600d683f..eca30b91bc 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json +++ b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 12", + "_": "Missing Localizations: 23", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Sprzęgło", "block.create.cogwheel": "Koło zębate", "block.create.content_observer": "Detektor zawartości", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Tory sterujące", "block.create.controls": "Kontroler pociągów", "block.create.copper_backtank": "Miedziany zbiornik w plecaku", @@ -204,6 +205,8 @@ "block.create.display_board": "Tablica wyświetlająca", "block.create.display_link": "Nadajnik wyświetlacza", "block.create.dripstone_pillar": "Naciekowy filar", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Izolowany przekaźnik łańcuchowy", "block.create.encased_fan": "Izolowany wiatrak", "block.create.encased_fluid_pipe": "Izolowana rura", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "poprzez 1 silnik", "create.boiler.via_engines": "poprzez %1$s silniki(ów)", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "Kliknij LPM, aby edytować", "create.gui.schedule.rmb_remove": "Kliknij PPM, aby usunąć", "create.gui.schedule.duplicate": "Duplikuj", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "Teraz kontrolowane: %1$s", "create.contraption.controls.stop_controlling": "Przestano kontrolować maszynę", "create.contraption.controls.approach_station": "Przytrzymaj %1$s aby podjechać do %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "Pozycja docelowa zaznaczona", "create.display_link.success": "Pomyślnie przypisano do pozycji docelowej", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "Maksymalny koszt zaklinania", "create.display_source.boiler_status": "Stan boilera", "create.display_source.entity_name": "Nazwa bytu", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "Prędkość obrotu (Ob/min)", "create.display_source.kinetic_speed.absolute": "Ignoruj kierunek", "create.display_source.kinetic_speed.directional": "Pokaż kierunek", 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 4be946869f..a06725447d 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: 1331", + "_": "Missing Localizations: 1342", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Embreagem", "block.create.cogwheel": "Roda Dentada", "block.create.content_observer": "Observador de Conteúdo", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Trilho Controlador", "block.create.controls": "Controles do trem", "block.create.copper_backtank": "Tanque Traseiro de Cobre", @@ -204,6 +205,8 @@ "block.create.display_board": "Placa de exibição", "block.create.display_link": "Conexão de placa de exibição", "block.create.dripstone_pillar": "Pilar de espeleotema", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Correia Revestida", "block.create.encased_fan": "Ventilador Revestida", "block.create.encased_fluid_pipe": "Cano de Fluidos Revestido", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "UNLOCALIZED: via 1 engine", "create.boiler.via_engines": "UNLOCALIZED: via %1$s engines", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "UNLOCALIZED: Left-Click to Edit", "create.gui.schedule.rmb_remove": "UNLOCALIZED: Right-Click to Remove", "create.gui.schedule.duplicate": "UNLOCALIZED: Duplicate", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s", "create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption", "create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "UNLOCALIZED: Targeted position selected", "create.display_link.success": "UNLOCALIZED: Successfully bound to targeted position", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "UNLOCALIZED: Max Enchanting Cost", "create.display_source.boiler_status": "UNLOCALIZED: Boiler Status", "create.display_source.entity_name": "UNLOCALIZED: Entity Name", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "UNLOCALIZED: Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "UNLOCALIZED: Ignore Direction", "create.display_source.kinetic_speed.directional": "UNLOCALIZED: Include Direction", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_pt.json b/src/generated/resources/assets/create/lang/unfinished/pt_pt.json index a62924d83a..4c2e0ac5ab 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_pt.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_pt.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 2196", + "_": "Missing Localizations: 2207", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Embreagem", "block.create.cogwheel": "Roda Dentada", "block.create.content_observer": "Observador de Conteúdo", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Trilho Controlador", "block.create.controls": "UNLOCALIZED: Train Controls", "block.create.copper_backtank": "Tanque Traseiro de Cobre", @@ -204,6 +205,8 @@ "block.create.display_board": "UNLOCALIZED: Display Board", "block.create.display_link": "UNLOCALIZED: Display Link", "block.create.dripstone_pillar": "UNLOCALIZED: Dripstone Pillar", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Correia Revestida", "block.create.encased_fan": "Ventilador Revestida", "block.create.encased_fluid_pipe": "Cano de Fluidos Revestido", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "UNLOCALIZED: via 1 engine", "create.boiler.via_engines": "UNLOCALIZED: via %1$s engines", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "UNLOCALIZED: Left-Click to Edit", "create.gui.schedule.rmb_remove": "UNLOCALIZED: Right-Click to Remove", "create.gui.schedule.duplicate": "UNLOCALIZED: Duplicate", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s", "create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption", "create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "UNLOCALIZED: Targeted position selected", "create.display_link.success": "UNLOCALIZED: Successfully bound to targeted position", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "UNLOCALIZED: Max Enchanting Cost", "create.display_source.boiler_status": "UNLOCALIZED: Boiler Status", "create.display_source.entity_name": "UNLOCALIZED: Entity Name", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "UNLOCALIZED: Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "UNLOCALIZED: Ignore Direction", "create.display_source.kinetic_speed.directional": "UNLOCALIZED: Include Direction", diff --git a/src/generated/resources/assets/create/lang/unfinished/ro_ro.json b/src/generated/resources/assets/create/lang/unfinished/ro_ro.json index 25aa3227a7..37d996decb 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ro_ro.json +++ b/src/generated/resources/assets/create/lang/unfinished/ro_ro.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 655", + "_": "Missing Localizations: 666", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Ambreiaj", "block.create.cogwheel": "Roată Dințată", "block.create.content_observer": "Observator De Conținut", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Controlor De Șină", "block.create.controls": "UNLOCALIZED: Train Controls", "block.create.copper_backtank": "Backtank De Cupru", @@ -204,6 +205,8 @@ "block.create.display_board": "UNLOCALIZED: Display Board", "block.create.display_link": "UNLOCALIZED: Display Link", "block.create.dripstone_pillar": "Coloană De Dripstone", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Lanț De Distribuție Încapsulat", "block.create.encased_fan": "Ventilator Încapsulat", "block.create.encased_fluid_pipe": "Conductă De Fluide Încapsulată", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "UNLOCALIZED: via 1 engine", "create.boiler.via_engines": "UNLOCALIZED: via %1$s engines", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "UNLOCALIZED: Left-Click to Edit", "create.gui.schedule.rmb_remove": "UNLOCALIZED: Right-Click to Remove", "create.gui.schedule.duplicate": "UNLOCALIZED: Duplicate", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s", "create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption", "create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "UNLOCALIZED: Targeted position selected", "create.display_link.success": "UNLOCALIZED: Successfully bound to targeted position", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "UNLOCALIZED: Max Enchanting Cost", "create.display_source.boiler_status": "UNLOCALIZED: Boiler Status", "create.display_source.entity_name": "UNLOCALIZED: Entity Name", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "UNLOCALIZED: Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "UNLOCALIZED: Ignore Direction", "create.display_source.kinetic_speed.directional": "UNLOCALIZED: Include Direction", 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 28d2f0826d..bed5a534d7 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: 0", + "_": "Missing Localizations: 11", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Сцепление", "block.create.cogwheel": "Шестерня", "block.create.content_observer": "Наблюдатель за содержимым", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Контролирующие рельсы", "block.create.controls": "Контроллер поезда", "block.create.copper_backtank": "Медный баллон", @@ -204,6 +205,8 @@ "block.create.display_board": "Механическое табло", "block.create.display_link": "Передатчик информации", "block.create.dripstone_pillar": "Колонна из натёчного камня", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Цепной привод в корпусе", "block.create.encased_fan": "Вентилятор в корпусе", "block.create.encased_fluid_pipe": "Жидкостная труба в корпусе", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "с помощью 1 двигателя", "create.boiler.via_engines": "с помощью %1$s двигателей", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "ЛКМ для редактирования", "create.gui.schedule.rmb_remove": "ПКМ для удаления", "create.gui.schedule.duplicate": "Дублировать", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "Под управлением: %1$s", "create.contraption.controls.stop_controlling": "Выход из режима управления", "create.contraption.controls.approach_station": "Зажмите %1$s для прибытия на %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "Выбрана целевая позиция", "create.display_link.success": "Успешно привязан к целевой позиции", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "Уровень чар", "create.display_source.boiler_status": "Статус котла", "create.display_source.entity_name": "Имя существа", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "Обороты в минуту", "create.display_source.kinetic_speed.absolute": "Без направления", "create.display_source.kinetic_speed.directional": "С направлением", diff --git a/src/generated/resources/assets/create/lang/unfinished/uk_ua.json b/src/generated/resources/assets/create/lang/unfinished/uk_ua.json index 94152cfd66..522132907a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/uk_ua.json +++ b/src/generated/resources/assets/create/lang/unfinished/uk_ua.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 986", + "_": "Missing Localizations: 997", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "Зчеплення", "block.create.cogwheel": "Шестірня", "block.create.content_observer": "Спостерігач вмісту", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "Контролерна рейка", "block.create.controls": "UNLOCALIZED: Train Controls", "block.create.copper_backtank": "Мідний резервуар", @@ -204,6 +205,8 @@ "block.create.display_board": "UNLOCALIZED: Display Board", "block.create.display_link": "UNLOCALIZED: Display Link", "block.create.dripstone_pillar": "UNLOCALIZED: Dripstone Pillar", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "Ланцюговий привід у корпусі", "block.create.encased_fan": "Вентилятор у корпусі", "block.create.encased_fluid_pipe": "Труба для рідини в корпусі", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "UNLOCALIZED: via 1 engine", "create.boiler.via_engines": "UNLOCALIZED: via %1$s engines", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "UNLOCALIZED: Left-Click to Edit", "create.gui.schedule.rmb_remove": "UNLOCALIZED: Right-Click to Remove", "create.gui.schedule.duplicate": "UNLOCALIZED: Duplicate", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s", "create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption", "create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "UNLOCALIZED: Targeted position selected", "create.display_link.success": "UNLOCALIZED: Successfully bound to targeted position", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "UNLOCALIZED: Max Enchanting Cost", "create.display_source.boiler_status": "UNLOCALIZED: Boiler Status", "create.display_source.entity_name": "UNLOCALIZED: Entity Name", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "UNLOCALIZED: Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "UNLOCALIZED: Ignore Direction", "create.display_source.kinetic_speed.directional": "UNLOCALIZED: Include Direction", 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 f4be7ff19d..6e9b3c4864 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: 0", + "_": "Missing Localizations: 11", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "离合器", "block.create.cogwheel": "齿轮", "block.create.content_observer": "物品侦测器", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "控制铁轨", "block.create.controls": "列车驾驶台", "block.create.copper_backtank": "铜背罐", @@ -204,6 +205,8 @@ "block.create.display_board": "翻牌显示器", "block.create.display_link": "显示链接器", "block.create.dripstone_pillar": "滴水石柱", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "链式传动箱", "block.create.encased_fan": "鼓风机", "block.create.encased_fluid_pipe": "流体管道箱", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "通过1个引擎", "create.boiler.via_engines": "通过%1$s个引擎", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "左键点击编辑", "create.gui.schedule.rmb_remove": "右键点击移除", "create.gui.schedule.duplicate": "复制", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "现在控制:%1$s", "create.contraption.controls.stop_controlling": "停止控制装置", "create.contraption.controls.approach_station": "按住%1$s以接近%2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "已选择目标位置", "create.display_link.success": "成功绑定到目标位置", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "最大附魔花费", "create.display_source.boiler_status": "锅炉状态", "create.display_source.entity_name": "实体名称", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "转速(RPM)", "create.display_source.kinetic_speed.absolute": "无视转向", "create.display_source.kinetic_speed.directional": "包含转向", 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 1af6b480cf..a3edce07f4 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: 8", + "_": "Missing Localizations: 19", "_": "->------------------------] Game Elements [------------------------<-", @@ -55,6 +55,7 @@ "block.create.clutch": "離合器", "block.create.cogwheel": "齒輪", "block.create.content_observer": "物品偵測器", + "block.create.contraption_controls": "UNLOCALIZED: Contraption Controls", "block.create.controller_rail": "控制軌道", "block.create.controls": "火車控制台", "block.create.copper_backtank": "銅製後背包", @@ -204,6 +205,8 @@ "block.create.display_board": "顯示板", "block.create.display_link": "顯示鏈路", "block.create.dripstone_pillar": "鐘乳石柱", + "block.create.elevator_contact": "UNLOCALIZED: Elevator Contact", + "block.create.elevator_pulley": "UNLOCALIZED: Elevator Pulley", "block.create.encased_chain_drive": "鏈式傳動箱", "block.create.encased_fan": "鼓風機", "block.create.encased_fluid_pipe": "流體管道箱", @@ -1424,6 +1427,10 @@ "create.boiler.via_one_engine": "透過 1 個引擎", "create.boiler.via_engines": "透過 %1$s 個引擎", + "create.elevator_contact.title": "UNLOCALIZED: Elevator Contact", + "create.elevator_contact.floor_identifier": "UNLOCALIZED: Floor Identifier", + "create.elevator_contact.floor_description": "UNLOCALIZED: Floor Description", + "create.gui.schedule.lmb_edit": "左鍵點擊編輯", "create.gui.schedule.rmb_remove": "右鍵點擊移除", "create.gui.schedule.duplicate": "複製", @@ -1629,6 +1636,10 @@ "create.contraption.controls.start_controlling": "正在控制:%1$s", "create.contraption.controls.stop_controlling": "停止控制裝置", "create.contraption.controls.approach_station": "按住 %1$s 以接近 %2$s", + "create.contraption.controls.specific_actor_toggle": "UNLOCALIZED: %1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "UNLOCALIZED: All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "UNLOCALIZED: On", + "create.contraption.controls.actor_toggle.off": "UNLOCALIZED: Off", "create.display_link.set": "已選定目標位置", "create.display_link.success": "成功綁定到目標位置", @@ -1691,6 +1702,7 @@ "create.display_source.max_enchant_level": "最大附魔費用", "create.display_source.boiler_status": "鍋爐狀態", "create.display_source.entity_name": "實體名稱", + "create.display_source.current_floor": "UNLOCALIZED: Elevator Location", "create.display_source.kinetic_speed": "轉速 (RPM)", "create.display_source.kinetic_speed.absolute": "無視轉向", "create.display_source.kinetic_speed.directional": "顯示轉向", diff --git a/src/generated/resources/assets/create/models/item/contraption_controls.json b/src/generated/resources/assets/create/models/item/contraption_controls.json new file mode 100644 index 0000000000..07a722d362 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/contraption_controls.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/contraption_controls/item" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/elevator_contact.json b/src/generated/resources/assets/create/models/item/elevator_contact.json new file mode 100644 index 0000000000..50fc0dfa99 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/elevator_contact.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/elevator_contact/block" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/elevator_pulley.json b/src/generated/resources/assets/create/models/item/elevator_pulley.json new file mode 100644 index 0000000000..df00e5656e --- /dev/null +++ b/src/generated/resources/assets/create/models/item/elevator_pulley.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/elevator_pulley/item" +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/contraption_controls.json b/src/generated/resources/data/create/loot_tables/blocks/contraption_controls.json new file mode 100644 index 0000000000..69cece5200 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/contraption_controls.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "create:contraption_controls" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/elevator_contact.json b/src/generated/resources/data/create/loot_tables/blocks/elevator_contact.json new file mode 100644 index 0000000000..da0d76bbdb --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/elevator_contact.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "create:redstone_contact" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/elevator_pulley.json b/src/generated/resources/data/create/loot_tables/blocks/elevator_pulley.json new file mode 100644 index 0000000000..f73be002f7 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/elevator_pulley.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "create:elevator_pulley" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/blocks/climbable.json b/src/generated/resources/data/minecraft/tags/blocks/climbable.json index 4098917428..0a947eec28 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/climbable.json +++ b/src/generated/resources/data/minecraft/tags/blocks/climbable.json @@ -3,6 +3,8 @@ "values": [ "create:andesite_ladder", "create:brass_ladder", - "create:copper_ladder" + "create:copper_ladder", + "create:rope", + "create:pulley_magnet" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index 3dfa8509f3..0c6012b4ae 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -42,10 +42,12 @@ "create:mechanical_bearing", "create:clockwork_bearing", "create:rope_pulley", + "create:elevator_pulley", "create:cart_assembler", "create:linear_chassis", "create:secondary_linear_chassis", "create:radial_chassis", + "create:contraption_controls", "create:mechanical_drill", "create:mechanical_saw", "create:deployer", @@ -97,6 +99,7 @@ "create:rotation_speed_controller", "create:mechanical_arm", "create:railway_casing", + "create:elevator_contact", "create:content_observer", "create:stockpile_switch", "create:creative_crate", diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 3394d19b5b..8ad563b282 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -89,12 +89,14 @@ "create:mechanical_bearing", "create:clockwork_bearing", "create:rope_pulley", + "create:elevator_pulley", "create:cart_assembler", "create:controller_rail", "create:linear_chassis", "create:secondary_linear_chassis", "create:radial_chassis", "create:sticker", + "create:contraption_controls", "create:mechanical_drill", "create:mechanical_saw", "create:deployer", @@ -124,6 +126,7 @@ "create:train_trapdoor", "create:framed_glass_door", "create:framed_glass_trapdoor", + "create:elevator_contact", "create:item_vault", "create:andesite_funnel", "create:andesite_belt_funnel", diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 88443bdc24..5979377b76 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -1,7 +1,9 @@ package com.simibubi.create; +import java.util.ArrayList; import java.util.EnumMap; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.jozufozu.flywheel.core.PartialModel; @@ -64,6 +66,9 @@ public class AllBlockPartials { HOSE_MAGNET = block("hose_pulley/pulley_magnet"), HOSE_HALF = block("hose_pulley/rope_half"), HOSE_HALF_MAGNET = block("hose_pulley/rope_half_magnet"), + ELEVATOR_COIL = block("elevator_pulley/rope_coil"), ELEVATOR_MAGNET = block("elevator_pulley/pulley_magnet"), + ELEVATOR_BELT = block("elevator_pulley/rope"), ELEVATOR_BELT_HALF = block("elevator_pulley/rope_half"), + MILLSTONE_COG = block("millstone/inner"), SYMMETRY_PLANE = block("symmetry_effect/plane"), SYMMETRY_CROSSPLANE = block("symmetry_effect/crossplane"), @@ -120,6 +125,7 @@ public class AllBlockPartials { TRAIN_COUPLING_CABLE = block("track/bogey/coupling_cable"), TRAIN_CONTROLS_COVER = block("controls/train/cover"), TRAIN_CONTROLS_LEVER = block("controls/train/lever"), + CONTRAPTION_CONTROLS_BUTTON = block("contraption_controls/button"), ENGINE_PISTON = block("steam_engine/piston"), ENGINE_LINKAGE = block("steam_engine/linkage"), ENGINE_CONNECTOR = block("steam_engine/shaft_connector"), BOILER_GAUGE = block("steam_engine/gauge"), @@ -166,6 +172,7 @@ public class AllBlockPartials { public static final Map METAL_GIRDER_BRACKETS = new EnumMap<>(Direction.class); public static final Map TOOLBOX_LIDS = new EnumMap<>(DyeColor.class); + public static final List CONTRAPTION_CONTROLS_INDICATOR = new ArrayList<>(); static { for (FluidTransportBehaviour.AttachmentTypes.ComponentPartials type : FluidTransportBehaviour.AttachmentTypes.ComponentPartials.values()) { @@ -180,6 +187,8 @@ public class AllBlockPartials { TOOLBOX_LIDS.put(color, block("toolbox/lid/" + Lang.asId(color.name()))); for (Direction d : Iterate.horizontalDirections) METAL_GIRDER_BRACKETS.put(d, block("metal_girder/bracket_" + Lang.asId(d.name()))); + for (int i = 0; i < 8; i++) + CONTRAPTION_CONTROLS_INDICATOR.add(block("contraption_controls/indicator_" + i)); } private static PartialModel block(String path) { diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 1fd9d6434d..316fe62b23 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -31,6 +31,9 @@ import com.simibubi.create.content.contraptions.components.actors.SawMovementBeh import com.simibubi.create.content.contraptions.components.actors.SeatBlock; import com.simibubi.create.content.contraptions.components.actors.SeatInteractionBehaviour; import com.simibubi.create.content.contraptions.components.actors.SeatMovementBehaviour; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsBlock; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsMovement; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsMovingInteraction; import com.simibubi.create.content.contraptions.components.clock.CuckooClockBlock; import com.simibubi.create.content.contraptions.components.crafter.CrafterCTBehaviour; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock; @@ -66,6 +69,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.cha import com.simibubi.create.content.contraptions.components.structureMovement.chassis.LinearChassisBlock.ChassisCTBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.RadialChassisBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContactBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorPulleyBlock; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageBlock; import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock; import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsInteractionBehaviour; @@ -165,6 +170,7 @@ import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock; import com.simibubi.create.content.logistics.block.display.DisplayLinkBlockItem; import com.simibubi.create.content.logistics.block.display.source.AccumulatedItemCountDisplaySource; import com.simibubi.create.content.logistics.block.display.source.BoilerDisplaySource; +import com.simibubi.create.content.logistics.block.display.source.CurrentFloorDisplaySource; import com.simibubi.create.content.logistics.block.display.source.EntityNameDisplaySource; import com.simibubi.create.content.logistics.block.display.source.FillLevelDisplaySource; import com.simibubi.create.content.logistics.block.display.source.FluidAmountDisplaySource; @@ -197,6 +203,7 @@ import com.simibubi.create.content.logistics.block.redstone.ContentObserverBlock import com.simibubi.create.content.logistics.block.redstone.NixieTubeBlock; import com.simibubi.create.content.logistics.block.redstone.NixieTubeGenerator; import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock; +import com.simibubi.create.content.logistics.block.redstone.RedstoneContactItem; import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock; import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkGenerator; import com.simibubi.create.content.logistics.block.redstone.RoseQuartzLampBlock; @@ -1135,6 +1142,7 @@ public class AllBlocks { public static final BlockEntry ROPE = REGISTRATE.block("rope", PulleyBlock.RopeBlock::new) .initialProperties(SharedProperties.BELT_MATERIAL, MaterialColor.COLOR_BROWN) .tag(AllBlockTags.BRITTLE.tag) + .tag(BlockTags.CLIMBABLE) .properties(p -> p.sound(SoundType.WOOL)) .blockstate((c, p) -> p.simpleBlock(c.get(), p.models() .getExistingFile(p.modLoc("block/rope_pulley/" + c.getName())))) @@ -1144,10 +1152,22 @@ public class AllBlocks { REGISTRATE.block("pulley_magnet", PulleyBlock.MagnetBlock::new) .initialProperties(SharedProperties::stone) .tag(AllBlockTags.BRITTLE.tag) + .tag(BlockTags.CLIMBABLE) .blockstate((c, p) -> p.simpleBlock(c.get(), p.models() .getExistingFile(p.modLoc("block/rope_pulley/" + c.getName())))) .register(); + public static final BlockEntry ELEVATOR_PULLEY = + REGISTRATE.block("elevator_pulley", ElevatorPulleyBlock::new) + .initialProperties(SharedProperties::softMetal) + .properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN)) + .transform(axeOrPickaxe()) + .blockstate(BlockStateGen.horizontalBlockProvider(true)) + .transform(BlockStressDefaults.setImpact(4.0)) + .item() + .transform(customItemModel()) + .register(); + public static final BlockEntry CART_ASSEMBLER = REGISTRATE.block("cart_assembler", CartAssemblerBlock::new) .initialProperties(SharedProperties::stone) @@ -1229,6 +1249,19 @@ public class AllBlocks { .transform(customItemModel()) .register(); + public static final BlockEntry CONTRAPTION_CONTROLS = + REGISTRATE.block("contraption_controls", ContraptionControlsBlock::new) + .initialProperties(SharedProperties::stone) + .properties(p -> p.color(MaterialColor.PODZOL)) + .addLayer(() -> RenderType::cutoutMipped) + .transform(axeOrPickaxe()) + .blockstate((c, p) -> p.horizontalBlock(c.get(), s -> AssetLookup.partialBaseModel(c, p))) + .onRegister(movementBehaviour(new ContraptionControlsMovement())) + .onRegister(interactionBehaviour(new ContraptionControlsMovingInteraction())) + .item() + .transform(customItemModel()) + .register(); + public static final BlockEntry MECHANICAL_DRILL = REGISTRATE.block("mechanical_drill", DrillBlock::new) .initialProperties(SharedProperties::stone) .properties(p -> p.color(MaterialColor.PODZOL)) @@ -1282,7 +1315,7 @@ public class AllBlocks { .transform(axeOrPickaxe()) .onRegister(movementBehaviour(new ContactMovementBehaviour())) .blockstate((c, p) -> p.directionalBlock(c.get(), AssetLookup.forPowered(c, p))) - .item() + .item(RedstoneContactItem::new) .transform(customItemModel("_", "block")) .register(); @@ -1579,7 +1612,7 @@ public class AllBlocks { .transform(BuilderTransformers.bogey()) .register(); - public static final BlockEntry CONTROLS = REGISTRATE.block("controls", ControlsBlock::new) + public static final BlockEntry TRAIN_CONTROLS = REGISTRATE.block("controls", ControlsBlock::new) .initialProperties(SharedProperties::softMetal) .properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN)) .properties(p -> p.sound(SoundType.NETHERITE_BLOCK)) @@ -1629,9 +1662,28 @@ public class AllBlocks { .addLayer(() -> RenderType::cutoutMipped) .register(); + public static final BlockEntry ELEVATOR_CONTACT = + REGISTRATE.block("elevator_contact", ElevatorContactBlock::new) + .initialProperties(SharedProperties::softMetal) + .properties(p -> p.color(MaterialColor.TERRACOTTA_YELLOW)) + .properties(p -> p.lightLevel(ElevatorContactBlock::getLight)) + .transform(axeOrPickaxe()) + .blockstate((c, p) -> p.directionalBlock(c.get(), state -> { + Boolean calling = state.getValue(ElevatorContactBlock.CALLING); + Boolean powering = state.getValue(ElevatorContactBlock.POWERING); + return powering ? AssetLookup.partialBaseModel(c, p, "powered") + : calling ? AssetLookup.partialBaseModel(c, p, "dim") : AssetLookup.partialBaseModel(c, p); + })) + .loot((p, b) -> p.dropOther(b, REDSTONE_CONTACT.get())) + .onRegister(assignDataBehaviour(new CurrentFloorDisplaySource(), "current_floor")) + .item() + .transform(customItemModel("_", "block")) + .register(); + public static final BlockEntry ITEM_VAULT = REGISTRATE.block("item_vault", ItemVaultBlock::new) .initialProperties(SharedProperties::softMetal) - .properties(p -> p.color(MaterialColor.TERRACOTTA_BLUE)) + .properties(p -> p.color( + MaterialColor.TERRACOTTA_BLUE)) .properties(p -> p.sound(SoundType.NETHERITE_BLOCK) .explosionResistance(1200)) .transform(pickaxeOnly()) diff --git a/src/main/java/com/simibubi/create/AllMovementBehaviours.java b/src/main/java/com/simibubi/create/AllMovementBehaviours.java index 843ece1f73..8d98bbc7f8 100644 --- a/src/main/java/com/simibubi/create/AllMovementBehaviours.java +++ b/src/main/java/com/simibubi/create/AllMovementBehaviours.java @@ -3,7 +3,7 @@ package com.simibubi.create; import java.util.ArrayList; import java.util.List; -import org.jetbrains.annotations.Nullable; +import javax.annotation.Nullable; import com.simibubi.create.content.contraptions.components.actors.BellMovementBehaviour; import com.simibubi.create.content.contraptions.components.actors.CampfireMovementBehaviour; diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index 57ae5e08c3..a15e9ed283 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -41,6 +41,9 @@ public class AllShapes { .add(2, 13, 2, 14, 16, 14) .add(0, 0, 14, 16, 16, 16) .forHorizontalAxis(), + ELEVATOR_PULLEY = shape(0, 0, 0, 16, 16, 2).add(0, 0, 14, 16, 16, 16) + .add(2, 0, 2, 14, 14, 14) + .forHorizontal(EAST), SAIL_FRAME_COLLISION = shape(0, 5, 0, 16, 9, 16).erase(2, 0, 2, 14, 16, 14) .forDirectional(), SAIL_FRAME = shape(0, 5, 0, 16, 9, 16).forDirectional(), SAIL = shape(0, 5, 0, 16, 10, 16).forDirectional(), @@ -122,6 +125,10 @@ public class AllShapes { .forHorizontalAxis(), CONTROLS = shape(0, 0, 6, 16, 14, 16).forHorizontal(NORTH), + CONTRAPTION_CONTROLS = shape(0, 0, 6, 2, 14, 16).add(14, 0, 6, 16, 14, 16) + .add(0, 0, 14, 16, 14, 16) + .add(0, 0, 7, 16, 10, 16) + .forHorizontal(NORTH), NIXIE_TUBE = shape(9, 0, 5, 15, 12, 11).add(1, 0, 5, 7, 12, 11) .forHorizontalAxis(), @@ -181,8 +188,8 @@ public class AllShapes { // Static Block Shapes public static final VoxelShape - TRACK_CROSS = shape(TRACK_ORTHO.get(SOUTH)).add(TRACK_ORTHO.get(EAST)) - .build(), + TRACK_CROSS = shape(TRACK_ORTHO.get(SOUTH)).add(TRACK_ORTHO.get(EAST)) + .build(), TRACK_CROSS_DIAG = shape(TRACK_DIAG.get(SOUTH)).add(TRACK_DIAG.get(EAST)) .build(), @@ -211,6 +218,7 @@ public class AllShapes { 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), SEAT_COLLISION = cuboid(0, 0, 0, 16, 6, 16), + SEAT_COLLISION_PLAYERS = cuboid(0, 0, 0, 16, 3, 16), MECHANICAL_PROCESSOR_SHAPE = shape(Shapes.block()).erase(4, 0, 4, 12, 16, 12) .build(), TURNTABLE_SHAPE = shape(1, 4, 1, 15, 8, 15).add(5, 0, 5, 11, 4, 11) diff --git a/src/main/java/com/simibubi/create/AllSpriteShifts.java b/src/main/java/com/simibubi/create/AllSpriteShifts.java index 31abb134d7..b5efb35730 100644 --- a/src/main/java/com/simibubi/create/AllSpriteShifts.java +++ b/src/main/java/com/simibubi/create/AllSpriteShifts.java @@ -54,13 +54,18 @@ public class AllSpriteShifts { CHASSIS_STICKY = omni("linear_chassis_end_sticky"); public static final CTSpriteShiftEntry BRASS_TUNNEL_TOP = vertical("brass_tunnel_top"), - FLUID_TANK = getCT(AllCTTypes.RECTANGLE, "fluid_tank"), FLUID_TANK_TOP = getCT(AllCTTypes.RECTANGLE, "fluid_tank_top"), + FLUID_TANK = getCT(AllCTTypes.RECTANGLE, "fluid_tank"), + FLUID_TANK_TOP = getCT(AllCTTypes.RECTANGLE, "fluid_tank_top"), FLUID_TANK_INNER = getCT(AllCTTypes.RECTANGLE, "fluid_tank_inner"), CREATIVE_FLUID_TANK = getCT(AllCTTypes.CROSS, "creative_fluid_tank"); public static final Couple VAULT_TOP = vault("top"), VAULT_FRONT = vault("front"), VAULT_SIDE = vault("side"), VAULT_BOTTOM = vault("bottom"); + public static final SpriteShiftEntry ELEVATOR_BELT = + get("block/elevator_pulley_belt", "block/elevator_pulley_belt_scroll"), + ELEVATOR_COIL = get("block/elevator_pulley_coil", "block/elevator_pulley_coil_scroll"); + public static final SpriteShiftEntry BELT = get("block/belt", "block/belt_scroll"), BELT_OFFSET = get("block/belt_offset", "block/belt_scroll"), BELT_DIAGONAL = get("block/belt_diagonal", "block/belt_diagonal_scroll"), diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 3647ad732c..baeed8dc62 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -17,6 +17,8 @@ import com.simibubi.create.content.contraptions.components.actors.PSIInstance; import com.simibubi.create.content.contraptions.components.actors.PortableFluidInterfaceTileEntity; import com.simibubi.create.content.contraptions.components.actors.PortableItemInterfaceTileEntity; import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceRenderer; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsRenderer; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsTileEntity; import com.simibubi.create.content.contraptions.components.clock.CuckooClockRenderer; import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterInstance; @@ -65,6 +67,9 @@ import com.simibubi.create.content.contraptions.components.structureMovement.cha import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerInstance; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContactTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorPulleyRenderer; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorPulleyTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageInstance; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageTileEntity; @@ -476,6 +481,18 @@ public class AllTileEntities { .renderer(() -> PulleyRenderer::new) .register(); + public static final BlockEntityEntry ELEVATOR_PULLEY = Create.registrate() + .tileEntity("elevator_pulley", ElevatorPulleyTileEntity::new) +// .instance(() -> ElevatorPulleyInstance::new, false) + .validBlocks(AllBlocks.ELEVATOR_PULLEY) + .renderer(() -> ElevatorPulleyRenderer::new) + .register(); + + public static final BlockEntityEntry ELEVATOR_CONTACT = Create.registrate() + .tileEntity("elevator_contact", ElevatorContactTileEntity::new) + .validBlocks(AllBlocks.ELEVATOR_CONTACT) + .register(); + public static final BlockEntityEntry CHASSIS = Create.registrate() .tileEntity("chassis", ChassisTileEntity::new) .validBlocks(AllBlocks.RADIAL_CHASSIS, AllBlocks.LINEAR_CHASSIS, AllBlocks.SECONDARY_LINEAR_CHASSIS) @@ -488,6 +505,12 @@ public class AllTileEntities { .validBlocks(AllBlocks.STICKER) .renderer(() -> StickerRenderer::new) .register(); + + public static final BlockEntityEntry CONTRAPTION_CONTROLS = Create.registrate() + .tileEntity("contraption_controls", ContraptionControlsTileEntity::new) + .validBlocks(AllBlocks.CONTRAPTION_CONTROLS) + .renderer(() -> ContraptionControlsRenderer::new) + .register(); public static final BlockEntityEntry DRILL = Create.registrate() .tileEntity("drill", DrillTileEntity::new) @@ -653,7 +676,7 @@ public class AllTileEntities { .validBlocks(AllBlocks.ANALOG_LEVER) .renderer(() -> AnalogLeverRenderer::new) .register(); - + public static final BlockEntityEntry PLACARD = Create.registrate() .tileEntity("placard", PlacardTileEntity::new) .validBlocks(AllBlocks.PLACARD) @@ -780,7 +803,7 @@ public class AllTileEntities { .renderer(() -> TrackRenderer::new) .validBlocks(AllBlocks.TRACK) .register(); - + public static final BlockEntityEntry FAKE_TRACK = Create.registrate() .tileEntity("fake_track", FakeTrackTileEntity::new) .validBlocks(AllBlocks.FAKE_TRACK) @@ -797,7 +820,7 @@ public class AllTileEntities { .renderer(() -> StationRenderer::new) .validBlocks(AllBlocks.TRACK_STATION) .register(); - + public static final BlockEntityEntry SLIDING_DOOR = Create.registrate() .tileEntity("sliding_door", SlidingDoorTileEntity::new) .renderer(() -> SlidingDoorRenderer::new) @@ -816,7 +839,7 @@ public class AllTileEntities { .renderer(() -> SignalRenderer::new) .validBlocks(AllBlocks.TRACK_SIGNAL) .register(); - + public static final BlockEntityEntry TRACK_OBSERVER = Create.registrate() .tileEntity("track_observer", TrackObserverTileEntity::new) .renderer(() -> TrackObserverRenderer::new) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillMovementBehaviour.java index 89ebb9582d..1a7a7e863a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillMovementBehaviour.java @@ -24,8 +24,9 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public boolean isActive(MovementContext context) { - return !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(DrillBlock.FACING) - .getOpposite()); + return super.isActive(context) + && !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(DrillBlock.FACING) + .getOpposite()); } @Override 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 de07acdd9d..9b9efbf08a 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 @@ -45,30 +45,31 @@ public class HarvesterActorInstance extends ActorInstance { horizontalAngle = facing.toYRot() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0); - harvester.setBlockLight(localBlockLight()); - } + harvester.setBlockLight(localBlockLight()); + } - @Override - public void tick() { - super.tick(); + @Override + public void tick() { + super.tick(); - previousRotation = rotation; + previousRotation = rotation; - if (context.contraption.stalled || VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite())) - return; + if (context.contraption.stalled || context.disabled + || VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite())) + return; - double arcLength = context.motion.length(); + double arcLength = context.motion.length(); - double radians = arcLength * oneOverRadius; + double radians = arcLength * oneOverRadius; - float deg = AngleHelper.deg(radians); + float deg = AngleHelper.deg(radians); - deg = (float) (((int) (deg * 3000)) / 3000); + deg = (float) (((int) (deg * 3000)) / 3000); - rotation += deg * 1.25; + rotation += deg * 1.25; - rotation %= 360; - } + rotation %= 360; + } @Override public void beginFrame() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java index 53e6acefc9..3367abc843 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java @@ -39,8 +39,9 @@ public class HarvesterMovementBehaviour implements MovementBehaviour { @Override public boolean isActive(MovementContext context) { - return !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(HarvesterBlock.FACING) - .getOpposite()); + return MovementBehaviour.super.isActive(context) + && !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(HarvesterBlock.FACING) + .getOpposite()); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PloughMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PloughMovementBehaviour.java index 9f95c06520..a7bab0a2ca 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PloughMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PloughMovementBehaviour.java @@ -38,8 +38,9 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public boolean isActive(MovementContext context) { - return !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(PloughBlock.FACING) - .getOpposite()); + return super.isActive(context) + && !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(PloughBlock.FACING) + .getOpposite()); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SawMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SawMovementBehaviour.java index 17965f8645..d2e36e53b7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SawMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SawMovementBehaviour.java @@ -30,8 +30,9 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public boolean isActive(MovementContext context) { - return !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(SawBlock.FACING) - .getOpposite()); + return super.isActive(context) + && !VecHelper.isVecPointingTowards(context.relativeMotion, context.state.getValue(SawBlock.FACING) + .getOpposite()); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java index 3ebd4be6c8..4108634155 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java @@ -40,6 +40,7 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.EntityCollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @ParametersAreNonnullByDefault @@ -127,7 +128,9 @@ public class SeatBlock extends Block implements ProperWaterloggedBlock { @Override public VoxelShape getCollisionShape(BlockState p_220071_1_, BlockGetter p_220071_2_, BlockPos p_220071_3_, - CollisionContext p_220071_4_) { + CollisionContext ctx) { + if (ctx instanceof EntityCollisionContext ecc && ecc.getEntity() instanceof Player) + return AllShapes.SEAT_COLLISION_PLAYERS; return AllShapes.SEAT_COLLISION; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlock.java new file mode 100644 index 0000000000..cef0a52458 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlock.java @@ -0,0 +1,65 @@ +package com.simibubi.create.content.contraptions.components.actors.controls; + +import com.simibubi.create.AllShapes; +import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock; +import com.simibubi.create.foundation.block.ITE; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class ContraptionControlsBlock extends ControlsBlock implements ITE { + + public ContraptionControlsBlock(Properties pProperties) { + super(pProperties); + } + + @Override + public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, + BlockHitResult pHit) { + return onTileEntityUse(pLevel, pPos, cte -> { + cte.pressButton(); + cte.disabled = !cte.disabled; + cte.notifyUpdate(); + if (!pLevel.isClientSide()) { + ContraptionControlsTileEntity.sendStatus(pPlayer, cte.filtering.getFilter(), !cte.disabled); + AllSoundEvents.CONTROLLER_CLICK.play(cte.getLevel(), null, cte.getBlockPos(), 1, + cte.disabled ? 0.8f : 1.5f); + } + return InteractionResult.SUCCESS; + }); + } + + @Override + public void neighborChanged(BlockState pState, Level pLevel, BlockPos pPos, Block pBlock, BlockPos pFromPos, + boolean pIsMoving) { + withTileEntityDo(pLevel, pPos, ContraptionControlsTileEntity::updatePoweredState); + } + + @Override + public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { + return AllShapes.CONTRAPTION_CONTROLS.get(pState.getValue(FACING)); + } + + @Override + public Class getTileEntityClass() { + return ContraptionControlsTileEntity.class; + } + + @Override + public BlockEntityType getTileEntityType() { + return AllTileEntities.CONTRAPTION_CONTROLS.get(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovement.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovement.java new file mode 100644 index 0000000000..7aa0dec3a1 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovement.java @@ -0,0 +1,239 @@ +package com.simibubi.create.content.contraptions.components.actors.controls; + +import java.util.Random; + +import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld; +import com.jozufozu.flywheel.util.transform.TransformStack; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContraption; +import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices; +import com.simibubi.create.content.logistics.block.redstone.NixieTubeRenderer; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.Color; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.DyeHelper; +import com.simibubi.create.foundation.utility.IntAttached; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.items.ItemHandlerHelper; + +public class ContraptionControlsMovement implements MovementBehaviour { + + @Override + public ItemStack canBeDisabledVia(MovementContext context) { + return null; + } + + @Override + public void startMoving(MovementContext context) { + if (context.contraption instanceof ElevatorContraption && context.tileData != null) + context.tileData.remove("Filter"); + } + + @Override + public void stopMoving(MovementContext context) { + ItemStack filter = getFilter(context); + if (filter != null) + context.tileData.putBoolean("Disabled", context.contraption.isActorTypeDisabled(filter) + || context.contraption.isActorTypeDisabled(ItemStack.EMPTY)); + } + + public static boolean isSameFilter(ItemStack stack1, ItemStack stack2) { + if (stack1.isEmpty() && stack2.isEmpty()) + return true; + return ItemHandlerHelper.canItemStacksStack(stack1, stack2); + } + + private static Random r = new Random(); + + public static ItemStack getFilter(MovementContext ctx) { + CompoundTag tileData = ctx.tileData; + if (tileData == null) + return null; + return ItemStack.of(tileData.getCompound("Filter")); + } + + public static boolean isDisabledInitially(MovementContext ctx) { + return ctx.tileData != null && ctx.tileData.getBoolean("Disabled"); + } + + @Override + public void tick(MovementContext ctx) { + if (!ctx.world.isClientSide()) + return; + + Contraption contraption = ctx.contraption; + if (!(contraption instanceof ElevatorContraption ec)) { + if (!(contraption.presentTileEntities.get(ctx.localPos)instanceof ContraptionControlsTileEntity cte)) + return; + ItemStack filter = getFilter(ctx); + int value = + contraption.isActorTypeDisabled(filter) || contraption.isActorTypeDisabled(ItemStack.EMPTY) ? 4 * 45 + : 0; + cte.indicator.setValue(value); + cte.indicator.updateChaseTarget(value); + cte.tickAnimations(); + return; + } + + if (!(ctx.temporaryData instanceof ElevatorFloorSelection)) + ctx.temporaryData = new ElevatorFloorSelection(); + + ElevatorFloorSelection efs = (ElevatorFloorSelection) ctx.temporaryData; + tickFloorSelection(efs, ec); + + if (!(contraption.presentTileEntities.get(ctx.localPos)instanceof ContraptionControlsTileEntity cte)) + return; + + cte.tickAnimations(); + + int currentY = (int) Math.round(contraption.entity.getY() + ec.getContactYOffset()); + boolean atTargetY = ec.clientYTarget == currentY; + + LerpedFloat indicator = cte.indicator; + float currentIndicator = indicator.getChaseTarget(); + boolean below = atTargetY ? currentIndicator > 0 : ec.clientYTarget <= currentY; + + if (currentIndicator == 0 && !atTargetY) { + int startingPoint = below ? 181 : -181; + indicator.setValue(startingPoint); + indicator.updateChaseTarget(startingPoint); + cte.tickAnimations(); + return; + } + + int currentStage = Mth.floor(((currentIndicator % 360) + 360) % 360); + if (!atTargetY || currentStage / 45 != 0) { + float increment = currentStage / 45 == (below ? 4 : 3) ? 2.25f : 33.75f; + indicator.chase(currentIndicator + (below ? increment : -increment), 45f, Chaser.LINEAR); + return; + } + + indicator.setValue(0); + indicator.updateChaseTarget(0); + return; + } + + public static void tickFloorSelection(ElevatorFloorSelection efs, ElevatorContraption ec) { + if (ec.namesList.isEmpty()) { + efs.currentShortName = "X"; + efs.currentLongName = "No Floors"; + efs.currentIndex = 0; + efs.targetYEqualsSelection = true; + return; + } + + efs.currentIndex = Mth.clamp(efs.currentIndex, 0, ec.namesList.size() - 1); + IntAttached> entry = ec.namesList.get(efs.currentIndex); + efs.currentTargetY = entry.getFirst(); + efs.currentShortName = entry.getSecond() + .getFirst(); + efs.currentLongName = entry.getSecond() + .getSecond(); + efs.targetYEqualsSelection = efs.currentTargetY == ec.clientYTarget; + } + + @Override + public boolean renderAsNormalTileEntity() { + return true; + } + + @Override + @OnlyIn(Dist.CLIENT) + public void renderInContraption(MovementContext ctx, VirtualRenderWorld renderWorld, ContraptionMatrices matrices, + MultiBufferSource buffer) { + + if (!(ctx.temporaryData instanceof ElevatorFloorSelection efs)) + return; + if (!AllBlocks.CONTRAPTION_CONTROLS.has(ctx.state)) + return; + + Entity cameraEntity = Minecraft.getInstance() + .getCameraEntity(); + float playerDistance = (float) (ctx.position == null || cameraEntity == null ? 0 + : ctx.position.distanceToSqr(cameraEntity.getEyePosition())); + + float flicker = r.nextFloat(); + Couple couple = DyeHelper.DYE_TABLE.get(efs.targetYEqualsSelection ? DyeColor.WHITE : DyeColor.ORANGE); + int brightColor = couple.getFirst(); + int darkColor = couple.getSecond(); + int flickeringBrightColor = Color.mixColors(brightColor, darkColor, flicker / 4); + Font fontRenderer = Minecraft.getInstance().font; + float shadowOffset = .5f; + + String text = efs.currentShortName; + String description = efs.currentLongName; + PoseStack ms = matrices.getViewProjection(); + TransformStack msr = TransformStack.cast(ms); + + ms.pushPose(); + msr.translate(ctx.localPos); + msr.rotateCentered(Direction.UP, + AngleHelper.rad(AngleHelper.horizontalAngle(ctx.state.getValue(ContraptionControlsBlock.FACING)))); + ms.translate(0.275f + 0.125f, 1, 0.5f); + msr.rotate(Direction.WEST, AngleHelper.rad(67.5f)); + + float buttondepth = -.25f; + if (ctx.contraption.presentTileEntities.get(ctx.localPos)instanceof ContraptionControlsTileEntity cte) + buttondepth += -1 / 24f * cte.button.getValue(AnimationTickHolder.getPartialTicks(renderWorld)); + + if (!text.isBlank() && playerDistance < 100) { + int actualWidth = fontRenderer.width(text); + int width = Math.max(actualWidth, 12); + float scale = 1 / (5f * (width - .5f)); + float heightCentering = (width - 8f) / 2; + + ms.pushPose(); + ms.translate(0, .15f, buttondepth); + ms.scale(scale, -scale, scale); + ms.translate(Math.max(0, width - actualWidth) / 2, heightCentering, 0); + NixieTubeRenderer.drawInWorldString(ms, buffer, text, flickeringBrightColor); + ms.translate(shadowOffset, shadowOffset, -1 / 16f); + NixieTubeRenderer.drawInWorldString(ms, buffer, text, Color.mixColors(darkColor, 0, .35f)); + ms.popPose(); + } + + if (!description.isBlank() && playerDistance < 20) { + int actualWidth = fontRenderer.width(description); + int width = Math.max(actualWidth, 55); + float scale = 1 / (3f * (width - .5f)); + float heightCentering = (width - 8f) / 2; + + ms.pushPose(); + ms.translate(-.0635f, 0.06f, buttondepth); + ms.scale(scale, -scale, scale); + ms.translate(Math.max(0, width - actualWidth) / 2, heightCentering, 0); + NixieTubeRenderer.drawInWorldString(ms, buffer, description, flickeringBrightColor); + ms.popPose(); + } + + ms.popPose(); + + } + + public static class ElevatorFloorSelection { + public int currentIndex = 0; + public int currentTargetY = 0; + public boolean targetYEqualsSelection = true; + public String currentShortName = ""; + public String currentLongName = ""; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovingInteraction.java new file mode 100644 index 0000000000..75f8df0391 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsMovingInteraction.java @@ -0,0 +1,127 @@ +package com.simibubi.create.content.contraptions.components.actors.controls; + +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.lang3.tuple.MutablePair; + +import com.simibubi.create.AllMovementBehaviours; +import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsMovement.ElevatorFloorSelection; +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.MovementBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContraption; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorTargetFloorPacket; +import com.simibubi.create.foundation.networking.AllPackets; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.network.PacketDistributor; + +public class ContraptionControlsMovingInteraction extends MovingInteractionBehaviour { + + @Override + public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos, + AbstractContraptionEntity contraptionEntity) { + Contraption contraption = contraptionEntity.getContraption(); + + MutablePair actor = contraption.getActorAt(localPos); + if (actor == null) + return false; + MovementContext ctx = actor.right; + if (ctx == null) + return false; + if (contraption instanceof ElevatorContraption ec) + return elevatorInteraction(localPos, contraptionEntity, ec, ctx); + if (contraptionEntity.level.isClientSide()) { + if (contraption.presentTileEntities.get(ctx.localPos)instanceof ContraptionControlsTileEntity cte) + cte.pressButton(); + return true; + } + + ItemStack filter = ContraptionControlsMovement.getFilter(ctx); + boolean disable = true; + boolean invert = false; + + List disabledActors = contraption.getDisabledActors(); + for (Iterator iterator = disabledActors.iterator(); iterator.hasNext();) { + ItemStack presentFilter = iterator.next(); + boolean sameFilter = ContraptionControlsMovement.isSameFilter(presentFilter, filter); + if (presentFilter.isEmpty()) { + iterator.remove(); + disable = false; + if (!sameFilter) + invert = true; + continue; + } + if (!sameFilter) + continue; + iterator.remove(); + disable = false; + break; + } + + if (invert) { + for (MutablePair pair : contraption.getActors()) { + MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.left.state); + if (behaviour == null) + continue; + ItemStack behaviourStack = behaviour.canBeDisabledVia(pair.right); + if (behaviourStack == null) + continue; + if (ContraptionControlsMovement.isSameFilter(behaviourStack, filter)) + continue; + if (contraption.isActorTypeDisabled(behaviourStack)) + continue; + disabledActors.add(behaviourStack); + send(contraptionEntity, behaviourStack, true); + } + } + + if (filter.isEmpty()) + disabledActors.clear(); + if (disable) + disabledActors.add(filter); + + contraption.setActorsActive(filter, !disable); + ContraptionControlsTileEntity.sendStatus(player, filter, !disable); + send(contraptionEntity, filter, disable); + + AllSoundEvents.CONTROLLER_CLICK.play(player.level, null, + new BlockPos(contraptionEntity.toGlobalVector(Vec3.atCenterOf(localPos), 1)), 1, disable ? 0.8f : 1.5f); + + return true; + } + + private void send(AbstractContraptionEntity contraptionEntity, ItemStack filter, boolean disable) { + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> contraptionEntity), + new ContraptionDisableActorPacket(contraptionEntity.getId(), filter, !disable)); + } + + private boolean elevatorInteraction(BlockPos localPos, AbstractContraptionEntity contraptionEntity, + ElevatorContraption contraption, MovementContext ctx) { + if (!contraptionEntity.level.isClientSide()) { + BlockPos pos = new BlockPos(contraptionEntity.toGlobalVector(Vec3.atCenterOf(localPos), 1)); + AllSoundEvents.CONTROLLER_CLICK.play(contraptionEntity.level, null, pos, 1, 1.5f); + AllSoundEvents.CONTRAPTION_ASSEMBLE.play(contraptionEntity.level, null, pos, 0.75f, 0.8f); + return true; + } + if (!(ctx.temporaryData instanceof ElevatorFloorSelection efs)) + return false; + if (efs.currentTargetY == contraption.clientYTarget) + return false; + + AllPackets.channel.sendToServer(new ElevatorTargetFloorPacket(contraptionEntity, efs.currentTargetY)); + if (contraption.presentTileEntities.get(ctx.localPos)instanceof ContraptionControlsTileEntity cte) + cte.pressButton(); + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java new file mode 100644 index 0000000000..31d8838d61 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java @@ -0,0 +1,52 @@ +package com.simibubi.create.content.contraptions.components.actors.controls; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.CachedBufferer; +import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; + +public class ContraptionControlsRenderer extends SmartTileEntityRenderer { + + public ContraptionControlsRenderer(Context context) { + super(context); + } + + @Override + protected void renderSafe(ContraptionControlsTileEntity tileEntityIn, float pt, PoseStack ms, + MultiBufferSource buffer, int light, int overlay) { + BlockState blockState = tileEntityIn.getBlockState(); + Direction facing = blockState.getValue(ContraptionControlsBlock.FACING) + .getOpposite(); + Vec3 buttonAxis = VecHelper.rotate(new Vec3(0, 1, -.325), AngleHelper.horizontalAngle(facing), Axis.Y) + .scale(-1 / 24f * tileEntityIn.button.getValue(pt)); + + ms.pushPose(); + ms.translate(buttonAxis.x, buttonAxis.y, buttonAxis.z); + super.renderSafe(tileEntityIn, pt, ms, buffer, light, overlay); + + VertexConsumer vc = buffer.getBuffer(RenderType.solid()); + CachedBufferer.partialFacing(AllBlockPartials.CONTRAPTION_CONTROLS_BUTTON, blockState, facing) + .light(light) + .renderInto(ms, vc); + + ms.popPose(); + + int i = (((int) tileEntityIn.indicator.getValue(pt) / 45) % 8) + 8; + CachedBufferer.partialFacing(AllBlockPartials.CONTRAPTION_CONTROLS_INDICATOR.get(i % 8), blockState, facing) + .light(light) + .renderInto(ms, vc); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsTileEntity.java new file mode 100644 index 0000000000..eb2f92ce42 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsTileEntity.java @@ -0,0 +1,152 @@ +package com.simibubi.create.content.contraptions.components.actors.controls; + +import java.util.List; + +import com.jozufozu.flywheel.util.transform.TransformStack; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.DyeHelper; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; + +public class ContraptionControlsTileEntity extends SmartTileEntity { + + public FilteringBehaviour filtering; + public boolean disabled; + public boolean powered; + + public LerpedFloat indicator; + public LerpedFloat button; + + public ContraptionControlsTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + indicator = LerpedFloat.angular() + .startWithValue(0); + button = LerpedFloat.linear() + .startWithValue(0) + .chase(0, 0.125f, Chaser.EXP); + } + + @Override + public void addBehaviours(List behaviours) { + behaviours.add(filtering = new FilteringBehaviour(this, new ControlsSlot()).moveText(new Vec3(-30, 20, 10))); + } + + public void pressButton() { + button.setValue(1); + } + + public void updatePoweredState() { + if (level.isClientSide()) + return; + boolean powered = level.hasNeighborSignal(worldPosition); + if (this.powered == powered) + return; + this.powered = powered; + this.disabled = powered; + notifyUpdate(); + } + + @Override + public void initialize() { + super.initialize(); + updatePoweredState(); + } + + @Override + public void tick() { + super.tick(); + if (!level.isClientSide()) + return; + tickAnimations(); + int value = disabled ? 4 * 45 : 0; + indicator.setValue(value); + indicator.updateChaseTarget(value); + } + + public void tickAnimations() { + button.tickChaser(); + indicator.tickChaser(); + } + + @Override + protected void read(CompoundTag tag, boolean clientPacket) { + super.read(tag, clientPacket); + disabled = tag.getBoolean("Disabled"); + powered = tag.getBoolean("Powered"); + } + + @Override + protected void write(CompoundTag tag, boolean clientPacket) { + super.write(tag, clientPacket); + tag.putBoolean("Disabled", disabled); + tag.putBoolean("Powered", powered); + } + + public static void sendStatus(Player player, ItemStack filter, boolean enabled) { + MutableComponent state = Lang.translate("contraption.controls.actor_toggle." + (enabled ? "on" : "off")) + .color(DyeHelper.DYE_TABLE.get(enabled ? DyeColor.LIME : DyeColor.ORANGE) + .getFirst()) + .component(); + + if (filter.isEmpty()) { + Lang.translate("contraption.controls.all_actor_toggle", state) + .sendStatus(player); + return; + } + + Lang.translate("contraption.controls.specific_actor_toggle", filter.getHoverName() + .getString(), state) + .sendStatus(player); + } + + public static class ControlsSlot extends ValueBoxTransform.Sided { + + @Override + protected Vec3 getLocalOffset(BlockState state) { + Direction facing = state.getValue(ControlsBlock.FACING); + float yRot = AngleHelper.horizontalAngle(facing); + return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 10.875f, 5.1f), yRot, Axis.Y); + } + + @Override + protected void rotate(BlockState state, PoseStack ms) { + Direction facing = state.getValue(ControlsBlock.FACING); + float yRot = AngleHelper.horizontalAngle(facing); + TransformStack.cast(ms) + .rotateY(yRot + 180) + .rotateX(67.5f); + } + + @Override + protected float getScale() { + return .5f; + } + + @Override + protected Vec3 getSouthLocation() { + return Vec3.ZERO; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionDisableActorPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionDisableActorPacket.java new file mode 100644 index 0000000000..108cf83494 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionDisableActorPacket.java @@ -0,0 +1,74 @@ +package com.simibubi.create.content.contraptions.components.actors.controls; + +import java.util.Iterator; +import java.util.List; +import java.util.function.Supplier; + +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.network.NetworkEvent.Context; + +public class ContraptionDisableActorPacket extends SimplePacketBase { + + private int entityID; + private ItemStack filter; + private boolean enable; + + public ContraptionDisableActorPacket(int entityID, ItemStack filter, boolean enable) { + this.entityID = entityID; + this.filter = filter; + this.enable = enable; + } + + public ContraptionDisableActorPacket(FriendlyByteBuf buffer) { + entityID = buffer.readInt(); + enable = buffer.readBoolean(); + filter = buffer.readItem(); + } + + @Override + public void write(FriendlyByteBuf buffer) { + buffer.writeInt(entityID); + buffer.writeBoolean(enable); + buffer.writeItem(filter); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + Entity entityByID = Minecraft.getInstance().level.getEntity(entityID); + if (!(entityByID instanceof AbstractContraptionEntity ace)) + return; + + Contraption contraption = ace.getContraption(); + List disabledActors = contraption.getDisabledActors(); + if (filter.isEmpty()) + disabledActors.clear(); + + if (!enable) { + disabledActors.add(filter); + contraption.setActorsActive(filter, false); + return; + } + + for (Iterator iterator = disabledActors.iterator(); iterator.hasNext();) { + ItemStack next = iterator.next(); + if (ContraptionControlsMovement.isSameFilter(next, filter) || next.isEmpty()) + iterator.remove(); + } + + contraption.setActorsActive(filter, true); + + }); + context.get() + .setPacketHandled(true); + } + +} 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 7477c48d12..56163a0e25 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 @@ -83,7 +83,9 @@ public class DeployerActorInstance extends ActorInstance { @Override public void beginFrame() { double factor; - if (context.contraption.stalled || context.position == null || context.data.contains("StationaryTimer")) { + if (context.disabled) { + factor = 0; + } else if (context.contraption.stalled || context.position == null || context.data.contains("StationaryTimer")) { factor = Mth.sin(AnimationTickHolder.getRenderTime() * .5f) * .25f + .25f; } else { Vec3 center = VecHelper.getCenterOf(new BlockPos(context.position)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java index 58bedbfd13..9bdd771978 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java @@ -22,26 +22,12 @@ public class DeployerMovingInteraction extends MovingInteractionBehaviour { @Override public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos, AbstractContraptionEntity contraptionEntity) { - StructureBlockInfo info = contraptionEntity.getContraption() - .getBlocks() - .get(localPos); - if (info == null) + MutablePair actor = contraptionEntity.getContraption() + .getActorAt(localPos); + if (actor == null || actor.right == null) return false; - MovementContext ctx = null; - int index = -1; - for (MutablePair pair : contraptionEntity.getContraption() - .getActors()) { - if (info.equals(pair.left)) { - ctx = pair.right; - index = contraptionEntity.getContraption() - .getActors() - .indexOf(pair); - break; - } - } - if (ctx == null) - return false; - + + MovementContext ctx = actor.right; ItemStack heldStack = player.getItemInHand(activeHand); if (heldStack.getItem() .equals(AllItems.WRENCH.get())) { @@ -73,8 +59,8 @@ public class DeployerMovingInteraction extends MovingInteractionBehaviour { ctx.tileData.put("HeldItem", heldStack.serializeNBT()); ctx.data.put("HeldItem", heldStack.serializeNBT()); } - if (index >= 0) - setContraptionActorData(contraptionEntity, index, info, ctx); +// if (index >= 0) +// setContraptionActorData(contraptionEntity, index, info, ctx); return true; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java index e5abdf1fb4..e4388a44c5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java @@ -206,7 +206,8 @@ public class DeployerRenderer extends SafeTileEntityRenderer shaft.rotateCentered(Direction.get(AxisDirection.POSITIVE, Axis.Y), angle); m.popPose(); - m.translate(offset.x, offset.y, offset.z); + if (!context.disabled) + m.translate(offset.x, offset.y, offset.z); pole.transform(m); hand.transform(m); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java index 00af0d4521..0fb21b5f3d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java @@ -448,7 +448,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit context.rotation = v -> applyRotation(v, 1); context.position = actorPosition; - if (!isActorActive(context, actor)) + if (!isActorActive(context, actor) && !actor.mustTickWhileDisabled()) continue; if (newPosVisited && !context.stall) { actor.visitNewPosition(context, gridPosition); 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 51655a2369..ba0f9112c1 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 @@ -21,8 +21,6 @@ import java.util.function.BiConsumer; import javax.annotation.Nullable; -import net.minecraft.world.level.block.DoorBlock; - import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -36,6 +34,7 @@ import com.simibubi.create.content.contraptions.components.actors.BlockBreakingM import com.simibubi.create.content.contraptions.components.actors.HarvesterMovementBehaviour; import com.simibubi.create.content.contraptions.components.actors.SeatBlock; import com.simibubi.create.content.contraptions.components.actors.SeatEntity; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsMovement; import com.simibubi.create.content.contraptions.components.steam.PoweredShaftTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingBlock; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedContraption; @@ -89,12 +88,14 @@ import net.minecraft.network.protocol.game.DebugPackets; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.village.poi.PoiType; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.ButtonBlock; import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.DoorBlock; import net.minecraft.world.level.block.PressurePlateBlock; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.SimpleWaterloggedBlock; @@ -138,6 +139,8 @@ public abstract class Contraption { protected Map blocks; protected List> actors; protected Map interactors; + protected List disabledActors; + protected List superglue; protected List seats; protected Map seatMapping; @@ -163,6 +166,7 @@ public abstract class Contraption { blocks = new HashMap<>(); seats = new ArrayList<>(); actors = new ArrayList<>(); + disabledActors = new ArrayList<>(); modelData = new HashMap<>(); interactors = new HashMap<>(); superglue = new ArrayList<>(); @@ -604,7 +608,7 @@ public abstract class Contraption { blockstate = blockstate.setValue(RedstoneContactBlock.POWERED, true); if (AllBlocks.POWERED_SHAFT.has(blockstate)) blockstate = BlockHelper.copyProperties(blockstate, AllBlocks.SHAFT.getDefaultState()); - if (AllBlocks.CONTROLS.has(blockstate)) + if (blockstate.getBlock() instanceof ControlsBlock) blockstate = blockstate.setValue(ControlsBlock.OPEN, true); if (blockstate.hasProperty(SlidingDoorBlock.VISIBLE)) blockstate = blockstate.setValue(SlidingDoorBlock.VISIBLE, false); @@ -701,6 +705,10 @@ public abstract class Contraption { getActors().add(MutablePair.of(info, context)); }); + disabledActors = NBTHelper.readItemList(nbt.getList("DisabledActors", Tag.TAG_COMPOUND)); + for (ItemStack stack : disabledActors) + setActorsActive(stack, false); + superglue.clear(); NBTHelper.iterateCompoundList(nbt.getList("Superglue", Tag.TAG_COMPOUND), c -> superglue.add(SuperGlueEntity.readBoundingBox(c))); @@ -753,6 +761,8 @@ public abstract class Contraption { actorsNBT.add(compound); } + ListTag disabledActorsNBT = NBTHelper.writeItemList(disabledActors); + ListTag superglueNBT = new ListTag(); if (!spawnPacket) { for (AABB glueEntry : superglue) { @@ -789,6 +799,7 @@ public abstract class Contraption { nbt.put("Blocks", blocksNBT); nbt.put("Actors", actorsNBT); + nbt.put("DisabledActors", disabledActorsNBT); nbt.put("Interactors", interactorNBT); nbt.put("Superglue", superglueNBT); nbt.put("Anchor", NbtUtils.writeBlockPos(anchor)); @@ -1005,7 +1016,7 @@ public abstract class Contraption { if (disassembled) return; disassembled = true; - + for (boolean nonBrittles : Iterate.trueAndFalse) { for (StructureBlockInfo block : blocks.values()) { if (nonBrittles == BlockMovementChecks.isBrittle(block.state)) @@ -1052,7 +1063,8 @@ public abstract class Contraption { boolean verticalRotation = transform.rotationAxis == null || transform.rotationAxis.isHorizontal(); verticalRotation = verticalRotation && transform.rotation != Rotation.NONE; if (verticalRotation) { - if (state.getBlock() instanceof RopeBlock || state.getBlock() instanceof MagnetBlock || state.getBlock() instanceof DoorBlock) + if (state.getBlock() instanceof RopeBlock || state.getBlock() instanceof MagnetBlock + || state.getBlock() instanceof DoorBlock) world.destroyBlock(targetPos, true); } @@ -1119,12 +1131,55 @@ public abstract class Contraption { } public void startMoving(Level world) { + disabledActors.clear(); + for (MutablePair pair : actors) { MovementContext context = new MovementContext(world, pair.left, this); - AllMovementBehaviours.getBehaviour(pair.left.state) - .startMoving(context); + MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.left.state); + behaviour.startMoving(context); pair.setRight(context); + if (behaviour instanceof ContraptionControlsMovement) + disableActorOnStart(context); } + + for (ItemStack stack : disabledActors) + setActorsActive(stack, false); + } + + protected void disableActorOnStart(MovementContext context) { + if (!ContraptionControlsMovement.isDisabledInitially(context)) + return; + ItemStack filter = ContraptionControlsMovement.getFilter(context); + if (filter == null) + return; + if (isActorTypeDisabled(filter)) + return; + disabledActors.add(filter); + } + + public boolean isActorTypeDisabled(ItemStack filter) { + return disabledActors.stream() + .anyMatch(i -> ContraptionControlsMovement.isSameFilter(i, filter)); + } + + public void setActorsActive(ItemStack referenceStack, boolean enable) { + for (MutablePair pair : actors) { + MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.left.state); + if (behaviour == null) + continue; + ItemStack behaviourStack = behaviour.canBeDisabledVia(pair.right); + if (behaviourStack == null) + continue; + if (!referenceStack.isEmpty() && !ContraptionControlsMovement.isSameFilter(referenceStack, behaviourStack)) + continue; + pair.right.disabled = !enable; + if (!enable) + behaviour.onDisabledByControls(pair.right); + } + } + + public List getDisabledActors() { + return disabledActors; } public void stop(Level world) { @@ -1213,6 +1268,14 @@ public abstract class Contraption { return actors; } + @Nullable + public MutablePair getActorAt(BlockPos localPos) { + for (MutablePair pair : actors) + if (localPos.equals(pair.left.pos)) + return pair; + return null; + } + public Map getInteractors() { return interactors; } 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 6d05941234..43aac9a87b 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 @@ -2,12 +2,14 @@ package com.simibubi.create.content.contraptions.components.structureMovement; import static net.minecraft.world.entity.Entity.collideBoundingBox; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableFloat; import org.apache.commons.lang3.mutable.MutableObject; +import org.apache.commons.lang3.tuple.MutablePair; import com.google.common.base.Predicates; import com.simibubi.create.AllBlocks; @@ -27,6 +29,7 @@ import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; +import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -48,6 +51,7 @@ import net.minecraft.world.level.block.CocoaBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.api.distmarker.Dist; @@ -60,6 +64,8 @@ public class ContraptionCollider { NONE, CLIENT, REMOTE, SERVER } + private static MutablePair, Double> safetyLock = new MutablePair<>(); + static void collideEntities(AbstractContraptionEntity contraptionEntity) { Level world = contraptionEntity.getCommandSenderWorld(); Contraption contraption = contraptionEntity.getContraption(); @@ -75,6 +81,10 @@ public class ContraptionCollider { Vec3 anchorVec = contraptionEntity.getAnchorVec(); ContraptionRotationState rotation = null; + if (world.isClientSide() && safetyLock.left != null && safetyLock.left.get() == contraptionEntity) + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, + () -> () -> saveClientPlayerFromClipping(contraptionEntity, contraptionMotion)); + // After death, multiple refs to the client player may show up in the area boolean skipClientPlayer = false; @@ -97,11 +107,12 @@ public class ContraptionCollider { if (playerType == PlayerType.SERVER) continue; - if (playerType == PlayerType.CLIENT) + if (playerType == PlayerType.CLIENT) { if (skipClientPlayer) continue; else skipClientPlayer = true; + } // Init matrix if (rotation == null) @@ -115,13 +126,15 @@ public class ContraptionCollider { float yawOffset = rotation.getYawOffset(); Vec3 position = getWorldToLocalTranslation(entity, anchorVec, rotationMatrix, yawOffset); + motion = motion.subtract(contraptionMotion); + motion = rotationMatrix.transform(motion); + // Prepare entity bounds AABB localBB = entityBounds.move(position) .inflate(1.0E-7D); + OrientedBB obb = new OrientedBB(localBB); obb.setRotation(rotationMatrix); - motion = motion.subtract(contraptionMotion); - motion = rotationMatrix.transform(motion); // Use simplified bbs when present final Vec3 motionCopy = motion; @@ -363,10 +376,67 @@ public class ContraptionCollider { if (limbSwing > 1.0F) limbSwing = 1.0F; AllPackets.channel.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing)); + + if (entity.isOnGround() && contraption instanceof TranslatingContraption) { + safetyLock.setLeft(new WeakReference<>(contraptionEntity)); + safetyLock.setRight(entity.getY() - contraptionEntity.getY()); + } } } + @OnlyIn(Dist.CLIENT) + private static void saveClientPlayerFromClipping(AbstractContraptionEntity contraptionEntity, + Vec3 contraptionMotion) { + Player entity = Minecraft.getInstance().player; + + if (entity.isPassenger()) + return; + + double prevDiff = safetyLock.right; + double currentDiff = entity.getY() - contraptionEntity.getY(); + double motion = contraptionMotion.subtract(entity.getDeltaMovement()).y; + double trend = Math.signum(currentDiff - prevDiff); + + if (trend == 0) + return; + if (trend == Math.signum(motion)) + return; + + double speed = contraptionMotion.multiply(0, 1, 0) + .lengthSqr(); + if (trend > 0 && speed < 0.1) + return; + if (speed < 0.05) + return; + + AABB bb = entity.getBoundingBox().deflate(1/4f, 0, 1/4f); + double shortestDistance = Double.MAX_VALUE; + double yStart = entity.getStepHeight() + contraptionEntity.getY() + prevDiff; + double rayLength = Math.max(5, Math.abs(entity.getY() - yStart)); + + for (int rayIndex = 0; rayIndex < 4; rayIndex++) { + Vec3 start = new Vec3(rayIndex / 2 == 0 ? bb.minX : bb.maxX, yStart, rayIndex % 2 == 0 ? bb.minZ : bb.maxZ); + Vec3 end = start.add(0, -rayLength, 0); + + BlockHitResult hitResult = ContraptionHandlerClient.rayTraceContraption(start, end, contraptionEntity); + if (hitResult == null) + continue; + + Vec3 hit = contraptionEntity.toGlobalVector(hitResult.getLocation(), 1); + double hitDiff = start.y - hit.y; + if (shortestDistance > hitDiff) + shortestDistance = hitDiff; + } + + if (shortestDistance > rayLength) { + safetyLock.setLeft(null); + return; + } + + entity.setPos(entity.getX(), yStart - shortestDistance, entity.getZ()); + } + private static Vec3 handleDamageFromTrain(Level world, AbstractContraptionEntity contraptionEntity, Vec3 contraptionMotion, Entity entity, Vec3 entityMotion, PlayerType playerType) { @@ -374,13 +444,13 @@ public class ContraptionCollider { return entityMotion; if (!entity.isOnGround()) return entityMotion; - + CompoundTag persistentData = entity.getPersistentData(); if (persistentData.contains("ContraptionGrounded")) { persistentData.remove("ContraptionGrounded"); return entityMotion; } - + if (cce.collidingEntities.containsKey(entity)) return entityMotion; if (entity instanceof ItemEntity) @@ -612,7 +682,7 @@ public class ContraptionCollider { .intersects(otherBounds.move(otherMotion))) continue; - for (BlockPos colliderPos : contraption.getColliders(world, movementDirection)) { + for (BlockPos colliderPos : contraption.getOrCreateColliders(world, movementDirection)) { colliderPos = colliderPos.offset(gridPos) .subtract(new BlockPos(otherPosition)); if (!otherContraption.getBlocks() @@ -627,7 +697,7 @@ public class ContraptionCollider { public static boolean isCollidingWithWorld(Level world, TranslatingContraption contraption, BlockPos anchor, Direction movementDirection) { - for (BlockPos pos : contraption.getColliders(world, movementDirection)) { + for (BlockPos pos : contraption.getOrCreateColliders(world, movementDirection)) { BlockPos colliderPos = pos.offset(anchor); if (!world.isLoaded(colliderPos)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionType.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionType.java index 4b5d8fcd02..aa3d98e5f9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionType.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionType.java @@ -8,6 +8,7 @@ import java.util.function.Supplier; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkContraption; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedContraption; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContraption; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraption; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption; import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonContraption; @@ -25,7 +26,8 @@ public class ContraptionType { MOUNTED = register("mounted", MountedContraption::new), STABILIZED = register("stabilized", StabilizedContraption::new), GANTRY = register("gantry", GantryContraption::new), - CARRIAGE = register("carriage", CarriageContraption::new); + CARRIAGE = register("carriage", CarriageContraption::new), + ELEVATOR = register("elevator", ElevatorContraption::new); Supplier factory; String id; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java index 46d7b8ac84..0f8cbc96ad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java @@ -14,6 +14,7 @@ import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -48,6 +49,15 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { entity.setContraption(contraption); return entity; } + + @Override + public void setPos(double x, double y, double z) { + super.setPos(x, y, z); + if (!level.isClientSide()) + return; + for (Entity entity : getPassengers()) + positionRider(entity); + } @Override public Vec3 getContactPointMotion(Vec3 globalContactPoint) { @@ -62,7 +72,6 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { if (contraption instanceof BearingContraption) rotationAxis = ((BearingContraption) contraption).getFacing() .getAxis(); - } @Override @@ -113,6 +122,11 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { public void setAngle(float angle) { this.angle = angle; + + if (!level.isClientSide()) + return; + for (Entity entity : getPassengers()) + positionRider(entity); } public float getAngle(float partialTicks) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementBehaviour.java index 642e7da4f1..4b2359f347 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementBehaviour.java @@ -12,6 +12,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -20,7 +21,7 @@ import net.minecraftforge.items.ItemHandlerHelper; public interface MovementBehaviour { default boolean isActive(MovementContext context) { - return true; + return !context.disabled; } default void tick(MovementContext context) {} @@ -33,6 +34,22 @@ public interface MovementBehaviour { return Vec3.ZERO; } + @Nullable + default ItemStack canBeDisabledVia(MovementContext context) { + Block block = context.state.getBlock(); + if (block == null) + return null; + return new ItemStack(block); + } + + default void onDisabledByControls(MovementContext context) { + cancelStall(context); + } + + default boolean mustTickWhileDisabled() { + return false; + } + default void dropItem(MovementContext context, ItemStack stack) { ItemStack remainder; if (AllConfigs.SERVER.kinetics.moveItemsToStorage.get()) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java index 751044b5b9..e2e1bb0a6d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java @@ -25,6 +25,7 @@ public class MovementContext { public CompoundTag tileData; public boolean stall; + public boolean disabled; public boolean firstMovement; public CompoundTag data; public Contraption contraption; @@ -37,6 +38,7 @@ public class MovementContext { this.contraption = contraption; localPos = info.pos; + disabled = false; firstMovement = true; motion = Vec3.ZERO; relativeMotion = Vec3.ZERO; @@ -49,6 +51,8 @@ public class MovementContext { public float getAnimationSpeed() { int modifier = 1000; double length = -motion.length(); + if (disabled) + return 0; if (world.isClientSide && contraption.stalled) return 700; if (Math.abs(length) < 1 / 512f) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java index b3a2c616c6..5b6ba8e3e2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java @@ -14,29 +14,32 @@ public abstract class TranslatingContraption extends Contraption { protected Set cachedColliders; protected Direction cachedColliderDirection; - public Set getColliders(Level world, Direction movementDirection) { + public Set getOrCreateColliders(Level world, Direction movementDirection) { if (getBlocks() == null) return Collections.emptySet(); if (cachedColliders == null || cachedColliderDirection != movementDirection) { - cachedColliders = new HashSet<>(); cachedColliderDirection = movementDirection; - - for (StructureBlockInfo info : getBlocks().values()) { - BlockPos offsetPos = info.pos.relative(movementDirection); - if (info.state.getCollisionShape(world, offsetPos) - .isEmpty()) - continue; - if (getBlocks().containsKey(offsetPos) - && !getBlocks().get(offsetPos).state.getCollisionShape(world, offsetPos) - .isEmpty()) - continue; - cachedColliders.add(info.pos); - } - + cachedColliders= createColliders(world, movementDirection); } return cachedColliders; } + public Set createColliders(Level world, Direction movementDirection) { + Set colliders = new HashSet<>(); + for (StructureBlockInfo info : getBlocks().values()) { + BlockPos offsetPos = info.pos.relative(movementDirection); + if (info.state.getCollisionShape(world, offsetPos) + .isEmpty()) + continue; + if (getBlocks().containsKey(offsetPos) + && !getBlocks().get(offsetPos).state.getCollisionShape(world, offsetPos) + .isEmpty()) + continue; + colliders.add(info.pos); + } + return colliders; + } + @Override public void removeBlocksFromWorld(Level world, BlockPos offset) { int count = blocks.size(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java index 340db86f89..16d5fb7bdd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java @@ -23,12 +23,18 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; public class StabilizedBearingMovementBehaviour implements MovementBehaviour { + @Override + public ItemStack canBeDisabledVia(MovementContext context) { + return null; + } + @Override @OnlyIn(Dist.CLIENT) public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorColumn.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorColumn.java new file mode 100644 index 0000000000..a13c1c4238 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorColumn.java @@ -0,0 +1,226 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import javax.annotation.Nullable; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.utility.BlockHelper; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.IntAttached; +import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.WorldAttached; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.entity.BlockEntity; + +public class ElevatorColumn { + + public static WorldAttached> LOADED_COLUMNS = + new WorldAttached<>($ -> new HashMap<>()); + + protected LevelAccessor level; + protected ColumnCoords coords; + protected List contacts; + protected int targetedYLevel; + protected boolean isActive; + + @Nullable + public static ElevatorColumn get(LevelAccessor level, ColumnCoords coords) { + return LOADED_COLUMNS.get(level) + .get(coords); + } + + public static ElevatorColumn getOrCreate(LevelAccessor level, ColumnCoords coords) { + return LOADED_COLUMNS.get(level) + .computeIfAbsent(coords, c -> new ElevatorColumn(level, c)); + } + + public ElevatorColumn(LevelAccessor level, ColumnCoords coords) { + this.level = level; + this.coords = coords; + contacts = new ArrayList<>(); + } + + public void markDirty() { + for (BlockPos pos : getContacts()) { + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof ElevatorContactTileEntity ecte) + ecte.setChanged(); + } + } + + public void floorReached(LevelAccessor level, String name) { + getContacts().stream() + .forEach(p -> { + if (level.getBlockEntity(p)instanceof ElevatorContactTileEntity ecte) + ecte.updateDisplayedFloor(name); + }); + } + + public int namesListVersion; + + public List>> compileNamesList() { + return getContacts().stream() + .map(p -> { + if (level.getBlockEntity(p)instanceof ElevatorContactTileEntity ecte) + return IntAttached.with(p.getY(), ecte.getNames()); + return null; + }) + .filter(Objects::nonNull) + .toList(); + } + + public void namesChanged() { + namesListVersion++; + } + + public Collection getContacts() { + return contacts.stream() + .map(this::contactAt) + .toList(); + } + + public void gatherAll() { + BlockPos.betweenClosedStream(contactAt(level.getMinBuildHeight()), contactAt(level.getMaxBuildHeight())) + .filter(p -> coords.equals(ElevatorContactBlock.getColumnCoords(level, p))) + .forEach(p -> level.setBlock(p, + BlockHelper.copyProperties(level.getBlockState(p), AllBlocks.ELEVATOR_CONTACT.getDefaultState()), 3)); + } + + public BlockPos contactAt(int y) { + return new BlockPos(coords.x, y, coords.z); + } + + public void setActive(boolean isActive) { + this.isActive = isActive; + markDirty(); + checkEmpty(); + } + + public boolean isActive() { + return isActive; + } + + public void target(int yLevel) { + targetedYLevel = yLevel; + } + + public int getTargetedYLevel() { + return targetedYLevel; + } + + public void initNames(Level level) { + Integer prevLevel = null; + + for (int i = 0; i < contacts.size(); i++) { + Integer y = contacts.get(i); + + BlockPos pos = contactAt(y); + if (!(level.getBlockEntity(pos)instanceof ElevatorContactTileEntity ecte)) + continue; + + Integer currentLevel = null; + + if (!ecte.shortName.isBlank()) { + Integer tryValueOf = tryValueOf(ecte.shortName); + if (tryValueOf != null) + currentLevel = tryValueOf; + if (currentLevel == null) + continue; + } + + if (prevLevel != null) + currentLevel = prevLevel + 1; + + Integer nextLevel = null; + + for (int peekI = i + 1; peekI < contacts.size(); peekI++) { + BlockPos peekPos = contactAt(contacts.get(peekI)); + if (!(level.getBlockEntity(peekPos)instanceof ElevatorContactTileEntity peekEcte)) + continue; + Integer tryValueOf = tryValueOf(peekEcte.shortName); + if (tryValueOf == null) + continue; + if (currentLevel != null && currentLevel >= tryValueOf) { + peekEcte.shortName = ""; + break; + } + nextLevel = tryValueOf; + break; + } + + if (currentLevel == null) + currentLevel = nextLevel != null ? nextLevel - 1 : 0; + + ecte.updateName(String.valueOf(currentLevel), ecte.longName); + prevLevel = currentLevel; + } + + } + + private static Integer tryValueOf(String floorName) { + try { + return Integer.valueOf(floorName, 10); + } catch (NumberFormatException nfe) { + return null; + } + } + + public void add(BlockPos contactPos) { + int coord = contactPos.getY(); + if (contacts.contains(coord)) + return; + int index = 0; + for (; index < contacts.size(); index++) + if (contacts.get(index) > coord) + break; + contacts.add(index, coord); + namesChanged(); + } + + public void remove(BlockPos contactPos) { + contacts.remove((Object) contactPos.getY()); + checkEmpty(); + namesChanged(); + } + + private void checkEmpty() { + if (contacts.isEmpty() && !isActive()) + LOADED_COLUMNS.get(level) + .remove(coords); + } + + public static record ColumnCoords(int x, int z, Direction side) { + + public ColumnCoords relative(BlockPos anchor) { + return new ColumnCoords(x + anchor.getX(), z + anchor.getZ(), side); + } + + public CompoundTag write() { + CompoundTag tag = new CompoundTag(); + tag.putInt("X", x); + tag.putInt("Z", z); + NBTHelper.writeEnum(tag, "Side", side); + return tag; + } + + public static ColumnCoords read(CompoundTag tag) { + int x = tag.getInt("X"); + int z = tag.getInt("Z"); + Direction side = NBTHelper.readEnum(tag, "Side", Direction.class); + return new ColumnCoords(x, z, side); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java new file mode 100644 index 0000000000..f0e3c7df05 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java @@ -0,0 +1,217 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.util.Optional; +import java.util.Random; + +import javax.annotation.Nullable; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorColumn.ColumnCoords; +import com.simibubi.create.content.logistics.block.diodes.BrassDiodeBlock; +import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock; +import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement; +import com.simibubi.create.content.schematics.ItemRequirement; +import com.simibubi.create.foundation.block.ITE; +import com.simibubi.create.foundation.block.WrenchableDirectionalBlock; +import com.simibubi.create.foundation.gui.ScreenOpener; + +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.NonNullList; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition.Builder; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; + +public class ElevatorContactBlock extends WrenchableDirectionalBlock + implements ITE, ISpecialBlockItemRequirement { + + public static final BooleanProperty POWERED = BlockStateProperties.POWERED; + public static final BooleanProperty CALLING = BooleanProperty.create("calling"); + public static final BooleanProperty POWERING = BrassDiodeBlock.POWERING; + + public ElevatorContactBlock(Properties pProperties) { + super(pProperties); + registerDefaultState(defaultBlockState().setValue(CALLING, false) + .setValue(POWERING, false) + .setValue(POWERED, false) + .setValue(FACING, Direction.SOUTH)); + } + + @Override + protected void createBlockStateDefinition(Builder builder) { + super.createBlockStateDefinition(builder.add(CALLING, POWERING, POWERED)); + } + + @Nullable + public static ColumnCoords getColumnCoords(LevelAccessor level, BlockPos pos) { + BlockState blockState = level.getBlockState(pos); + if (!AllBlocks.ELEVATOR_CONTACT.has(blockState) && !AllBlocks.REDSTONE_CONTACT.has(blockState)) + return null; + Direction facing = blockState.getValue(FACING); + BlockPos target = pos; + return new ColumnCoords(target.getX(), target.getZ(), facing); + } + + @Override + public void neighborChanged(BlockState pState, Level pLevel, BlockPos pPos, Block pBlock, BlockPos pFromPos, + boolean pIsMoving) { + if (pLevel.isClientSide) + return; + + boolean isPowered = pState.getValue(POWERED); + if (isPowered == pLevel.hasNeighborSignal(pPos)) + return; + + pLevel.setBlock(pPos, pState.cycle(POWERED), 2); + + if (isPowered) + return; + if (pState.getValue(CALLING)) + return; + + pLevel.setBlock(pPos, pState.cycle(CALLING), 2); + + ElevatorColumn elevatorColumn = ElevatorColumn.getOrCreate(pLevel, getColumnCoords(pLevel, pPos)); + for (BlockPos otherPos : elevatorColumn.getContacts()) { + if (otherPos.equals(pPos)) + continue; + BlockState otherState = pLevel.getBlockState(otherPos); + if (!AllBlocks.ELEVATOR_CONTACT.has(otherState)) + continue; + pLevel.setBlock(otherPos, otherState.setValue(CALLING, false), 2); + scheduleActivation(pLevel, otherPos); + } + + pLevel.setBlock(pPos, pState.setValue(POWERED, true) + .setValue(CALLING, true), 2); + pLevel.updateNeighborsAt(pPos, this); + + elevatorColumn.target(pPos.getY()); + elevatorColumn.markDirty(); + } + + public void scheduleActivation(LevelAccessor pLevel, BlockPos pPos) { + if (!pLevel.getBlockTicks() + .hasScheduledTick(pPos, this)) + pLevel.scheduleTick(pPos, this, 1); + } + + @Override + public void tick(BlockState pState, ServerLevel pLevel, BlockPos pPos, Random pRand) { + boolean wasPowering = pState.getValue(POWERING); + + Optional optionalTE = getTileEntityOptional(pLevel, pPos); + boolean shouldBePowering = optionalTE.map(te -> { + boolean activateBlock = te.activateBlock; + te.activateBlock = false; + te.setChanged(); + return activateBlock; + }) + .orElse(false); + + shouldBePowering |= RedstoneContactBlock.hasValidContact(pLevel, pPos, pState.getValue(FACING)); + + if (wasPowering || shouldBePowering) + pLevel.setBlock(pPos, pState.setValue(POWERING, shouldBePowering), 2); + + pLevel.updateNeighborsAt(pPos, this); + } + + @Override + public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor worldIn, + BlockPos currentPos, BlockPos facingPos) { + if (facing != stateIn.getValue(FACING)) + return stateIn; + boolean hasValidContact = RedstoneContactBlock.hasValidContact(worldIn, currentPos, facing); + if (stateIn.getValue(POWERING) != hasValidContact) + scheduleActivation(worldIn, currentPos); + return stateIn; + } + + @Override + public boolean shouldCheckWeakPower(BlockState state, LevelReader level, BlockPos pos, Direction side) { + return false; + } + + @Override + public boolean isSignalSource(BlockState state) { + return state.getValue(POWERING); + } + + @Override + public ItemStack getCloneItemStack(BlockGetter pLevel, BlockPos pPos, BlockState pState) { + return AllBlocks.REDSTONE_CONTACT.asStack(); + } + + @Override + public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) { + if (side == null) + return true; + return state.getValue(FACING) != side.getOpposite(); + } + + @Override + public int getSignal(BlockState state, BlockGetter blockAccess, BlockPos pos, Direction side) { + return state.getValue(POWERING) ? 15 : 0; + } + + @Override + public Class getTileEntityClass() { + return ElevatorContactTileEntity.class; + } + + @Override + public BlockEntityType getTileEntityType() { + return AllTileEntities.ELEVATOR_CONTACT.get(); + } + + @Override + public void fillItemCategory(CreativeModeTab pTab, NonNullList pItems) {} + + @Override + public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) { + return ItemRequirement.of(AllBlocks.REDSTONE_CONTACT.getDefaultState(), te); + } + + @Override + public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, + BlockHitResult hit) { + if (player != null && AllItems.WRENCH.isIn(player.getItemInHand(handIn))) + return InteractionResult.PASS; + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, + () -> () -> withTileEntityDo(worldIn, pos, te -> this.displayScreen(te, player))); + return InteractionResult.SUCCESS; + } + + @OnlyIn(value = Dist.CLIENT) + protected void displayScreen(ElevatorContactTileEntity te, Player player) { + if (player instanceof LocalPlayer) + ScreenOpener.open(new ElevatorContactScreen(te.getBlockPos(), te.shortName, te.longName)); + } + + public static int getLight(BlockState state) { + return state.getValue(POWERING) ? 10 : state.getValue(CALLING) ? 5 : 0; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactEditPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactEditPacket.java new file mode 100644 index 0000000000..7fd24f4908 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactEditPacket.java @@ -0,0 +1,40 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; + +public class ElevatorContactEditPacket extends TileEntityConfigurationPacket { + + private String shortName; + private String longName; + + public ElevatorContactEditPacket(BlockPos pos, String shortName, String longName) { + super(pos); + this.shortName = shortName; + this.longName = longName; + } + + public ElevatorContactEditPacket(FriendlyByteBuf buffer) { + super(buffer); + } + + @Override + protected void writeSettings(FriendlyByteBuf buffer) { + buffer.writeUtf(shortName, 4); + buffer.writeUtf(longName, 30); + } + + @Override + protected void readSettings(FriendlyByteBuf buffer) { + shortName = buffer.readUtf(4); + longName = buffer.readUtf(30); + } + + @Override + protected void applySettings(ElevatorContactTileEntity te) { + te.updateName(shortName, longName); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactScreen.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactScreen.java new file mode 100644 index 0000000000..a7d2f8466d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactScreen.java @@ -0,0 +1,171 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import org.lwjgl.glfw.GLFW; + +import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.element.GuiGameElement; +import com.simibubi.create.foundation.gui.widget.IconButton; +import com.simibubi.create.foundation.gui.widget.TooltipArea; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.util.FormattedCharSequence; + +public class ElevatorContactScreen extends AbstractSimiScreen { + + private AllGuiTextures background; + + private EditBox shortNameInput; + private EditBox longNameInput; + private IconButton confirm; + + private String shortName; + private String longName; + + private BlockPos pos; + + public ElevatorContactScreen(BlockPos pos, String prevShortName, String prevLongName) { + super(Lang.translateDirect("elevator_contact.title")); + this.pos = pos; + background = AllGuiTextures.ELEVATOR_CONTACT; + this.shortName = prevShortName; + this.longName = prevLongName; + } + + @Override + public void init() { + setWindowSize(background.width + 30, background.height); + super.init(); + + int x = guiLeft; + int y = guiTop; + + confirm = new IconButton(x + 200, y + 58, AllIcons.I_CONFIRM); + confirm.withCallback(this::confirm); + addRenderableWidget(confirm); + + shortNameInput = editBox(33, 30, 4); + shortNameInput.setValue(shortName); + centerInput(x); + shortNameInput.setResponder(s -> { + shortName = s; + centerInput(x); + }); + shortNameInput.changeFocus(true); + setFocused(shortNameInput); + shortNameInput.setHighlightPos(0); + + longNameInput = editBox(63, 140, 30); + longNameInput.setValue(longName); + longNameInput.setResponder(s -> longName = s); + + MutableComponent rmbToEdit = Lang.translate("gui.schedule.lmb_edit") + .style(ChatFormatting.DARK_GRAY) + .style(ChatFormatting.ITALIC) + .component(); + + addRenderableOnly(new TooltipArea(x + 21, y + 23, 30, 18) + .withTooltip(ImmutableList.of(Lang.translate("elevator_contact.floor_identifier") + .color(0x5391E1) + .component(), rmbToEdit))); + + addRenderableOnly(new TooltipArea(x + 57, y + 23, 147, 18).withTooltip(ImmutableList.of( + Lang.translate("elevator_contact.floor_description") + .color(0x5391E1) + .component(), + Lang.translate("crafting_blueprint.optional") + .style(ChatFormatting.GRAY) + .component(), + rmbToEdit))); + + } + + private int centerInput(int x) { + return shortNameInput.x = x + (shortName.isEmpty() ? 34 : 36 - font.width(shortName) / 2); + } + + private EditBox editBox(int x, int width, int chars) { + EditBox editBox = new EditBox(font, guiLeft + x, guiTop + 30, width, 10, Components.immutableEmpty()); + editBox.setTextColor(-1); + editBox.setTextColorUneditable(-1); + editBox.setBordered(false); + editBox.setMaxLength(chars); + editBox.changeFocus(false); + editBox.mouseClicked(0, 0, 0); + addRenderableWidget(editBox); + return editBox; + } + + @Override + protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) { + int x = guiLeft; + int y = guiTop; + + background.render(ms, x, y, this); + + FormattedCharSequence formattedcharsequence = title.getVisualOrderText(); + font.draw(ms, formattedcharsequence, + (float) (x + (background.width - 8) / 2 - font.width(formattedcharsequence) / 2), (float) y + 6, 0x2F3738); + + GuiGameElement.of(AllBlocks.ELEVATOR_CONTACT.asStack()).at(x + background.width + 6, y + background.height - 56, -200) + .scale(5) + .render(ms); + + } + + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { + boolean consumed = super.mouseClicked(pMouseX, pMouseY, pButton); + + if (!shortNameInput.isFocused()) { + int length = shortNameInput.getValue() + .length(); + shortNameInput.setHighlightPos(length); + shortNameInput.setCursorPosition(length); + } + + if (shortNameInput.isHoveredOrFocused()) + longNameInput.mouseClicked(0, 0, 0); + + if (!consumed && pMouseX > guiLeft + 22 && pMouseY > guiTop + 24 && pMouseX < guiLeft + 50 + && pMouseY < guiTop + 40) { + setFocused(shortNameInput); + shortNameInput.changeFocus(true); + return true; + } + + return consumed; + } + + @Override + public boolean keyPressed(int keyCode, int p_keyPressed_2_, int p_keyPressed_3_) { + if (super.keyPressed(keyCode, p_keyPressed_2_, p_keyPressed_3_)) + return true; + if (keyCode == GLFW.GLFW_KEY_ENTER) { + confirm(); + return true; + } + if (keyCode == 256 && this.shouldCloseOnEsc()) { + this.onClose(); + return true; + } + return false; + } + + private void confirm() { + AllPackets.channel.sendToServer(new ElevatorContactEditPacket(pos, shortName, longName)); + onClose(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactTileEntity.java new file mode 100644 index 0000000000..87d287cb39 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactTileEntity.java @@ -0,0 +1,154 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.util.List; + +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorColumn.ColumnCoords; +import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.NBTHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class ElevatorContactTileEntity extends SmartTileEntity { + + public ColumnCoords columnCoords; + public boolean activateBlock; + + public String shortName; + public String longName; + + public String lastReportedCurrentFloor; + + private int yTargetFromNBT = Integer.MIN_VALUE; + private boolean deferNameGenerator; + + public ElevatorContactTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + shortName = ""; + longName = ""; + deferNameGenerator = false; + } + + @Override + public void addBehaviours(List behaviours) {} + + @Override + protected void write(CompoundTag tag, boolean clientPacket) { + super.write(tag, clientPacket); + + tag.putString("ShortName", shortName); + tag.putString("LongName", longName); + + if (lastReportedCurrentFloor != null) + tag.putString("LastReportedCurrentFloor", lastReportedCurrentFloor); + + if (clientPacket) + return; + tag.putBoolean("Activate", activateBlock); + if (columnCoords == null) + return; + + ElevatorColumn column = ElevatorColumn.get(level, columnCoords); + if (column == null) + return; + tag.putInt("ColumnTarget", column.getTargetedYLevel()); + if (column.isActive()) + NBTHelper.putMarker(tag, "ColumnActive"); + } + + @Override + protected void read(CompoundTag tag, boolean clientPacket) { + super.read(tag, clientPacket); + + shortName = tag.getString("ShortName"); + longName = tag.getString("LongName"); + + if (tag.contains("LastReportedCurrentFloor")) + lastReportedCurrentFloor = tag.getString("LastReportedCurrentFloor"); + + if (clientPacket) + return; + activateBlock = tag.getBoolean("Activate"); + if (!tag.contains("ColumnTarget")) + return; + + int target = tag.getInt("ColumnTarget"); + boolean active = tag.contains("ColumnActive"); + + if (columnCoords == null) { + yTargetFromNBT = target; + return; + } + + ElevatorColumn column = ElevatorColumn.getOrCreate(level, columnCoords); + column.target(target); + column.setActive(active); + } + + public void updateDisplayedFloor(String floor) { + if (floor.equals(lastReportedCurrentFloor)) + return; + lastReportedCurrentFloor = floor; + DisplayLinkBlock.notifyGatherers(level, worldPosition); + } + + @Override + public void initialize() { + super.initialize(); + if (level.isClientSide()) + return; + columnCoords = ElevatorContactBlock.getColumnCoords(level, worldPosition); + if (columnCoords == null) + return; + ElevatorColumn column = ElevatorColumn.getOrCreate(level, columnCoords); + column.add(worldPosition); + if (shortName.isBlank()) + deferNameGenerator = true; + if (yTargetFromNBT == Integer.MIN_VALUE) + return; + column.target(yTargetFromNBT); + yTargetFromNBT = Integer.MIN_VALUE; + } + + @Override + public void tick() { + super.tick(); + if (!deferNameGenerator) + return; + if (columnCoords != null) + ElevatorColumn.getOrCreate(level, columnCoords) + .initNames(level); + deferNameGenerator = false; + } + + @Override + public void setRemoved() { + if (columnCoords != null) { + ElevatorColumn column = ElevatorColumn.get(level, columnCoords); + if (column != null) + column.remove(worldPosition); + } + super.setRemoved(); + } + + public void updateName(String shortName, String longName) { + this.shortName = shortName; + this.longName = longName; + this.deferNameGenerator = false; + notifyUpdate(); + + ElevatorColumn column = ElevatorColumn.get(level, columnCoords); + if (column != null) + column.namesChanged(); + } + + public Couple getNames() { + return Couple.create(shortName, longName); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContraption.java new file mode 100644 index 0000000000..c33b8e7f0e --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContraption.java @@ -0,0 +1,180 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.util.List; + +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.tuple.Pair; + +import com.google.common.collect.ImmutableList; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsMovement.ElevatorFloorSelection; +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorColumn.ColumnCoords; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyContraption; +import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.IntAttached; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; +import net.minecraftforge.network.PacketDistributor; + +public class ElevatorContraption extends PulleyContraption { + + protected ColumnCoords column; + protected int contactYOffset; + public boolean arrived; + + private int namesListVersion = -1; + public List>> namesList = ImmutableList.of(); + public int clientYTarget; + + // during assembly only + private int contacts; + + public ElevatorContraption() { + super(); + } + + public ElevatorContraption(int initialOffset) { + super(initialOffset); + } + + @Override + public void tickStorage(AbstractContraptionEntity entity) { + super.tickStorage(entity); + + if (entity.tickCount % 10 != 0) + return; + + ColumnCoords coords = getGlobalColumn(); + ElevatorColumn column = ElevatorColumn.get(entity.level, coords); + + if (column == null) + return; + if (column.namesListVersion == namesListVersion) + return; + + namesList = column.compileNamesList(); + namesListVersion = column.namesListVersion; + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), + new ElevatorFloorListPacket(entity, namesList)); + } + + @Override + protected void disableActorOnStart(MovementContext context) {} + + public ColumnCoords getGlobalColumn() { + return column.relative(anchor); + } + + public Integer getCurrentTargetY(Level level) { + ColumnCoords coords = getGlobalColumn(); + ElevatorColumn column = ElevatorColumn.get(level, coords); + if (column == null) + return null; + return column.targetedYLevel; + } + + @Override + public boolean assemble(Level world, BlockPos pos) throws AssemblyException { + if (!searchMovedStructure(world, pos, null)) + return false; + if (blocks.size() <= 0) + return false; + if (contacts == 0) + throw new AssemblyException(Lang.translateDirect("elevator_assembly.no_contacts")); + if (contacts > 1) + throw new AssemblyException(Lang.translateDirect("train_assembly.too_many_contacts")); + startMoving(world); + return true; + } + + @Override + protected Pair capture(Level world, BlockPos pos) { + BlockState blockState = world.getBlockState(pos); + + if (!AllBlocks.REDSTONE_CONTACT.has(blockState)) + return super.capture(world, pos); + + Direction facing = blockState.getValue(RedstoneContactBlock.FACING); + if (facing.getAxis() == Axis.Y) + return super.capture(world, pos); + + contacts++; + BlockPos local = toLocalPos(pos.relative(facing)); + column = new ColumnCoords(local.getX(), local.getZ(), facing.getOpposite()); + contactYOffset = local.getY(); + + return super.capture(world, pos); + } + + public int getContactYOffset() { + return contactYOffset; + } + + public void broadcastFloorData(Level level, BlockPos contactPos) { + ElevatorColumn column = ElevatorColumn.get(level, getGlobalColumn()); + if (!(world.getBlockEntity(contactPos)instanceof ElevatorContactTileEntity ecte)) + return; + if (column != null) + column.floorReached(level, ecte.shortName); + } + + @Override + public CompoundTag writeNBT(boolean spawnPacket) { + CompoundTag tag = super.writeNBT(spawnPacket); + tag.putBoolean("Arrived", arrived); + tag.put("Column", column.write()); + tag.putInt("ContactY", contactYOffset); + return tag; + } + + @Override + public void readNBT(Level world, CompoundTag nbt, boolean spawnData) { + arrived = nbt.getBoolean("Arrived"); + column = ColumnCoords.read(nbt.getCompound("Column")); + contactYOffset = nbt.getInt("ContactY"); + super.readNBT(world, nbt, spawnData); + } + + @Override + protected ContraptionType getType() { + return ContraptionType.ELEVATOR; + } + + public void setClientYTarget(int clientYTarget) { + if (this.clientYTarget == clientYTarget) + return; + + this.clientYTarget = clientYTarget; + syncControlDisplays(); + } + + public void syncControlDisplays() { + if (namesList.isEmpty()) + return; + for (int i = 0; i < namesList.size(); i++) + if (namesList.get(i) + .getFirst() == clientYTarget) + setAllControlsToFloor(i); + } + + public void setAllControlsToFloor(int floorIndex) { + for (MutablePair pair : actors) + if (pair.right != null && pair.right.temporaryData instanceof ElevatorFloorSelection efs) + efs.currentIndex = floorIndex; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorControlsHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorControlsHandler.java new file mode 100644 index 0000000000..bc603011b2 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorControlsHandler.java @@ -0,0 +1,117 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.lang.ref.WeakReference; +import java.util.Collection; + +import org.apache.commons.lang3.tuple.MutablePair; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsMovement; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsMovement.ElevatorFloorSelection; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsTileEntity; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionControlsTileEntity.ControlsSlot; +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.ContraptionHandler; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandlerClient; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.utility.Couple; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public class ElevatorControlsHandler { + + private static ControlsSlot slot = new ContraptionControlsTileEntity.ControlsSlot(); + + @OnlyIn(Dist.CLIENT) + public static boolean onScroll(double delta) { + Minecraft mc = Minecraft.getInstance(); + LocalPlayer player = mc.player; + + if (player == null) + return false; + if (player.isSpectator()) + return false; + if (mc.level == null) + return false; + + Couple rayInputs = ContraptionHandlerClient.getRayInputs(player); + Vec3 origin = rayInputs.getFirst(); + Vec3 target = rayInputs.getSecond(); + AABB aabb = new AABB(origin, target).inflate(16); + + Collection> contraptions = + ContraptionHandler.loadedContraptions.get(mc.level) + .values(); + + for (WeakReference ref : contraptions) { + AbstractContraptionEntity contraptionEntity = ref.get(); + if (contraptionEntity == null) + continue; + + Contraption contraption = contraptionEntity.getContraption(); + if (!(contraption instanceof ElevatorContraption ec)) + continue; + + if (!contraptionEntity.getBoundingBox() + .intersects(aabb)) + continue; + + BlockHitResult rayTraceResult = + ContraptionHandlerClient.rayTraceContraption(origin, target, contraptionEntity); + if (rayTraceResult == null) + continue; + + BlockPos pos = rayTraceResult.getBlockPos(); + StructureBlockInfo info = contraption.getBlocks() + .get(pos); + + if (info == null) + continue; + if (!AllBlocks.CONTRAPTION_CONTROLS.has(info.state)) + continue; + + if (!slot.testHit(info.state, rayTraceResult.getLocation() + .subtract(Vec3.atLowerCornerOf(pos)))) + continue; + + MovementContext ctx = null; + for (MutablePair pair : contraption.getActors()) { + if (info.equals(pair.left)) { + ctx = pair.right; + break; + } + } + + if (!(ctx.temporaryData instanceof ElevatorFloorSelection)) + ctx.temporaryData = new ElevatorFloorSelection(); + + ElevatorFloorSelection efs = (ElevatorFloorSelection) ctx.temporaryData; + int prev = efs.currentIndex; + efs.currentIndex += delta; + ContraptionControlsMovement.tickFloorSelection(efs, ec); + + if (prev != efs.currentIndex && !ec.namesList.isEmpty()) { + float pitch = (efs.currentIndex) / (float) (ec.namesList.size()); + pitch = Mth.lerp(pitch, 1f, 1.5f); + AllSoundEvents.SCROLL_VALUE.play(mc.player.level, mc.player, + new BlockPos(contraptionEntity.toGlobalVector(rayTraceResult.getLocation(), 1)), 1, pitch); + } + + return true; + } + + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorFloorListPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorFloorListPacket.java new file mode 100644 index 0000000000..b314c10fed --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorFloorListPacket.java @@ -0,0 +1,103 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.networking.SimplePacketBase; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.IntAttached; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.network.NetworkEvent.Context; +import net.minecraftforge.network.PacketDistributor; + +public class ElevatorFloorListPacket extends SimplePacketBase { + + private int entityId; + private List>> floorsList; + + public ElevatorFloorListPacket(AbstractContraptionEntity entity, List>> floorsList) { + this.entityId = entity.getId(); + this.floorsList = floorsList; + } + + public ElevatorFloorListPacket(FriendlyByteBuf buffer) { + entityId = buffer.readInt(); + int size = buffer.readInt(); + floorsList = new ArrayList<>(); + for (int i = 0; i < size; i++) + floorsList.add(IntAttached.with(buffer.readInt(), Couple.create(buffer.readUtf(), buffer.readUtf()))); + } + + @Override + public void write(FriendlyByteBuf buffer) { + buffer.writeInt(entityId); + buffer.writeInt(floorsList.size()); + for (IntAttached> entry : floorsList) { + buffer.writeInt(entry.getFirst()); + entry.getSecond() + .forEach(buffer::writeUtf); + } + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + + Entity entityByID = Minecraft.getInstance().level.getEntity(entityId); + if (!(entityByID instanceof AbstractContraptionEntity ace)) + return; + if (!(ace.getContraption()instanceof ElevatorContraption ec)) + return; + + ec.namesList = floorsList; + ec.syncControlDisplays(); + }); + context.get() + .setPacketHandled(true); + } + + public static class RequestFloorList extends SimplePacketBase { + + private int entityId; + + public RequestFloorList(AbstractContraptionEntity entity) { + this.entityId = entity.getId(); + } + + public RequestFloorList(FriendlyByteBuf buffer) { + entityId = buffer.readInt(); + } + + @Override + public void write(FriendlyByteBuf buffer) { + buffer.writeInt(entityId); + } + + @Override + public void handle(Supplier context) { + Context ctx = context.get(); + ctx.enqueueWork(() -> { + ServerPlayer sender = ctx.getSender(); + Entity entityByID = sender.getLevel() + .getEntity(entityId); + if (!(entityByID instanceof AbstractContraptionEntity ace)) + return; + if (!(ace.getContraption()instanceof ElevatorContraption ec)) + return; + AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> sender), + new ElevatorFloorListPacket(ace, ec.namesList)); + }); + ctx.setPacketHandled(true); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyBlock.java new file mode 100644 index 0000000000..6fc11c1cb8 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyBlock.java @@ -0,0 +1,74 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import com.simibubi.create.AllShapes; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock; +import com.simibubi.create.foundation.block.ITE; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class ElevatorPulleyBlock extends HorizontalKineticBlock implements ITE { + + public ElevatorPulleyBlock(Properties properties) { + super(properties); + } + + @Override + public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, + BlockHitResult hit) { + if (!player.mayBuild()) + return InteractionResult.FAIL; + if (player.isShiftKeyDown()) + return InteractionResult.FAIL; + if (!player.getItemInHand(handIn) + .isEmpty()) + return InteractionResult.PASS; + if (worldIn.isClientSide) + return InteractionResult.SUCCESS; + return onTileEntityUse(worldIn, pos, te -> { + te.clicked(); + return InteractionResult.SUCCESS; + }); + } + + @Override + public BlockEntityType getTileEntityType() { + return AllTileEntities.ELEVATOR_PULLEY.get(); + } + + @Override + public Axis getRotationAxis(BlockState state) { + return state.getValue(HORIZONTAL_FACING) + .getClockWise() + .getAxis(); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { + return AllShapes.ELEVATOR_PULLEY.get(state.getValue(HORIZONTAL_FACING)); + } + + @Override + public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { + return getRotationAxis(state) == face.getAxis(); + } + + @Override + public Class getTileEntityClass() { + return ElevatorPulleyTileEntity.class; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyInstance.java new file mode 100644 index 0000000000..3eb8693c6b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyInstance.java @@ -0,0 +1,25 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.light.TickingLightListener; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; + +// TODO +public class ElevatorPulleyInstance extends ShaftInstance implements DynamicInstance, TickingLightListener { + + public ElevatorPulleyInstance(MaterialManager dispatcher, KineticTileEntity tile) { + super(dispatcher, tile); + } + + @Override + public boolean tickLightListener() { + return false; + } + + @Override + public void beginFrame() { + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyRenderer.java new file mode 100644 index 0000000000..b0e18abd28 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyRenderer.java @@ -0,0 +1,123 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.AllSpriteShifts; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.AbstractPulleyRenderer; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyRenderer; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; +import com.simibubi.create.foundation.block.render.SpriteShiftEntry; +import com.simibubi.create.foundation.render.CachedBufferer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.utility.AngleHelper; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +public class ElevatorPulleyRenderer extends KineticTileEntityRenderer { + + public ElevatorPulleyRenderer(BlockEntityRendererProvider.Context context) { + super(context); + } + + @Override + protected void renderSafe(KineticTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer, + int light, int overlay) { + +// if (Backend.canUseInstancing(te.getLevel())) +// return; + + // from KTE. replace with super call when flw instance is implemented + BlockState state = getRenderedBlockState(te); + RenderType type = getRenderType(te, state); + if (type != null) + renderRotatingBuffer(te, getRotatedModel(te, state), ms, buffer.getBuffer(type), light); + // + + float offset = PulleyRenderer.getTileOffset(partialTicks, (PulleyTileEntity) te); + boolean running = PulleyRenderer.isPulleyRunning(te); + + SpriteShiftEntry beltShift = AllSpriteShifts.ELEVATOR_BELT; + SpriteShiftEntry coilShift = AllSpriteShifts.ELEVATOR_COIL; + VertexConsumer vb = buffer.getBuffer(RenderType.solid()); + Level world = te.getLevel(); + BlockState blockState = te.getBlockState(); + BlockPos pos = te.getBlockPos(); + + SuperByteBuffer magnet = CachedBufferer.partial(AllBlockPartials.ELEVATOR_MAGNET, blockState); + if (running || offset == 0) + AbstractPulleyRenderer.renderAt(world, magnet, offset, pos, ms, vb); + + SuperByteBuffer rotatedCoil = getRotatedCoil(te); + if (offset == 0) { + rotatedCoil.light(light) + .renderInto(ms, vb); + return; + } + + float spriteSize = beltShift.getTarget() + .getV1() + - beltShift.getTarget() + .getV0(); + + double coilScroll = -(offset + 3 / 16f) - Math.floor((offset + 3 / 16f) * -2) / 2; + double beltScroll = (-(offset + .5) - Math.floor(-(offset + .5))) / 2; + + rotatedCoil.shiftUVScrolling(coilShift, (float) coilScroll * spriteSize) + .light(light) + .renderInto(ms, vb); + + SuperByteBuffer halfRope = CachedBufferer.partial(AllBlockPartials.ELEVATOR_BELT_HALF, blockState); + SuperByteBuffer rope = CachedBufferer.partial(AllBlockPartials.ELEVATOR_BELT, blockState); + + float f = offset % 1; + if (f < .25f || f > .75f) { + halfRope.centre() + .rotateY(180 + AngleHelper.horizontalAngle(blockState.getValue(ElevatorPulleyBlock.HORIZONTAL_FACING))) + .unCentre(); + AbstractPulleyRenderer.renderAt(world, + halfRope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize), f > .75f ? f - 1 : f, pos, ms, + vb); + } + + if (!running) + return; + + for (int i = 0; i < offset - .25f; i++) { + rope.centre() + .rotateY(180 + AngleHelper.horizontalAngle(blockState.getValue(ElevatorPulleyBlock.HORIZONTAL_FACING))) + .unCentre(); + AbstractPulleyRenderer.renderAt(world, rope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize), + offset - i, pos, ms, vb); + } + } + + @Override + protected BlockState getRenderedBlockState(KineticTileEntity te) { + return shaft(getRotationAxisOf(te)); + } + + protected SuperByteBuffer getRotatedCoil(KineticTileEntity te) { + BlockState blockState = te.getBlockState(); + return CachedBufferer.partialFacing(AllBlockPartials.ELEVATOR_COIL, blockState, + blockState.getValue(ElevatorPulleyBlock.HORIZONTAL_FACING)); + } + + @Override + public int getViewDistance() { + return 128; + } + + @Override + public boolean shouldRenderOffScreen(KineticTileEntity p_188185_1_) { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyTileEntity.java new file mode 100644 index 0000000000..a9175c9f7d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorPulleyTileEntity.java @@ -0,0 +1,316 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.util.List; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; +import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorColumn.ColumnCoords; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; +import com.simibubi.create.foundation.advancement.AllAdvancements; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class ElevatorPulleyTileEntity extends PulleyTileEntity { + + private float prevSpeed; + private boolean arrived; + private int clientOffsetTarget; + private boolean initialOffsetReceived; + + public ElevatorPulleyTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + prevSpeed = 0; + arrived = true; + initialOffsetReceived = false; + } + + private int getTargetOffset() { + if (level.isClientSide) + return clientOffsetTarget; + if (movedContraption == null || !(movedContraption.getContraption()instanceof ElevatorContraption ec)) + return (int) offset; + + Integer target = ec.getCurrentTargetY(level); + if (target == null) + return (int) offset; + + return worldPosition.getY() - target + ec.contactYOffset - 1; + } + + @Override + public void attach(ControlledContraptionEntity contraption) { + super.attach(contraption); + if (offset >= 0) + resetContraptionToOffset(); + if (level.isClientSide) { + AllPackets.channel.sendToServer(new ElevatorFloorListPacket.RequestFloorList(contraption)); + return; + } + + if (contraption.getContraption()instanceof ElevatorContraption ec) + ElevatorColumn.getOrCreate(level, ec.getGlobalColumn()) + .setActive(true); + } + + @Override + public void tick() { + boolean wasArrived = arrived; + super.tick(); + + if (movedContraption == null) + return; + if (!(movedContraption.getContraption()instanceof ElevatorContraption ec)) + return; + if (level.isClientSide()) + ec.setClientYTarget(worldPosition.getY() - clientOffsetTarget + ec.contactYOffset - 1); + + ec.arrived = wasArrived; + + if (!arrived) + return; + + double y = movedContraption.getY(); + int targetLevel = Mth.floor(0.5f + y); + if (!wasArrived && !level.isClientSide()) { + triggerContact(ec, targetLevel); + AllSoundEvents.CONTRAPTION_DISASSEMBLE.play(level, null, worldPosition.below((int) offset), 0.75f, 0.8f); + } + + double diff = targetLevel - y; + if (Math.abs(diff) > 1f / 128) + diff *= 0.25f; + movedContraption.setPos(movedContraption.position() + .add(0, diff, 0)); + } + + @Override + public void lazyTick() { + super.lazyTick(); + if (level.isClientSide() || !arrived) + return; + if (movedContraption == null || !movedContraption.isAlive()) + return; + if (!(movedContraption.getContraption()instanceof ElevatorContraption ec)) + return; + if (getTargetOffset() != (int) offset) + return; + + double y = movedContraption.getY(); + int targetLevel = Mth.floor(0.5f + y); + triggerContact(ec, targetLevel); + } + + private void triggerContact(ElevatorContraption ec, int targetLevel) { + ColumnCoords coords = ec.getGlobalColumn(); + ElevatorColumn column = ElevatorColumn.get(level, coords); + if (column == null) + return; + + BlockPos contactPos = column.contactAt(targetLevel + ec.contactYOffset); + if (!level.isLoaded(contactPos)) + return; + BlockState contactState = level.getBlockState(contactPos); + if (!AllBlocks.ELEVATOR_CONTACT.has(contactState)) + return; + if (contactState.getValue(ElevatorContactBlock.POWERING)) + return; + + ElevatorContactBlock ecb = AllBlocks.ELEVATOR_CONTACT.get(); + ecb.withTileEntityDo(level, contactPos, te -> te.activateBlock = true); + ecb.scheduleActivation(level, contactPos); + } + + @Override + public void write(CompoundTag compound, boolean clientPacket) { + super.write(compound, clientPacket); + if (clientPacket) + compound.putInt("ClientTarget", clientOffsetTarget); + } + + @Override + protected void read(CompoundTag compound, boolean clientPacket) { + super.read(compound, clientPacket); + if (!clientPacket) + return; + + clientOffsetTarget = compound.getInt("ClientTarget"); + if (initialOffsetReceived) + return; + + offset = compound.getFloat("Offset"); + initialOffsetReceived = true; + resetContraptionToOffset(); + } + + @Override + public float getMovementSpeed() { + int currentTarget = getTargetOffset(); + + if (!level.isClientSide() && currentTarget != clientOffsetTarget) { + clientOffsetTarget = currentTarget; + sendData(); + } + + float diff = currentTarget - offset; + float movementSpeed = Mth.clamp(convertToLinear(getSpeed() * 2), -1.99f, 1.99f); + float rpmLimit = Math.abs(movementSpeed); + + float configacc = Mth.lerp(Math.abs(movementSpeed), 0.0075f, 0.0175f); + float decelleration = (float) Math.sqrt(2 * Math.abs(diff) * configacc); + + float speed = diff; + speed = Mth.clamp(speed, -rpmLimit, rpmLimit); + speed = Mth.clamp(speed, prevSpeed - configacc, prevSpeed + configacc); + speed = Mth.clamp(speed, -decelleration, decelleration); + + arrived = Math.abs(diff) < 0.5f; + + if (speed > 1 / 1024f && !level.isClientSide()) + setChanged(); + + return prevSpeed = speed; + } + + @Override + protected boolean shouldCreateRopes() { + return false; + } + + @Override + public void disassemble() { + if (movedContraption != null && movedContraption.getContraption()instanceof ElevatorContraption ec) { + ElevatorColumn column = ElevatorColumn.get(level, ec.getGlobalColumn()); + if (column != null) + column.setActive(false); + } + + super.disassemble(); + offset = -1; + sendData(); + } + + public void clicked() { + if (isPassive() && level.getBlockEntity(mirrorParent)instanceof ElevatorPulleyTileEntity parent) { + parent.clicked(); + return; + } + + if (running) + disassemble(); + else + assembleNextTick = true; + } + + @Override + protected boolean moveAndCollideContraption() { + if (arrived) + return false; + super.moveAndCollideContraption(); + return false; + } + + @Override + public void addBehaviours(List behaviours) { + registerAwardables(behaviours, AllAdvancements.CONTRAPTION_ACTORS); + } + + @Override + protected void assemble() throws AssemblyException { + if (!(level.getBlockState(worldPosition) + .getBlock() instanceof ElevatorPulleyBlock)) + return; + if (getSpeed() == 0) + return; + + int maxLength = AllConfigs.SERVER.kinetics.maxRopeLength.get(); + int i = 1; + while (i <= maxLength) { + BlockPos ropePos = worldPosition.below(i); + BlockState ropeState = level.getBlockState(ropePos); + if (!ropeState.getCollisionShape(level, ropePos) + .isEmpty() + && !ropeState.getMaterial() + .isReplaceable()) { + break; + } + ++i; + } + + offset = i - 1; + forceMove = true; + + // Collect Construct + if (!level.isClientSide && mirrorParent == null) { + needsContraption = false; + BlockPos anchor = worldPosition.below(Mth.floor(offset + 1)); + offset = Mth.floor(offset); + ElevatorContraption contraption = new ElevatorContraption((int) offset); + + float offsetOnSucess = offset; + offset = 0; + + boolean canAssembleStructure = contraption.assemble(level, anchor); + if (!canAssembleStructure && getSpeed() > 0) + return; + + if (!contraption.getBlocks() + .isEmpty()) { + offset = offsetOnSucess; + contraption.removeBlocksFromWorld(level, BlockPos.ZERO); + movedContraption = ControlledContraptionEntity.create(level, this, contraption); + movedContraption.setPos(anchor.getX(), anchor.getY(), anchor.getZ()); + level.addFreshEntity(movedContraption); + forceMove = true; + needsContraption = true; + + if (contraption.containsBlockBreakers()) + award(AllAdvancements.CONTRAPTION_ACTORS); + + for (BlockPos pos : contraption.createColliders(level, Direction.UP)) { + if (pos.getY() != 0) + continue; + pos = pos.offset(anchor); + if (level.getBlockEntity(new BlockPos(pos.getX(), worldPosition.getY(), + pos.getZ()))instanceof ElevatorPulleyTileEntity pte) + pte.startMirroringOther(worldPosition); + } + + ElevatorColumn column = ElevatorColumn.getOrCreate(level, contraption.getGlobalColumn()); + int target = (int) (worldPosition.getY() + contraption.contactYOffset - 1 - offset); + column.target(target); + column.gatherAll(); + column.setActive(true); + column.markDirty(); + + contraption.broadcastFloorData(level, column.contactAt(target)); + clientOffsetTarget = column.getTargetedYLevel(); + arrived = true; + } + } + + clientOffsetDiff = 0; + running = true; + sendData(); + } + + @Override + public void onSpeedChanged(float previousSpeed) { + setChanged(); + } + + @Override + protected MovementMode getMovementMode() { + return MovementMode.MOVE_NEVER_PLACE; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java new file mode 100644 index 0000000000..5a9e15b457 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java @@ -0,0 +1,73 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.elevator; + +import java.util.function.Supplier; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.network.NetworkEvent.Context; + +public class ElevatorTargetFloorPacket extends SimplePacketBase { + + private int entityId; + private int targetY; + + public ElevatorTargetFloorPacket(AbstractContraptionEntity entity, int targetY) { + this.targetY = targetY; + this.entityId = entity.getId(); + } + + public ElevatorTargetFloorPacket(FriendlyByteBuf buffer) { + entityId = buffer.readInt(); + targetY = buffer.readInt(); + } + + @Override + public void write(FriendlyByteBuf buffer) { + buffer.writeInt(entityId); + buffer.writeInt(targetY); + } + + @Override + public void handle(Supplier context) { + Context ctx = context.get(); + ctx.enqueueWork(() -> { + ServerPlayer sender = ctx.getSender(); + Entity entityByID = sender.getLevel() + .getEntity(entityId); + if (!(entityByID instanceof AbstractContraptionEntity ace)) + return; + if (!(ace.getContraption()instanceof ElevatorContraption ec)) + return; + if (ace.distanceToSqr(sender) > 50 * 50) + return; + + Level level = sender.level; + ElevatorColumn elevatorColumn = ElevatorColumn.get(level, ec.getGlobalColumn()); + if (!elevatorColumn.contacts.contains(targetY)) + return; + + for (BlockPos otherPos : elevatorColumn.getContacts()) { + BlockState otherState = level.getBlockState(otherPos); + if (!AllBlocks.ELEVATOR_CONTACT.has(otherState)) + continue; + level.setBlock(otherPos, otherState.setValue(ElevatorContactBlock.CALLING, otherPos.getY() == targetY), + 2); + AllBlocks.ELEVATOR_CONTACT.get() + .scheduleActivation(level, otherPos); + } + + elevatorColumn.target(targetY); + elevatorColumn.markDirty(); + }); + ctx.setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java index 39e54a86ea..5379103c22 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java @@ -61,14 +61,17 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity public void tick() { super.tick(); - if (movedContraption != null) { + if (movedContraption != null) if (!movedContraption.isAlive()) movedContraption = null; - } + if (isPassive()) + return; + if (level.isClientSide) clientOffsetDiff *= .75f; + waitingForSpeedChange = false;//TODO if (waitingForSpeedChange) { if (movedContraption != null) { if (level.isClientSide) { @@ -144,6 +147,10 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity } } + protected boolean isPassive() { + return false; + } + @Override public void lazyTick() { super.lazyTick(); @@ -164,6 +171,10 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity @Override public void onSpeedChanged(float prevSpeed) { super.onSpeedChanged(prevSpeed); + + if (isPassive()) + return; + assembleNextTick = true; waitingForSpeedChange = false; @@ -249,18 +260,22 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity disassemble(); return; } - if (movementMode.get() == MovementMode.MOVE_NEVER_PLACE) { + if (getMovementMode() == MovementMode.MOVE_NEVER_PLACE) { waitingForSpeedChange = true; return; } int initial = getInitialOffset(); - if ((int) (offset + .5f) != initial && movementMode.get() == MovementMode.MOVE_PLACE_RETURNED) { + if ((int) (offset + .5f) != initial && getMovementMode() == MovementMode.MOVE_PLACE_RETURNED) { waitingForSpeedChange = true; return; } disassemble(); } + protected MovementMode getMovementMode() { + return movementMode.get(); + } + protected boolean moveAndCollideContraption() { if (movedContraption == null) return false; @@ -288,6 +303,8 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity protected void resetContraptionToOffset() { if (movedContraption == null) return; + if (!movedContraption.isAlive()) + return; Vec3 vec = toPosition(offset); movedContraption.setPos(vec.x, vec.y, vec.z); if (getSpeed() == 0 || waitingForSpeedChange) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java index dfa6dcd0c9..b40e862a0c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java @@ -80,8 +80,8 @@ public abstract class AbstractPulleyRenderer extends KineticTileEntityRenderer { renderAt(world, rope, offset - i - 1, pos, ms, vb); } - private void renderAt(LevelAccessor world, SuperByteBuffer partial, float offset, BlockPos pulleyPos, PoseStack ms, - VertexConsumer buffer) { + public static void renderAt(LevelAccessor world, SuperByteBuffer partial, float offset, BlockPos pulleyPos, + PoseStack ms, VertexConsumer buffer) { BlockPos actualPos = pulleyPos.below((int) offset); int light = LevelRenderer.getLightColor(world, world.getBlockState(actualPos), actualPos); partial.translate(0, -offset, 0) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java index ee53dfc949..76fc5474bf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java @@ -14,7 +14,7 @@ import net.minecraftforge.api.distmarker.OnlyIn; public class PulleyContraption extends TranslatingContraption { int initialOffset; - + @Override protected ContraptionType getType() { return ContraptionType.PULLEY; @@ -62,4 +62,8 @@ public class PulleyContraption extends TranslatingContraption { public ContraptionLighter makeLighter() { return new PulleyLighter(this); } + + public int getInitialOffset() { + return initialOffset; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java index ce547d0790..547fa97316 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java @@ -47,18 +47,22 @@ public class PulleyRenderer extends AbstractPulleyRenderer { @Override protected boolean isRunning(KineticTileEntity te) { - return ((PulleyTileEntity) te).running || te.isVirtual(); + return isPulleyRunning(te); + } + + public static boolean isPulleyRunning(KineticTileEntity te) { + PulleyTileEntity pte = (PulleyTileEntity) te; + return pte.running || pte.mirrorParent != null || te.isVirtual(); } - - static float getTileOffset(float partialTicks, PulleyTileEntity tile) { + public static float getTileOffset(float partialTicks, PulleyTileEntity tile) { float offset = tile.getInterpolatedOffset(partialTicks); - if (tile.movedContraption != null) { - AbstractContraptionEntity e = tile.movedContraption; - PulleyContraption c = (PulleyContraption) tile.movedContraption.getContraption(); - double entityPos = Mth.lerp(partialTicks, e.yOld, e.getY()); - offset = (float) -(entityPos - c.anchor.getY() - c.initialOffset); + AbstractContraptionEntity attachedContraption = tile.getAttachedContraption(); + if (attachedContraption != null) { + PulleyContraption c = (PulleyContraption) attachedContraption.getContraption(); + double entityPos = Mth.lerp(partialTicks, attachedContraption.yOld, attachedContraption.getY()); + offset = (float) -(entityPos - c.anchor.getY() - c.getInitialOffset()); } return offset; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index a71661c893..91209ba8c0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -1,8 +1,13 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pulley; +import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.List; +import javax.annotation.Nullable; + import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementChecks; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; @@ -14,13 +19,14 @@ import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.NBTHelper; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; import net.minecraft.util.Mth; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; @@ -34,13 +40,23 @@ public class PulleyTileEntity extends LinearActuatorTileEntity implements Stockp protected int initialOffset; private float prevAnimatedOffset; + protected BlockPos mirrorParent; + protected List mirrorChildren; + public WeakReference sharedMirrorContraption; + public PulleyTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } @Override protected AABB createRenderBoundingBox() { - return super.createRenderBoundingBox().expandTowards(0, -offset, 0); + double expandY = -offset; + if (sharedMirrorContraption != null) { + AbstractContraptionEntity ace = sharedMirrorContraption.get(); + if (ace != null) + expandY = ace.getY() - worldPosition.getY(); + } + return super.createRenderBoundingBox().expandTowards(0, expandY, 0); } @Override @@ -48,25 +64,46 @@ public class PulleyTileEntity extends LinearActuatorTileEntity implements Stockp super.addBehaviours(behaviours); registerAwardables(behaviours, AllAdvancements.PULLEY_MAXED); } - + @Override public void tick() { float prevOffset = offset; super.tick(); + + if (level.isClientSide() && mirrorParent != null) + if (sharedMirrorContraption == null || sharedMirrorContraption.get() == null + || !sharedMirrorContraption.get() + .isAlive()) { + sharedMirrorContraption = null; + if (level.getBlockEntity(mirrorParent)instanceof PulleyTileEntity pte && pte.movedContraption != null) + sharedMirrorContraption = new WeakReference<>(pte.movedContraption); + } + if (isVirtual()) prevAnimatedOffset = offset; invalidateRenderBoundingBox(); - + if (prevOffset < 200 && offset >= 200) award(AllAdvancements.PULLEY_MAXED); } + @Override + protected boolean isPassive() { + return mirrorParent != null; + } + + @Nullable + public AbstractContraptionEntity getAttachedContraption() { + return mirrorParent != null && sharedMirrorContraption != null ? sharedMirrorContraption.get() + : movedContraption; + } + @Override protected void assemble() throws AssemblyException { if (!(level.getBlockState(worldPosition) .getBlock() instanceof PulleyBlock)) return; - if (speed == 0) + if (speed == 0 && mirrorParent == null) return; int maxLength = AllConfigs.SERVER.kinetics.maxRopeLength.get(); int i = 1; @@ -85,7 +122,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity implements Stockp return; // Collect Construct - if (!level.isClientSide) { + if (!level.isClientSide && mirrorParent == null) { needsContraption = false; BlockPos anchor = worldPosition.below(Mth.floor(offset + 1)); initialOffset = Mth.floor(offset); @@ -102,17 +139,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity implements Stockp if (!canAssembleStructure && getSpeed() > 0) return; - for (i = ((int) offset); i > 0; i--) { - BlockPos offset = worldPosition.below(i); - BlockState oldState = level.getBlockState(offset); - if (oldState.getBlock() instanceof SimpleWaterloggedBlock - && oldState.hasProperty(BlockStateProperties.WATERLOGGED) - && oldState.getValue(BlockStateProperties.WATERLOGGED)) { - level.setBlock(offset, Blocks.WATER.defaultBlockState(), 66); - continue; - } - level.setBlock(offset, Blocks.AIR.defaultBlockState(), 66); - } + removeRopes(); if (!contraption.getBlocks() .isEmpty()) { @@ -122,27 +149,48 @@ public class PulleyTileEntity extends LinearActuatorTileEntity implements Stockp level.addFreshEntity(movedContraption); forceMove = true; needsContraption = true; - + if (contraption.containsBlockBreakers()) award(AllAdvancements.CONTRAPTION_ACTORS); + + for (BlockPos pos : contraption.createColliders(level, Direction.UP)) { + if (pos.getY() != 0) + continue; + pos = pos.offset(anchor); + if (level.getBlockEntity( + new BlockPos(pos.getX(), worldPosition.getY(), pos.getZ()))instanceof PulleyTileEntity pte) + pte.startMirroringOther(worldPosition); + } } } + + if (mirrorParent != null) + removeRopes(); clientOffsetDiff = 0; running = true; sendData(); } + private void removeRopes() { + for (int i = ((int) offset); i > 0; i--) { + BlockPos offset = worldPosition.below(i); + BlockState oldState = level.getBlockState(offset); + level.setBlock(offset, oldState.getFluidState() + .createLegacyBlock(), 66); + } + } + @Override public void disassemble() { - if (!running && movedContraption == null) + if (!running && movedContraption == null && mirrorParent == null) return; offset = getGridOffset(offset); if (movedContraption != null) resetContraptionToOffset(); if (!level.isClientSide) { - if (!remove) { + if (shouldCreateRopes()) { if (offset > 0) { BlockPos magnetPos = worldPosition.below((int) offset); FluidState ifluidstate = level.getFluidState(magnetPos); @@ -170,24 +218,30 @@ public class PulleyTileEntity extends LinearActuatorTileEntity implements Stockp .setValue(BlockStateProperties.WATERLOGGED, waterlog[i]), 66); } - if (movedContraption != null) + if (movedContraption != null && mirrorParent == null) movedContraption.disassemble(); + notifyMirrorsOfDisassembly(); } if (movedContraption != null) movedContraption.discard(); + movedContraption = null; initialOffset = 0; running = false; sendData(); } + protected boolean shouldCreateRopes() { + return !remove; + } + @Override protected Vec3 toPosition(float offset) { if (movedContraption.getContraption() instanceof PulleyContraption) { PulleyContraption contraption = (PulleyContraption) movedContraption.getContraption(); return Vec3.atLowerCornerOf(contraption.anchor) - .add(0, contraption.initialOffset - offset, 0); + .add(0, contraption.getInitialOffset() - offset, 0); } return Vec3.ZERO; @@ -219,12 +273,70 @@ public class PulleyTileEntity extends LinearActuatorTileEntity implements Stockp initialOffset = compound.getInt("InitialOffset"); needsContraption = compound.getBoolean("NeedsContraption"); super.read(compound, clientPacket); + + BlockPos prevMirrorParent = mirrorParent; + mirrorParent = null; + mirrorChildren = null; + + if (compound.contains("MirrorParent")) { + mirrorParent = NbtUtils.readBlockPos(compound.getCompound("MirrorParent")); + offset = 0; + if (prevMirrorParent == null || !prevMirrorParent.equals(mirrorParent)) + sharedMirrorContraption = null; + } + + if (compound.contains("MirrorChildren")) + mirrorChildren = NBTHelper.readCompoundList(compound.getList("MirrorChildren", Tag.TAG_COMPOUND), + NbtUtils::readBlockPos); + + if (mirrorParent == null) + sharedMirrorContraption = null; } @Override public void write(CompoundTag compound, boolean clientPacket) { compound.putInt("InitialOffset", initialOffset); super.write(compound, clientPacket); + + if (mirrorParent != null) + compound.put("MirrorParent", NbtUtils.writeBlockPos(mirrorParent)); + if (mirrorChildren != null) + compound.put("MirrorChildren", NBTHelper.writeCompoundList(mirrorChildren, NbtUtils::writeBlockPos)); + } + + public void startMirroringOther(BlockPos parent) { + if (parent.equals(worldPosition)) + return; + if (!(level.getBlockEntity(parent)instanceof PulleyTileEntity pte)) + return; + if (pte.getType() != getType()) + return; + if (pte.mirrorChildren == null) + pte.mirrorChildren = new ArrayList<>(); + pte.mirrorChildren.add(worldPosition); + pte.notifyUpdate(); + + mirrorParent = parent; + try { + assemble(); + } catch (AssemblyException e) { + } + notifyUpdate(); + } + + public void notifyMirrorsOfDisassembly() { + if (mirrorChildren == null) + return; + for (BlockPos blockPos : mirrorChildren) { + if (!(level.getBlockEntity(blockPos)instanceof PulleyTileEntity pte)) + continue; + pte.offset = offset; + pte.disassemble(); + pte.mirrorParent = null; + pte.notifyUpdate(); + } + mirrorChildren.clear(); + notifyUpdate(); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/RopePulleyInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/RopePulleyInstance.java index 5eac17ee0f..cdb1803937 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/RopePulleyInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/RopePulleyInstance.java @@ -39,6 +39,6 @@ public class RopePulleyInstance extends AbstractPulleyInstance { } protected boolean isRunning() { - return ((PulleyTileEntity) blockEntity).running || blockEntity.isVirtual(); + return PulleyRenderer.isPulleyRunning(blockEntity); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerMovementBehaviour.java index 28de9978c7..f5f6face54 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerMovementBehaviour.java @@ -24,6 +24,7 @@ import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -34,6 +35,11 @@ public class BlazeBurnerMovementBehaviour implements MovementBehaviour { public boolean renderAsNormalTileEntity() { return false; } + + @Override + public ItemStack canBeDisabledVia(MovementContext context) { + return null; + } @Override public void tick(MovementContext context) { diff --git a/src/main/java/com/simibubi/create/content/curiosities/deco/SlidingDoorMovementBehaviour.java b/src/main/java/com/simibubi/create/content/curiosities/deco/SlidingDoorMovementBehaviour.java index 5e42e9b1ae..a76cedb99a 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/deco/SlidingDoorMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/curiosities/deco/SlidingDoorMovementBehaviour.java @@ -5,6 +5,7 @@ import java.util.Map; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContraption; import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.logistics.trains.entity.CarriageSyncData; import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; @@ -24,7 +25,12 @@ public class SlidingDoorMovementBehaviour implements MovementBehaviour { public boolean renderAsNormalTileEntity() { return true; } - + + @Override + public boolean mustTickWhileDisabled() { + return true; + } + @Override public void tick(MovementContext context) { StructureBlockInfo structureBlockInfo = context.contraption.getBlocks() @@ -97,6 +103,10 @@ public class SlidingDoorMovementBehaviour implements MovementBehaviour { } protected boolean shouldOpen(MovementContext context) { + if (context.disabled) + return false; + if (context.contraption instanceof ElevatorContraption ec && ec.arrived) + return true; if (context.contraption.entity instanceof CarriageContraptionEntity cce) { CarriageSyncData carriageData = cce.getCarriageData(); if (Math.abs(carriageData.distanceToDestination) > 1) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/display/source/CurrentFloorDisplaySource.java b/src/main/java/com/simibubi/create/content/logistics/block/display/source/CurrentFloorDisplaySource.java new file mode 100644 index 0000000000..32d4dde28f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/display/source/CurrentFloorDisplaySource.java @@ -0,0 +1,29 @@ +package com.simibubi.create.content.logistics.block.display.source; + +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContactTileEntity; +import com.simibubi.create.content.logistics.block.display.DisplayLinkContext; +import com.simibubi.create.content.logistics.block.display.target.DisplayTargetStats; +import com.simibubi.create.foundation.utility.Components; + +import net.minecraft.network.chat.MutableComponent; + +public class CurrentFloorDisplaySource extends SingleLineDisplaySource { + + @Override + protected MutableComponent provideLine(DisplayLinkContext context, DisplayTargetStats stats) { + if (!(context.getSourceTE() instanceof ElevatorContactTileEntity ecte)) + return EMPTY_LINE; + return Components.literal(ecte.lastReportedCurrentFloor); + } + + @Override + protected String getTranslationKey() { + return "current_floor"; + } + + @Override + protected boolean allowsLabeling(DisplayLinkContext context) { + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContactMovementBehaviour.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContactMovementBehaviour.java index fe75390641..4e5cfa5f69 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContactMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContactMovementBehaviour.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.logistics.block.redstone; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContraption; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -16,7 +17,9 @@ public class ContactMovementBehaviour implements MovementBehaviour { @Override public Vec3 getActiveAreaOffset(MovementContext context) { - return Vec3.atLowerCornerOf(context.state.getValue(RedstoneContactBlock.FACING).getNormal()).scale(.65f); + return Vec3.atLowerCornerOf(context.state.getValue(RedstoneContactBlock.FACING) + .getNormal()) + .scale(.65f); } @Override @@ -31,16 +34,22 @@ public class ContactMovementBehaviour implements MovementBehaviour { deactivateLastVisitedContact(context); BlockState visitedState = world.getBlockState(pos); - if (!AllBlocks.REDSTONE_CONTACT.has(visitedState)) + if (!AllBlocks.REDSTONE_CONTACT.has(visitedState) && !AllBlocks.ELEVATOR_CONTACT.has(visitedState)) return; - Vec3 contact = Vec3.atLowerCornerOf(block.getValue(RedstoneContactBlock.FACING).getNormal()); + Vec3 contact = Vec3.atLowerCornerOf(block.getValue(RedstoneContactBlock.FACING) + .getNormal()); contact = context.rotation.apply(contact); Direction direction = Direction.getNearest(contact.x, contact.y, contact.z); - if (!RedstoneContactBlock.hasValidContact(world, pos.relative(direction.getOpposite()), direction)) + if (visitedState.getValue(RedstoneContactBlock.FACING) != direction.getOpposite()) return; - world.setBlockAndUpdate(pos, visitedState.setValue(RedstoneContactBlock.POWERED, true)); + + if (AllBlocks.REDSTONE_CONTACT.has(visitedState)) + world.setBlockAndUpdate(pos, visitedState.setValue(RedstoneContactBlock.POWERED, true)); + if (AllBlocks.ELEVATOR_CONTACT.has(visitedState) && context.contraption instanceof ElevatorContraption ec) + ec.broadcastFloorData(world, pos); + context.data.put("lastContact", NbtUtils.writeBlockPos(pos)); return; } @@ -49,7 +58,7 @@ public class ContactMovementBehaviour implements MovementBehaviour { public void stopMoving(MovementContext context) { deactivateLastVisitedContact(context); } - + @Override public void cancelStall(MovementContext context) { MovementBehaviour.super.cancelStall(context); @@ -57,11 +66,15 @@ public class ContactMovementBehaviour implements MovementBehaviour { } public void deactivateLastVisitedContact(MovementContext context) { - if (context.data.contains("lastContact")) { - BlockPos last = NbtUtils.readBlockPos(context.data.getCompound("lastContact")); + if (!context.data.contains("lastContact")) + return; + + BlockPos last = NbtUtils.readBlockPos(context.data.getCompound("lastContact")); + context.data.remove("lastContact"); + BlockState blockState = context.world.getBlockState(last); + + if (AllBlocks.REDSTONE_CONTACT.has(blockState)) context.world.scheduleTick(last, AllBlocks.REDSTONE_CONTACT.get(), 1, TickPriority.NORMAL); - context.data.remove("lastContact"); - } } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/NixieTubeRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/NixieTubeRenderer.java index 4428908fad..1798c1cc74 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/NixieTubeRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/NixieTubeRenderer.java @@ -93,25 +93,25 @@ public class NixieTubeRenderer extends SafeTileEntityRenderer LOADED_FLAP_CYCLES = new HashMap<>(); + static Random r = new Random(); public static final float MONOSPACE = 7; public static final float WIDE_MONOSPACE = 9; @@ -83,7 +84,7 @@ public class FlapDisplaySection { spinningTicks = 0; } - public int tick() { + public int tick(boolean instant) { if (cyclingOptions == null) return 0; int max = Math.max(4, (int) (cyclingOptions.length * 1.75f)); @@ -97,13 +98,13 @@ public class FlapDisplaySection { int spinningFlaps = 0; for (int i = 0; i < spinning.length; i++) { int increasingChance = Mth.clamp(8 - spinningTicks, 1, 10); - boolean continueSpin = Create.RANDOM.nextInt(increasingChance * max / 4) != 0; + boolean continueSpin = !instant && r.nextInt(increasingChance * max / 4) != 0; continueSpin &= max > 5 || spinningTicks < 2; spinning[i] &= continueSpin; - if (i > 0 && Create.RANDOM.nextInt(3) > 0) + if (i > 0 && r.nextInt(3) > 0) spinning[i - 1] &= continueSpin; - if (i < spinning.length - 1 && Create.RANDOM.nextInt(3) > 0) + if (i < spinning.length - 1 && r.nextInt(3) > 0) spinning[i + 1] &= continueSpin; if (spinningTicks > max) spinning[i] = false; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/display/FlapDisplayTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/display/FlapDisplayTileEntity.java index 3554194959..22f6478e88 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/display/FlapDisplayTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/display/FlapDisplayTileEntity.java @@ -111,9 +111,10 @@ public class FlapDisplayTileEntity extends KineticTileEntity { if ((!level.isClientSide || !isRunning) && !isVirtual()) return; int activeFlaps = 0; + boolean instant = getSpeed() > 128; for (FlapDisplayLayout line : lines) for (FlapDisplaySection section : line.getSections()) - activeFlaps += section.tick(); + activeFlaps += section.tick(instant); if (activeFlaps == 0) return; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/destination/ChangeThrottleInstruction.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/destination/ChangeThrottleInstruction.java index 36d71f3d30..f1941136d6 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/destination/ChangeThrottleInstruction.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/destination/ChangeThrottleInstruction.java @@ -73,7 +73,7 @@ public class ChangeThrottleInstruction extends ScheduleInstruction { } private ItemStack icon() { - return AllBlocks.CONTROLS.asStack(); + return AllBlocks.TRAIN_CONTROLS.asStack(); } @Override diff --git a/src/main/java/com/simibubi/create/events/InputEvents.java b/src/main/java/com/simibubi/create/events/InputEvents.java index b40b720cd7..a47ce01b8f 100644 --- a/src/main/java/com/simibubi/create/events/InputEvents.java +++ b/src/main/java/com/simibubi/create/events/InputEvents.java @@ -1,6 +1,7 @@ package com.simibubi.create.events; import com.simibubi.create.CreateClient; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorControlsHandler; import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.TrainHUD; import com.simibubi.create.content.curiosities.toolbox.ToolboxHandlerClient; import com.simibubi.create.content.logistics.item.LinkedControllerClientHandler; @@ -43,7 +44,8 @@ public class InputEvents { // CollisionDebugger.onScroll(delta); boolean cancelled = CreateClient.SCHEMATIC_HANDLER.mouseScrolled(delta) || CreateClient.SCHEMATIC_AND_QUILL_HANDLER.mouseScrolled(delta) || FilteringHandler.onScroll(delta) - || ScrollValueHandler.onScroll(delta) || TrainHUD.onScroll(delta); + || ScrollValueHandler.onScroll(delta) || TrainHUD.onScroll(delta) + || ElevatorControlsHandler.onScroll(delta); event.setCanceled(cancelled); } diff --git a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java index 8664b0a5e7..1b67a386e6 100644 --- a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java +++ b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java @@ -60,7 +60,7 @@ public class AllCommands { .then(CameraDistanceCommand.register()) .then(CameraAngleCommand.register()) .then(FlySpeedCommand.register()) - //.then(KillTPSCommand.register()) + .then(KillTPSCommand.register()) .build(); } diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java index 5401c429cc..1c6451ea92 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java @@ -593,7 +593,7 @@ public class StandardRecipeGen extends CreateRecipeProvider { .viaShapeless(b -> b.requires(I.railwayCasing()) .requires(Items.COMPASS)), - TRAIN_CONTROLS = create(AllBlocks.CONTROLS).unlockedBy(I::railwayCasing) + TRAIN_CONTROLS = create(AllBlocks.TRAIN_CONTROLS).unlockedBy(I::railwayCasing) .viaShaped(b -> b.define('I', I.precisionMechanism()) .define('B', Items.LEVER) .define('C', I.railwayCasing()) diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java index 53f9571e80..bcb832da5e 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java @@ -131,6 +131,8 @@ public enum AllGuiTextures implements ScreenElement { I_NEW_TRAIN("schedule_2", 14, 239, 24, 16), I_DISASSEMBLE_TRAIN("schedule_2", 39, 239, 24, 16), I_ASSEMBLE_TRAIN("schedule_2", 64, 239, 24, 16), + + ELEVATOR_CONTACT("display_link", 20, 172, 233, 82), // JEI JEI_SLOT("jei/widgets", 18, 18), diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 10c6a635f1..1fd3ea6952 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -8,11 +8,15 @@ import java.util.function.Function; import java.util.function.Supplier; import com.simibubi.create.Create; +import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionDisableActorPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionBlockChangedPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRelocationPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; import com.simibubi.create.content.contraptions.components.structureMovement.TrainCollisionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContactEditPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorFloorListPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorTargetFloorPacket; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraptionUpdatePacket; import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueRemovalPacket; @@ -148,6 +152,10 @@ public enum AllPackets { OBSERVER_STRESSOMETER(GaugeObservedPacket.class, GaugeObservedPacket::new, PLAY_TO_SERVER), EJECTOR_AWARD(EjectorAwardPacket.class, EjectorAwardPacket::new, PLAY_TO_SERVER), TRACK_GRAPH_REQUEST(TrackGraphRequestPacket.class, TrackGraphRequestPacket::new, PLAY_TO_SERVER), + CONFIGURE_ELEVATOR_CONTACT(ElevatorContactEditPacket.class, ElevatorContactEditPacket::new, PLAY_TO_SERVER), + REQUEST_FLOOR_LIST(ElevatorFloorListPacket.RequestFloorList.class, ElevatorFloorListPacket.RequestFloorList::new, + PLAY_TO_SERVER), + ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket::new, PLAY_TO_SERVER), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), @@ -184,6 +192,8 @@ public enum AllPackets { S_TRAIN_PROMPT(TrainPromptPacket.class, TrainPromptPacket::new, PLAY_TO_CLIENT), CONTRAPTION_RELOCATION(ContraptionRelocationPacket.class, ContraptionRelocationPacket::new, PLAY_TO_CLIENT), TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket::new, PLAY_TO_CLIENT), + UPDATE_ELEVATOR_FLOORS(ElevatorFloorListPacket.class, ElevatorFloorListPacket::new, PLAY_TO_CLIENT), + CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket::new, PLAY_TO_CLIENT), ; 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 ed44673e80..fec11c123a 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 @@ -320,7 +320,7 @@ public class PonderIndex { HELPER.forComponents(AllItems.SCHEDULE) .addStoryBoard("train_schedule", TrainScenes::schedule); - HELPER.forComponents(AllBlocks.CONTROLS) + HELPER.forComponents(AllBlocks.TRAIN_CONTROLS) .addStoryBoard("train_controls", TrainScenes::controls); HELPER.forComponents(AllBlocks.TRACK_OBSERVER) @@ -377,7 +377,7 @@ public class PonderIndex { .add(AllBlocks.TRACK_STATION) .add(AllBlocks.TRACK_SIGNAL) .add(AllBlocks.TRACK_OBSERVER) - .add(AllBlocks.CONTROLS) + .add(AllBlocks.TRAIN_CONTROLS) .add(AllItems.SCHEDULE) .add(AllBlocks.TRAIN_DOOR) .add(AllBlocks.TRAIN_TRAPDOOR) @@ -522,7 +522,7 @@ public class PonderIndex { .add(AllBlocks.ANDESITE_FUNNEL) .add(AllBlocks.BRASS_FUNNEL) .add(AllBlocks.SEATS.get(DyeColor.WHITE)) - .add(AllBlocks.CONTROLS) + .add(AllBlocks.TRAIN_CONTROLS) .add(AllBlocks.REDSTONE_CONTACT) .add(Blocks.BELL) .add(Blocks.DISPENSER) diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java index 75d6367d23..a98450419a 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java @@ -38,10 +38,14 @@ public class ValueBox extends ChasingAABBOutline { protected BlockState blockState; public ValueBox(Component label, AABB bb, BlockPos pos) { + this(label, bb, pos, Minecraft.getInstance().level.getBlockState(pos)); + } + + public ValueBox(Component label, AABB bb, BlockPos pos, BlockState state) { super(bb); this.label = label; this.pos = pos; - this.blockState = Minecraft.getInstance().level.getBlockState(pos); + this.blockState = state; } public ValueBox transform(ValueBoxTransform transform) { @@ -169,6 +173,11 @@ public class ValueBox extends ChasingAABBOutline { super(label, bb, pos); this.text = text; } + + public TextValueBox(Component label, AABB bb, BlockPos pos, BlockState state, Component text) { + super(label, bb, pos, state); + this.text = text; + } @Override public void renderContents(PoseStack ms, MultiBufferSource buffer) { diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java index 58b93c7e8b..7ff2bb4663 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java @@ -1,6 +1,8 @@ package com.simibubi.create.foundation.tileEntity.behaviour; +import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix3f; import com.simibubi.create.content.contraptions.relays.elementary.AbstractSimpleShaftBlock; import com.simibubi.create.content.logistics.item.filter.FilterItem; @@ -8,8 +10,10 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.tags.BlockTags; +import net.minecraft.util.Mth; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -33,6 +37,45 @@ public class ValueBoxRenderer { itemRenderer.renderStatic(filter, TransformType.FIXED, light, overlay, ms, buffer, 0); } + public static void renderFlatItemIntoValueBox(ItemStack filter, PoseStack ms, MultiBufferSource buffer, int light, + int overlay) { + if (filter.isEmpty()) + return; + + int bl = light >> 4 & 0xf; + int sl = light >> 20 & 0xf; + int itemLight = Mth.floor(sl + .5) << 20 | (Mth.floor(bl + .5) & 0xf) << 4; + + ms.pushPose(); + TransformStack.cast(ms) + .rotateX(230); + Matrix3f copy = ms.last() + .normal() + .copy(); + ms.popPose(); + + ms.pushPose(); + TransformStack.cast(ms) + .translate(0, 0, -1 / 4f) + .translate(0, 0, 1 / 32f + .001) + .rotateY(180); + + PoseStack squashedMS = new PoseStack(); + squashedMS.last() + .pose() + .multiply(ms.last() + .pose()); + squashedMS.scale(.5f, .5f, 1 / 1024f); + squashedMS.last() + .normal() + .load(copy); + Minecraft.getInstance() + .getItemRenderer() + .renderStatic(filter, TransformType.GUI, itemLight, OverlayTexture.NO_OVERLAY, squashedMS, buffer, 0); + + ms.popPose(); + } + @SuppressWarnings("deprecation") private static float customZOffset(Item item) { float nudge = -.1f; @@ -44,7 +87,8 @@ public class ValueBoxRenderer { return nudge; if (block instanceof FenceBlock) return nudge; - if (block.builtInRegistryHolder().is(BlockTags.BUTTONS)) + if (block.builtInRegistryHolder() + .is(BlockTags.BUTTONS)) return nudge; if (block == Blocks.END_ROD) return nudge; diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java index d9fe1c1930..ede584da72 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.tileEntity.behaviour.filtering; import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.CreateClient; import com.simibubi.create.content.logistics.item.filter.FilterItem; @@ -131,7 +132,10 @@ public class FilteringRenderer { ms.pushPose(); slotPositioning.transform(blockState, ms); - ValueBoxRenderer.renderItemIntoValueBox(filter, ms, buffer, light, overlay); + if (AllBlocks.CONTRAPTION_CONTROLS.has(blockState)) + ValueBoxRenderer.renderFlatItemIntoValueBox(filter, ms, buffer, light, overlay); + else + ValueBoxRenderer.renderItemIntoValueBox(filter, ms, buffer, light, overlay); ms.popPose(); } sided.fromSide(side); diff --git a/src/main/resources/assets/create/lang/default/interface.json b/src/main/resources/assets/create/lang/default/interface.json index 2c861151e6..8c7a2aab4a 100644 --- a/src/main/resources/assets/create/lang/default/interface.json +++ b/src/main/resources/assets/create/lang/default/interface.json @@ -588,6 +588,10 @@ "create.boiler.via_one_engine": "via 1 engine", "create.boiler.via_engines": "via %1$s engines", + "create.elevator_contact.title": "Elevator Contact", + "create.elevator_contact.floor_identifier": "Floor Identifier", + "create.elevator_contact.floor_description": "Floor Description", + "create.gui.schedule.lmb_edit": "Left-Click to Edit", "create.gui.schedule.rmb_remove": "Right-Click to Remove", "create.gui.schedule.duplicate": "Duplicate", @@ -799,6 +803,11 @@ "create.contraption.controls.stop_controlling": "Stopped controlling contraption", "create.contraption.controls.approach_station": "Hold %1$s to approach %2$s", + "create.contraption.controls.specific_actor_toggle": "%1$s Actors: %2$s", + "create.contraption.controls.all_actor_toggle": "All Actors: %1$s", + "create.contraption.controls.actor_toggle.on": "On", + "create.contraption.controls.actor_toggle.off": "Off", + "create.display_link.set": "Targeted position selected", "create.display_link.success": "Successfully bound to targeted position", "create.display_link.clear": "Cleared position selection", @@ -860,6 +869,7 @@ "create.display_source.max_enchant_level": "Max Enchanting Cost", "create.display_source.boiler_status": "Boiler Status", "create.display_source.entity_name": "Entity Name", + "create.display_source.current_floor": "Elevator Location", "create.display_source.kinetic_speed": "Rotation Speed (RPM)", "create.display_source.kinetic_speed.absolute": "Ignore Direction", "create.display_source.kinetic_speed.directional": "Include Direction", diff --git a/src/main/resources/assets/create/models/block/contraption_controls/block.json b/src/main/resources/assets/create/models/block/contraption_controls/block.json new file mode 100644 index 0000000000..82d694c11b --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/block.json @@ -0,0 +1,104 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_frame", + "1_7": "create:block/contraption_controls", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [14, 0, 6], + "to": [16, 14, 16], + "faces": { + "north": {"uv": [0, 9, 1, 16], "texture": "#4"}, + "east": {"uv": [13, 0, 8, 7], "texture": "#4"}, + "south": {"uv": [7, 0, 8, 7], "texture": "#4"}, + "west": {"uv": [16, 9, 11, 16], "texture": "#4"}, + "up": {"uv": [0, 0, 1, 5], "rotation": 180, "texture": "#1_7"}, + "down": {"uv": [0, 11, 1, 16], "rotation": 180, "texture": "#1_7"} + } + }, + { + "from": [2, 5, 14], + "to": [14, 14, 16], + "faces": { + "north": {"uv": [1, 0, 7, 4.5], "texture": "#1_7"}, + "south": {"uv": [1, 0, 7, 4.5], "texture": "#4"}, + "up": {"uv": [1, 0, 7, 1], "rotation": 180, "texture": "#4"} + } + }, + { + "from": [0, 0, 6], + "to": [2, 14, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [7, 9, 8, 16], "texture": "#4"}, + "east": {"uv": [11, 9, 16, 16], "texture": "#4"}, + "south": {"uv": [0, 0, 1, 7], "texture": "#4"}, + "west": {"uv": [8, 0, 13, 7], "texture": "#4"}, + "up": {"uv": [7, 0, 8, 5], "rotation": 180, "texture": "#1_7"}, + "down": {"uv": [7, 11, 8, 16], "rotation": 180, "texture": "#1_7"} + } + }, + { + "from": [2, 5, 7], + "to": [14, 10, 15], + "faces": { + "north": {"uv": [1, 16, 7, 13.5], "rotation": 180, "texture": "#4"}, + "down": {"uv": [1, 16, 7, 12], "rotation": 180, "texture": "#4"} + } + }, + { + "from": [2, 0, 8], + "to": [14, 5, 16], + "faces": { + "north": {"uv": [1, 4.5, 7, 7], "texture": "#4"}, + "south": {"uv": [1, 4.5, 7, 7], "texture": "#4"}, + "down": {"uv": [7, 12, 1, 16], "texture": "#1_7"} + } + }, + { + "from": [2, 9, 7], + "to": [14, 10, 15], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [1, 9.5, 7, 13.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/button.json b/src/main/resources/assets/create/models/block/contraption_controls/button.json new file mode 100644 index 0000000000..47a0a32baa --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/button.json @@ -0,0 +1,56 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_frame", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [4.95, 8.5, 7.95], + "to": [11.05, 11, 14.05], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "north": {"uv": [5.5, 12.5, 2.5, 13], "rotation": 180, "texture": "#4"}, + "east": {"uv": [2.5, 13, 3, 10], "rotation": 90, "texture": "#4"}, + "south": {"uv": [2.5, 10, 5.5, 10.5], "rotation": 180, "texture": "#4"}, + "west": {"uv": [5, 10, 5.5, 13], "rotation": 90, "texture": "#4"}, + "up": {"uv": [2.5, 10, 5.5, 13], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_0.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_0.json new file mode 100644 index 0000000000..3be842dccb --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_0.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [1, 0.5, 7, 3.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_1.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_1.json new file mode 100644 index 0000000000..5c4e856cb4 --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_1.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [1, 4.5, 7, 7.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_2.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_2.json new file mode 100644 index 0000000000..3da3a805e1 --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_2.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [1, 8.5, 7, 11.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_3.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_3.json new file mode 100644 index 0000000000..c3e33150ee --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_3.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [1, 12.5, 7, 15.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_4.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_4.json new file mode 100644 index 0000000000..8f4a0a2437 --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_4.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [9, 0.5, 15, 3.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_5.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_5.json new file mode 100644 index 0000000000..093fd61d9b --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_5.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [9, 4.5, 15, 7.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_6.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_6.json new file mode 100644 index 0000000000..466ed81e65 --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_6.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [9, 8.5, 15, 11.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/indicator_7.json b/src/main/resources/assets/create/models/block/contraption_controls/indicator_7.json new file mode 100644 index 0000000000..9a7d326870 --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/indicator_7.json @@ -0,0 +1,52 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_indicator", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [9, 12.5, 15, 15.5], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/contraption_controls/item.json b/src/main/resources/assets/create/models/block/contraption_controls/item.json new file mode 100644 index 0000000000..ae87b0f88e --- /dev/null +++ b/src/main/resources/assets/create/models/block/contraption_controls/item.json @@ -0,0 +1,124 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "4": "create:block/contraption_controls_frame", + "1_7": "create:block/contraption_controls", + "particle": "create:block/andesite_casing" + }, + "elements": [ + { + "from": [14, 0, 6], + "to": [16, 14, 16], + "faces": { + "north": {"uv": [0, 9, 1, 16], "texture": "#4"}, + "east": {"uv": [13, 0, 8, 7], "texture": "#4"}, + "south": {"uv": [7, 0, 8, 7], "texture": "#4"}, + "west": {"uv": [16, 9, 11, 16], "texture": "#4"}, + "up": {"uv": [0, 0, 1, 5], "rotation": 180, "texture": "#1_7"}, + "down": {"uv": [0, 11, 1, 16], "rotation": 180, "texture": "#1_7"} + } + }, + { + "from": [2, 5, 14], + "to": [14, 14, 16], + "faces": { + "north": {"uv": [1, 0, 7, 4.5], "texture": "#1_7"}, + "south": {"uv": [1, 0, 7, 4.5], "texture": "#4"}, + "up": {"uv": [1, 0, 7, 1], "rotation": 180, "texture": "#4"} + } + }, + { + "from": [0, 0, 6], + "to": [2, 14, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [7, 9, 8, 16], "texture": "#4"}, + "east": {"uv": [11, 9, 16, 16], "texture": "#4"}, + "south": {"uv": [0, 0, 1, 7], "texture": "#4"}, + "west": {"uv": [8, 0, 13, 7], "texture": "#4"}, + "up": {"uv": [7, 0, 8, 5], "rotation": 180, "texture": "#1_7"}, + "down": {"uv": [7, 11, 8, 16], "rotation": 180, "texture": "#1_7"} + } + }, + { + "from": [2, 5, 7], + "to": [14, 10, 15], + "faces": { + "north": {"uv": [1, 16, 7, 13.5], "rotation": 180, "texture": "#4"}, + "down": {"uv": [1, 16, 7, 12], "rotation": 180, "texture": "#4"} + } + }, + { + "from": [2, 0, 8], + "to": [14, 5, 16], + "faces": { + "north": {"uv": [1, 4.5, 7, 7], "texture": "#4"}, + "south": {"uv": [1, 4.5, 7, 7], "texture": "#4"}, + "down": {"uv": [7, 12, 1, 16], "texture": "#1_7"} + } + }, + { + "from": [4.95, 8.5, 7.95], + "to": [11.05, 11, 14.05], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "north": {"uv": [5.5, 12.5, 2.5, 13], "rotation": 180, "texture": "#4"}, + "east": {"uv": [2.5, 13, 3, 10], "rotation": 90, "texture": "#4"}, + "south": {"uv": [2.5, 10, 5.5, 10.5], "rotation": 180, "texture": "#4"}, + "west": {"uv": [5, 10, 5.5, 13], "rotation": 90, "texture": "#4"}, + "up": {"uv": [2.5, 10, 5.5, 13], "rotation": 180, "texture": "#4"} + } + }, + { + "from": [2, 9, 7], + "to": [14, 10, 15], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [1, 9.5, 7, 13.5], "rotation": 180, "texture": "#4"} + } + }, + { + "from": [2, 9.05, 8], + "to": [14, 10.05, 14], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 7]}, + "faces": { + "up": {"uv": [1, 10, 7, 13], "rotation": 180, "texture": "#4"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [1.5, -0.25, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 8.5, -2.25] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_contact/block.json b/src/main/resources/assets/create/models/block/elevator_contact/block.json new file mode 100644 index 0000000000..6ced587e73 --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_contact/block.json @@ -0,0 +1,82 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/contact_front", + "1": "create:block/elevator_contact_side", + "3": "create:block/rose_quartz_lamp", + "particle": "create:block/elevator_contact_side" + }, + "elements": [ + { + "name": "Center", + "from": [2, 0, 2], + "to": [14, 15, 14], + "faces": { + "up": {"uv": [2, 2, 14, 14], "texture": "#0"}, + "down": {"uv": [2, 2, 14, 14], "texture": "#3"} + } + }, + { + "name": "Side", + "from": [0, 0, 0], + "to": [2, 16, 16], + "faces": { + "north": {"uv": [14, 0, 16, 16], "texture": "#1"}, + "east": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 16], "texture": "#0"}, + "down": {"uv": [0, 0, 2, 16], "texture": "#3"} + } + }, + { + "name": "Side", + "from": [14, 0, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 2, 16], "texture": "#1"}, + "east": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "south": {"uv": [14, 0, 16, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "up": {"uv": [14, 0, 16, 16], "texture": "#0"}, + "down": {"uv": [14, 0, 16, 16], "texture": "#3"} + } + }, + { + "name": "Short Side", + "from": [2, 0, 0], + "to": [14, 16, 2], + "faces": { + "north": {"uv": [2, 0, 14, 16], "texture": "#1"}, + "south": {"uv": [2, 0, 14, 16], "texture": "#1"}, + "up": {"uv": [2, 0, 14, 2], "texture": "#0"}, + "down": {"uv": [2, 14, 14, 16], "texture": "#3"} + } + }, + { + "name": "Short Side", + "from": [2, 0, 14], + "to": [14, 16, 16], + "faces": { + "north": {"uv": [2, 0, 14, 16], "texture": "#1"}, + "south": {"uv": [2, 0, 14, 16], "texture": "#1"}, + "up": {"uv": [2, 14, 14, 16], "texture": "#0"}, + "down": {"uv": [2, 0, 14, 2], "texture": "#3"} + } + }, + { + "name": "Contact", + "from": [6, 15, 6], + "to": [10, 16, 10], + "shade": false, + "faces": { + "north": {"uv": [6, 6, 10, 7], "rotation": 180, "texture": "#0"}, + "east": {"uv": [9, 6, 10, 10], "rotation": 90, "texture": "#0"}, + "south": {"uv": [9, 6, 10, 10], "rotation": 270, "texture": "#0"}, + "west": {"uv": [6, 6, 10, 7], "texture": "#0"}, + "up": {"uv": [6, 6, 10, 10], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_contact/block_dim.json b/src/main/resources/assets/create/models/block/elevator_contact/block_dim.json new file mode 100644 index 0000000000..b19221a98d --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_contact/block_dim.json @@ -0,0 +1,8 @@ +{ + "parent": "create:block/elevator_contact/block", + "textures": { + "1": "create:block/elevator_contact_side_dim", + "3": "create:block/rose_quartz_lamp_dim", + "particle": "create:block/elevator_contact_side_dim" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_contact/block_powered.json b/src/main/resources/assets/create/models/block/elevator_contact/block_powered.json new file mode 100644 index 0000000000..3807fab67a --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_contact/block_powered.json @@ -0,0 +1,8 @@ +{ + "parent": "create:block/elevator_contact/block", + "textures": { + "1": "create:block/elevator_contact_side_powered", + "3": "create:block/rose_quartz_lamp_powered", + "particle": "create:block/elevator_contact_side_powered" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_pulley/block.json b/src/main/resources/assets/create/models/block/elevator_pulley/block.json new file mode 100644 index 0000000000..cc3c334ee8 --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_pulley/block.json @@ -0,0 +1,151 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/elevator_pulley", + "particle": "create:block/brass_gearbox" + }, + "elements": [ + { + "from": [13, 2, 2], + "to": [15, 14, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [1, 1, 1.5, 7], "texture": "#0"}, + "east": {"uv": [9, 1, 15, 7], "texture": "#0"}, + "south": {"uv": [6.5, 1, 7, 7], "texture": "#0"}, + "up": {"uv": [1, 1, 1.5, 7], "texture": "#0"}, + "down": {"uv": [6.5, 1, 7, 7], "texture": "#0"} + } + }, + { + "from": [0, 0, 0], + "to": [2, 16, 2], + "faces": { + "north": {"uv": [7, 0, 8, 8], "texture": "#0"}, + "east": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "south": {"uv": [9, 0, 8, 8], "texture": "#0"}, + "west": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "up": {"uv": [7, 7, 8, 8], "rotation": 180, "texture": "#0"}, + "down": {"uv": [7, 0, 8, 1], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [0, 0, 14], + "to": [2, 16, 16], + "faces": { + "north": {"uv": [16, 0, 15, 8], "texture": "#0"}, + "east": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "west": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "up": {"uv": [7, 0, 8, 1], "rotation": 180, "texture": "#0"}, + "down": {"uv": [7, 7, 8, 8], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [0, 0, 2], + "to": [2, 2, 14], + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "east": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "west": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "up": {"uv": [9, 7, 15, 8], "rotation": 270, "texture": "#0"}, + "down": {"uv": [7, 1, 8, 7], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [0, 14, 2], + "to": [2, 16, 14], + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "east": {"uv": [9, 0, 15.5, 1], "texture": "#0"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "west": {"uv": [9, 0, 15, 1], "texture": "#0"}, + "up": {"uv": [7, 0.5, 8, 7.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [9, 1, 15, 0], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [1, 2, 2], + "to": [3, 14, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [6.5, 1, 7, 7], "texture": "#0"}, + "south": {"uv": [1, 1, 1.5, 7], "texture": "#0"}, + "west": {"uv": [9, 1, 15, 7], "texture": "#0"}, + "up": {"uv": [6.5, 1, 7, 7], "texture": "#0"}, + "down": {"uv": [1, 1, 1.5, 7], "texture": "#0"} + } + }, + { + "from": [14, 0, 14], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 0, 8, 8], "texture": "#0"}, + "east": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "south": {"uv": [7, 0, 8, 8], "texture": "#0"}, + "west": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "up": {"uv": [7, 7, 8, 8], "texture": "#0"}, + "down": {"uv": [7, 0, 8, 1], "texture": "#0"} + } + }, + { + "from": [14, 0, 0], + "to": [16, 16, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "east": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "south": {"uv": [16, 0, 15, 8], "texture": "#0"}, + "west": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "up": {"uv": [7, 0, 8, 1], "texture": "#0"}, + "down": {"uv": [7, 7, 8, 8], "texture": "#0"} + } + }, + { + "from": [14, 0, 2], + "to": [16, 2, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "east": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "west": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "up": {"uv": [9, 7, 15, 8], "rotation": 90, "texture": "#0"}, + "down": {"uv": [7, 1, 8, 7], "texture": "#0"} + } + }, + { + "from": [14, 14, 2], + "to": [16, 16, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "east": {"uv": [9, 0, 15, 1], "texture": "#0"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "west": {"uv": [9, 0, 15.5, 1], "texture": "#0"}, + "up": {"uv": [7, 0.5, 8, 7.5], "texture": "#0"}, + "down": {"uv": [9, 1, 15, 0], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [2, 0, 2.9], + "to": [14, 2, 13.1], + "faces": { + "north": {"uv": [0, 8, 6, 9], "texture": "#0"}, + "south": {"uv": [0, 8, 6, 9], "texture": "#0"}, + "down": {"uv": [0, 9, 6, 14], "rotation": 180, "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "Frame", + "origin": [8, 8, 8], + "color": 0, + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_pulley/item.json b/src/main/resources/assets/create/models/block/elevator_pulley/item.json new file mode 100644 index 0000000000..f5c2abfac4 --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_pulley/item.json @@ -0,0 +1,250 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/elevator_pulley", + "1": "create:block/elevator_pulley_coil", + "1_0": "create:block/axis", + "1_1": "create:block/axis_top", + "particle": "create:block/brass_gearbox" + }, + "elements": [ + { + "from": [2, 2, 13], + "to": [14, 14, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "east": {"uv": [1, 1, 1.5, 7], "texture": "#0"}, + "south": {"uv": [9, 1, 15, 7], "texture": "#0"}, + "west": {"uv": [6.5, 1, 7, 7], "texture": "#0"}, + "up": {"uv": [1, 1, 1.5, 7], "rotation": 90, "texture": "#0"}, + "down": {"uv": [6.5, 1, 7, 7], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [14, 0, 0], + "to": [16, 16, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "east": {"uv": [7, 0, 8, 8], "texture": "#0"}, + "south": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "west": {"uv": [9, 0, 8, 8], "texture": "#0"}, + "up": {"uv": [7, 7, 8, 8], "rotation": 270, "texture": "#0"}, + "down": {"uv": [7, 0, 8, 1], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [0, 0, 0], + "to": [2, 16, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "east": {"uv": [16, 0, 15, 8], "texture": "#0"}, + "south": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "up": {"uv": [7, 0, 8, 1], "rotation": 270, "texture": "#0"}, + "down": {"uv": [7, 7, 8, 8], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [2, 0, 0], + "to": [14, 2, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "south": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "up": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "down": {"uv": [7, 1, 8, 7], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [2, 14, 0], + "to": [14, 16, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [9, 0, 15, 1], "texture": "#0"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "south": {"uv": [9, 0, 15.5, 1], "texture": "#0"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "up": {"uv": [7, 0.5, 8, 7.5], "rotation": 270, "texture": "#0"}, + "down": {"uv": [9, 1, 15, 0], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [2, 2, 1], + "to": [14, 14, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 1, 15, 7], "texture": "#0"}, + "east": {"uv": [6.5, 1, 7, 7], "texture": "#0"}, + "west": {"uv": [1, 1, 1.5, 7], "texture": "#0"}, + "up": {"uv": [6.5, 1, 7, 7], "rotation": 90, "texture": "#0"}, + "down": {"uv": [1, 1, 1.5, 7], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [0, 0, 14], + "to": [2, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "east": {"uv": [9, 0, 8, 8], "texture": "#0"}, + "south": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "west": {"uv": [7, 0, 8, 8], "texture": "#0"}, + "up": {"uv": [7, 7, 8, 8], "rotation": 90, "texture": "#0"}, + "down": {"uv": [7, 0, 8, 1], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [14, 0, 14], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [8, 0, 9, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "south": {"uv": [15, 0, 16, 8], "texture": "#0"}, + "west": {"uv": [16, 0, 15, 8], "texture": "#0"}, + "up": {"uv": [7, 0, 8, 1], "rotation": 90, "texture": "#0"}, + "down": {"uv": [7, 7, 8, 8], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [2, 0, 14], + "to": [14, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "south": {"uv": [9, 7, 15, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "up": {"uv": [9, 7, 15, 8], "rotation": 180, "texture": "#0"}, + "down": {"uv": [7, 1, 8, 7], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [2, 14, 14], + "to": [14, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 0, 15.5, 1], "texture": "#0"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "south": {"uv": [9, 0, 15, 1], "texture": "#0"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "up": {"uv": [7, 0.5, 8, 7.5], "rotation": 90, "texture": "#0"}, + "down": {"uv": [9, 1, 15, 0], "texture": "#0"} + } + }, + { + "from": [2.9, 0, 2], + "to": [13.1, 2, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "east": {"uv": [0, 8, 6, 9], "texture": "#0"}, + "west": {"uv": [0, 8, 6, 9], "texture": "#0"}, + "down": {"uv": [0, 9, 6, 14], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [3, -2, 3], + "to": [13, 3, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "east": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "south": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "west": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "up": {"uv": [6, 8, 11, 13], "rotation": 90, "texture": "#0"}, + "down": {"uv": [6, 8, 11, 13], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [4, 2, 5], + "to": [12, 5, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "north": {"uv": [10, 13, 14, 14.5], "texture": "#0"}, + "east": {"uv": [12, 9, 15, 10.5], "texture": "#0"}, + "south": {"uv": [10, 13, 14, 14.5], "texture": "#0"}, + "west": {"uv": [12, 9, 15, 10.5], "texture": "#0"}, + "up": {"uv": [6, 13, 10, 16], "rotation": 180, "texture": "#0"} + } + }, + { + "name": "Axis", + "from": [6, 6, 0], + "to": [10, 10, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [6, 6, 10, 10], "rotation": 90, "texture": "#1_1"}, + "east": {"uv": [6, 0, 10, 16], "rotation": 270, "texture": "#1_0"}, + "south": {"uv": [6, 6, 10, 10], "rotation": 90, "texture": "#1_1"}, + "west": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#1_0"}, + "up": {"uv": [6, 0, 10, 16], "rotation": 180, "texture": "#1_0"}, + "down": {"uv": [6, 0, 10, 16], "texture": "#1_0"} + } + }, + { + "from": [2, 10, 3], + "to": [14, 14, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "west": {"uv": [3, 12, 13, 16], "texture": "#1"}, + "up": {"uv": [3, 0, 13, 12], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [10, 2, 3], + "to": [14, 14, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "east": {"uv": [3, 4, 13, 16], "rotation": 180, "texture": "#1"}, + "down": {"uv": [3, 0, 13, 4], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [2, 2, 3], + "to": [10, 10, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]}, + "faces": { + "west": {"uv": [3, 0, 13, 8], "texture": "#1"}, + "down": {"uv": [3, 8, 13, 16], "rotation": 270, "texture": "#1"} + } + } + ], + "groups": [ + { + "name": "Frame", + "origin": [8, 8, 8], + "color": 0, + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + }, + { + "name": "Anchor", + "origin": [0, 0, 0], + "color": 0, + "children": [11, 12] + }, + { + "name": "shaft", + "origin": [8, 8, 8], + "color": 0, + "children": [13] + }, + { + "name": "rope_coil", + "origin": [8, 8, 8], + "color": 0, + "children": [ + { + "name": "Spool", + "origin": [8, 8, 8], + "color": 0, + "children": [14, 15, 16] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_pulley/pulley_magnet.json b/src/main/resources/assets/create/models/block/elevator_pulley/pulley_magnet.json new file mode 100644 index 0000000000..7f5134fb56 --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_pulley/pulley_magnet.json @@ -0,0 +1,41 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/elevator_pulley", + "particle": "create:block/brass_gearbox" + }, + "elements": [ + { + "from": [3, -3, 3], + "to": [13, 2, 13], + "faces": { + "north": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "east": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "south": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "west": {"uv": [11, 10.5, 16, 13], "texture": "#0"}, + "up": {"uv": [6, 8, 11, 13], "texture": "#0"}, + "down": {"uv": [6, 8, 11, 13], "texture": "#0"} + } + }, + { + "from": [5, 2, 4], + "to": [11, 5, 12], + "faces": { + "north": {"uv": [12, 9, 15, 10.5], "texture": "#0"}, + "east": {"uv": [10, 13, 14, 14.5], "texture": "#0"}, + "south": {"uv": [12, 9, 15, 10.5], "texture": "#0"}, + "west": {"uv": [10, 13, 14, 14.5], "texture": "#0"}, + "up": {"uv": [6, 13, 10, 16], "rotation": 90, "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "Anchor", + "origin": [0, 0, 0], + "color": 0, + "children": [0, 1] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_pulley/rope.json b/src/main/resources/assets/create/models/block/elevator_pulley/rope.json new file mode 100644 index 0000000000..06e3cc6ab8 --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_pulley/rope.json @@ -0,0 +1,31 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "create:block/elevator_pulley_belt", + "particle": "create:block/brass_gearbox" + }, + "elements": [ + { + "from": [6, 0, 3.5], + "to": [10, 16, 5.5], + "faces": { + "north": {"uv": [3, 0, 7, 16], "texture": "#1"}, + "east": {"uv": [2, 0, 0, 16], "texture": "#1"}, + "south": {"uv": [3, 0, 7, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 16], "texture": "#1"} + } + }, + { + "from": [6, 0, 10.5], + "to": [10, 16, 12.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -5.5, 11.5]}, + "faces": { + "north": {"uv": [13, 16, 9, 0], "texture": "#1"}, + "east": {"uv": [14, 0, 16, 16], "rotation": 180, "texture": "#1"}, + "south": {"uv": [13, 16, 9, 0], "texture": "#1"}, + "west": {"uv": [16, 0, 14, 16], "rotation": 180, "texture": "#1"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_pulley/rope_coil.json b/src/main/resources/assets/create/models/block/elevator_pulley/rope_coil.json new file mode 100644 index 0000000000..b36884c47b --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_pulley/rope_coil.json @@ -0,0 +1,42 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "create:block/elevator_pulley_coil", + "particle": "create:block/brass_gearbox" + }, + "elements": [ + { + "from": [3, 10, 2], + "to": [13, 14, 14], + "faces": { + "south": {"uv": [3, 12, 13, 16], "texture": "#1"}, + "up": {"uv": [3, 0, 13, 12], "texture": "#1"} + } + }, + { + "from": [3, 2, 2], + "to": [13, 14, 6], + "faces": { + "north": {"uv": [3, 4, 13, 16], "rotation": 180, "texture": "#1"}, + "down": {"uv": [3, 0, 13, 4], "texture": "#1"} + } + }, + { + "from": [3, 2, 6], + "to": [13, 10, 14], + "faces": { + "south": {"uv": [3, 0, 13, 8], "texture": "#1"}, + "down": {"uv": [3, 8, 13, 16], "texture": "#1"} + } + } + ], + "groups": [ + { + "name": "Spool", + "origin": [8, 8, 8], + "color": 0, + "children": [0, 1, 2] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/elevator_pulley/rope_half.json b/src/main/resources/assets/create/models/block/elevator_pulley/rope_half.json new file mode 100644 index 0000000000..5ff05ff15a --- /dev/null +++ b/src/main/resources/assets/create/models/block/elevator_pulley/rope_half.json @@ -0,0 +1,39 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "create:block/elevator_pulley_belt", + "particle": "create:block/brass_gearbox" + }, + "elements": [ + { + "from": [6, 0, 3.5], + "to": [10, 8, 5.5], + "faces": { + "north": {"uv": [3, 8, 7, 16], "texture": "#1"}, + "east": {"uv": [2, 8, 0, 16], "texture": "#1"}, + "south": {"uv": [3, 8, 7, 16], "texture": "#1"}, + "west": {"uv": [0, 8, 2, 16], "texture": "#1"} + } + }, + { + "from": [6, 0, 10.5], + "to": [10, 8, 12.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -5.5, 11.5]}, + "faces": { + "north": {"uv": [13, 8, 9, 0], "texture": "#1"}, + "east": {"uv": [14, 0, 16, 8], "rotation": 180, "texture": "#1"}, + "south": {"uv": [13, 8, 9, 0], "texture": "#1"}, + "west": {"uv": [16, 0, 14, 8], "rotation": 180, "texture": "#1"} + } + } + ], + "groups": [ + { + "name": "rope", + "origin": [8, 8, 8], + "color": 0, + "children": [0, 1] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/mechanical_drill/item.json b/src/main/resources/assets/create/models/block/mechanical_drill/item.json index 0deb494475..725b4ed4a6 100644 --- a/src/main/resources/assets/create/models/block/mechanical_drill/item.json +++ b/src/main/resources/assets/create/models/block/mechanical_drill/item.json @@ -209,16 +209,24 @@ } } ], - "display": {}, + "display": { + "fixed": { + "rotation": [0, 180, 0], + "translation": [0, 0, -1.75], + "scale": [0.5, 0.5, 0.5] + } + }, "groups": [ { "name": "head", "origin": [8, 8, 8], + "color": 0, "children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "name": "casing", "origin": [8, 8, 8], + "color": 0, "children": [10, 11, 12, 13, 14] } ] diff --git a/src/main/resources/assets/create/models/block/mechanical_harvester/item.json b/src/main/resources/assets/create/models/block/mechanical_harvester/item.json index 970dc1d272..d81d76a75f 100644 --- a/src/main/resources/assets/create/models/block/mechanical_harvester/item.json +++ b/src/main/resources/assets/create/models/block/mechanical_harvester/item.json @@ -1,161 +1,168 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", + "credit": "Made with Blockbench", "parent": "create:block/block", - "textures": { - "harvester": "create:block/harvester", - "anvil": "minecraft:block/anvil", - "andesite_casing_short": "create:block/andesite_casing_short", - "particle": "create:block/andesite_casing_short" - }, - "elements": [ - { - "name": "Core", - "from": [ 0, 2, 0 ], - "to": [ 16, 14, 2.9 ], - "faces": { - "north": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 2, 0, 14, 3 ], "rotation": 270 }, - "south": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 2, 0, 14, 3 ], "rotation": 90 }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 16, 2.9 ], "rotation": 180 }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 16, 2.9 ] } - } - }, - { - "name": "Wheel", - "from": [ 1, 0, 3 ], - "to": [ 1, 12, 15 ], - "rotation": { "origin": [ 8, 6, 9 ], "axis": "x", "angle": -22.5 }, - "faces": { - "east": { "texture": "#harvester", "uv": [ 0, 0, 12, 12 ] }, - "west": { "texture": "#harvester", "uv": [ 0, 0, 12, 12 ] } - } - }, - { - "name": "Trim", - "from": [ 0, 0, 11 ], - "to": [ 16, 2, 12 ], - "faces": { - "north": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] }, - "east": { "texture": "#anvil", "uv": [ 0, 0, 1, 2 ] }, - "south": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] }, - "west": { "texture": "#anvil", "uv": [ 0, 0, 1, 2 ] }, - "up": { "texture": "#anvil", "uv": [ 0, 0, 16, 1 ] }, - "down": { "texture": "#anvil", "uv": [ 0, 0, 16, 1 ] } - } - }, - { - "name": "Trim", - "from": [ 0, 10, 6 ], - "to": [ 16, 12, 7 ], - "faces": { - "north": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] }, - "east": { "texture": "#anvil", "uv": [ 0, 0, 1, 2 ] }, - "south": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] }, - "west": { "texture": "#anvil", "uv": [ 0, 0, 1, 2 ] }, - "up": { "texture": "#anvil", "uv": [ 0, 0, 16, 1 ] }, - "down": { "texture": "#anvil", "uv": [ 0, 0, 16, 1 ] } - } - }, - { - "name": "Trim", - "from": [ 0, 8, 13 ], - "to": [ 16, 9, 15 ], - "faces": { - "north": { "texture": "#anvil", "uv": [ 0, 9, 16, 10 ] }, - "east": { "texture": "#anvil", "uv": [ 0, 0, 2, 1 ] }, - "south": { "texture": "#anvil", "uv": [ 0, 0, 16, 1 ] }, - "west": { "texture": "#anvil", "uv": [ 0, 0, 2, 1 ] }, - "up": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] }, - "down": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] } - } - }, - { - "name": "Trim", - "from": [ 0, 3, 3 ], - "to": [ 16, 4, 5 ], - "faces": { - "north": { "texture": "#anvil", "uv": [ 0, 0, 16, 1 ] }, - "east": { "texture": "#anvil", "uv": [ 0, 0, 2, 1 ] }, - "south": { "texture": "#anvil", "uv": [ 0, 0, 16, 1 ] }, - "west": { "texture": "#anvil", "uv": [ 0, 0, 2, 1 ] }, - "up": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] }, - "down": { "texture": "#anvil", "uv": [ 0, 0, 16, 2 ] } - } - }, - { - "name": "Blade", - "from": [ 0, 6, 15 ], - "to": [ 16, 8, 15 ], - "faces": { - "north": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ], "rotation": 180 }, - "south": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ], "rotation": 180 } - } - }, - { - "name": "Wheel", - "from": [ 15, 0, 3 ], - "to": [ 15, 12, 15 ], - "rotation": { "origin": [ 8, 6, 9 ], "axis": "x", "angle": -22.5 }, - "faces": { - "east": { "texture": "#harvester", "uv": [ 0, 0, 12, 12 ] }, - "west": { "texture": "#harvester", "uv": [ 0, 0, 12, 12 ] } - } - }, - { - "name": "Blade", - "from": [ 0, 4, 3 ], - "to": [ 16, 6, 3 ], - "faces": { - "north": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ] }, - "south": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ] } - } - }, - { - "name": "Blade", - "from": [ 0, 12, 7 ], - "to": [ 16, 12, 9 ], - "faces": { - "up": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ], "rotation": 180 }, - "down": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ] } - } - }, - { - "name": "Blade", - "from": [ 0, 0, 9 ], - "to": [ 16, 0, 11 ], - "faces": { - "up": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ] }, - "down": { "texture": "#harvester", "uv": [ 0, 12, 16, 14 ], "rotation": 180 } - } - }, - { - "name": "Attachment", - "from": [ 0.1, 7, 3 ], - "to": [ 2, 10, 11 ], - "rotation": { "origin": [ 0, 10, 3 ], "axis": "x", "angle": 22.5 }, - "faces": { - "north": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 1.9, 3 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 8, 3 ] }, - "south": { "texture": "#andesite_casing_short", "uv": [ 0.1, 8, 2, 11 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 8, 3 ] }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0.1, 6, 2, 14 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0.1, 6, 2, 14 ] } - } - }, - { - "name": "Attachment", - "from": [ 14, 7, 3 ], - "to": [ 15.9, 10, 11 ], - "rotation": { "origin": [ 0, 10, 3 ], "axis": "x", "angle": 22.5 }, - "faces": { - "north": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 1.9, 3 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 8, 3 ] }, - "south": { "texture": "#andesite_casing_short", "uv": [ 14, 8, 15.9, 11 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 0, 0, 8, 3 ] }, - "up": { "texture": "#andesite_casing_short", "uv": [ 14, 6, 15.9, 14 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 14, 6, 15.9, 14 ] } - } - } - ] + "textures": { + "harvester": "create:block/harvester", + "anvil": "block/anvil", + "particle": "create:block/andesite_casing_short", + "andesite_casing_short": "create:block/andesite_casing_short" + }, + "elements": [ + { + "name": "Core", + "from": [0, 2, 0], + "to": [16, 14, 2.9], + "faces": { + "north": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "east": {"uv": [2, 0, 14, 3], "rotation": 270, "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "west": {"uv": [2, 0, 14, 3], "rotation": 90, "texture": "#andesite_casing_short"}, + "up": {"uv": [0, 0, 16, 2.9], "rotation": 180, "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 0, 16, 2.9], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Wheel", + "from": [1, 0, 3], + "to": [1, 12, 15], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 6, 9]}, + "faces": { + "east": {"uv": [0, 0, 12, 12], "texture": "#harvester"}, + "west": {"uv": [0, 0, 12, 12], "texture": "#harvester"} + } + }, + { + "name": "Trim", + "from": [0, 0, 11], + "to": [16, 2, 12], + "faces": { + "north": {"uv": [0, 0, 16, 2], "texture": "#anvil"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#anvil"}, + "south": {"uv": [0, 0, 16, 2], "texture": "#anvil"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#anvil"}, + "up": {"uv": [0, 0, 16, 1], "texture": "#anvil"}, + "down": {"uv": [0, 0, 16, 1], "texture": "#anvil"} + } + }, + { + "name": "Trim", + "from": [0, 10, 6], + "to": [16, 12, 7], + "faces": { + "north": {"uv": [0, 0, 16, 2], "texture": "#anvil"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#anvil"}, + "south": {"uv": [0, 0, 16, 2], "texture": "#anvil"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#anvil"}, + "up": {"uv": [0, 0, 16, 1], "texture": "#anvil"}, + "down": {"uv": [0, 0, 16, 1], "texture": "#anvil"} + } + }, + { + "name": "Trim", + "from": [0, 8, 13], + "to": [16, 9, 15], + "faces": { + "north": {"uv": [0, 9, 16, 10], "texture": "#anvil"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#anvil"}, + "south": {"uv": [0, 0, 16, 1], "texture": "#anvil"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#anvil"}, + "up": {"uv": [0, 0, 16, 2], "texture": "#anvil"}, + "down": {"uv": [0, 0, 16, 2], "texture": "#anvil"} + } + }, + { + "name": "Trim", + "from": [0, 3, 3], + "to": [16, 4, 5], + "faces": { + "north": {"uv": [0, 0, 16, 1], "texture": "#anvil"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#anvil"}, + "south": {"uv": [0, 0, 16, 1], "texture": "#anvil"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#anvil"}, + "up": {"uv": [0, 0, 16, 2], "texture": "#anvil"}, + "down": {"uv": [0, 0, 16, 2], "texture": "#anvil"} + } + }, + { + "name": "Blade", + "from": [0, 6, 15], + "to": [16, 8, 15], + "faces": { + "north": {"uv": [0, 12, 16, 14], "rotation": 180, "texture": "#harvester"}, + "south": {"uv": [0, 12, 16, 14], "rotation": 180, "texture": "#harvester"} + } + }, + { + "name": "Wheel", + "from": [15, 0, 3], + "to": [15, 12, 15], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 6, 9]}, + "faces": { + "east": {"uv": [0, 0, 12, 12], "texture": "#harvester"}, + "west": {"uv": [0, 0, 12, 12], "texture": "#harvester"} + } + }, + { + "name": "Blade", + "from": [0, 4, 3], + "to": [16, 6, 3], + "faces": { + "north": {"uv": [0, 12, 16, 14], "texture": "#harvester"}, + "south": {"uv": [0, 12, 16, 14], "texture": "#harvester"} + } + }, + { + "name": "Blade", + "from": [0, 12, 7], + "to": [16, 12, 9], + "faces": { + "up": {"uv": [0, 12, 16, 14], "rotation": 180, "texture": "#harvester"}, + "down": {"uv": [0, 12, 16, 14], "texture": "#harvester"} + } + }, + { + "name": "Blade", + "from": [0, 0, 9], + "to": [16, 0, 11], + "faces": { + "up": {"uv": [0, 12, 16, 14], "texture": "#harvester"}, + "down": {"uv": [0, 12, 16, 14], "rotation": 180, "texture": "#harvester"} + } + }, + { + "name": "Attachment", + "from": [0.1, 7, 3], + "to": [2, 10, 11], + "rotation": {"angle": 22.5, "axis": "x", "origin": [0, 10, 3]}, + "faces": { + "north": {"uv": [0, 0, 1.9, 3], "texture": "#andesite_casing_short"}, + "east": {"uv": [0, 0, 8, 3], "texture": "#andesite_casing_short"}, + "south": {"uv": [0.1, 8, 2, 11], "texture": "#andesite_casing_short"}, + "west": {"uv": [0, 0, 8, 3], "texture": "#andesite_casing_short"}, + "up": {"uv": [0.1, 6, 2, 14], "texture": "#andesite_casing_short"}, + "down": {"uv": [0.1, 6, 2, 14], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Attachment", + "from": [14, 7, 3], + "to": [15.9, 10, 11], + "rotation": {"angle": 22.5, "axis": "x", "origin": [0, 10, 3]}, + "faces": { + "north": {"uv": [0, 0, 1.9, 3], "texture": "#andesite_casing_short"}, + "east": {"uv": [0, 0, 8, 3], "texture": "#andesite_casing_short"}, + "south": {"uv": [14, 8, 15.9, 11], "texture": "#andesite_casing_short"}, + "west": {"uv": [0, 0, 8, 3], "texture": "#andesite_casing_short"}, + "up": {"uv": [14, 6, 15.9, 14], "texture": "#andesite_casing_short"}, + "down": {"uv": [14, 6, 15.9, 14], "texture": "#andesite_casing_short"} + } + } + ], + "display": { + "fixed": { + "rotation": [0, 180, 0], + "translation": [0, 0.5, -4], + "scale": [0.5, 0.5, 0.5] + } + } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/mechanical_plough.json b/src/main/resources/assets/create/models/block/mechanical_plough.json index bdbde566ae..ad0dd1fb03 100644 --- a/src/main/resources/assets/create/models/block/mechanical_plough.json +++ b/src/main/resources/assets/create/models/block/mechanical_plough.json @@ -78,10 +78,9 @@ } ], "display": { - "gui": { - "rotation": [30, -135, 0], - "translation": [1, 0, 0], - "scale": [0.625, 0.625, 0.625] + "fixed": { + "translation": [0, 0.5, -4], + "scale": [0.5, 0.5, 0.5] } } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/mechanical_saw/item.json b/src/main/resources/assets/create/models/block/mechanical_saw/item.json index a74e1a24c8..b81666f37b 100644 --- a/src/main/resources/assets/create/models/block/mechanical_saw/item.json +++ b/src/main/resources/assets/create/models/block/mechanical_saw/item.json @@ -1,98 +1,105 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", - "textures": { - "particle": "create:block/gearbox_top", - "slit": "create:block/mechanical_saw_top", - "stonecutter_saw": "block/stonecutter_saw", - "gearbox_top": "create:block/gearbox_top", - "encased_belt": "create:block/encased_chain_drive", - "gearbox": "create:block/gearbox", - "andesite_casing_short": "create:block/andesite_casing_short" - }, + "credit": "Made with Blockbench", "parent": "create:block/block", - "elements": [ - { - "name": "Bottom", - "from": [ 0, 0, 0 ], - "to": [ 16, 2, 12 ], - "faces": { - "north": { "texture": "#andesite_casing_short", "uv": [ 0, 14, 16, 16 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 4, 14, 16, 16 ] }, - "south": { "texture": "#encased_belt", "uv": [ 0, 14, 16, 16 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 0, 14, 12, 16 ] }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] } - } - }, - { - "name": "Top", - "from": [ 0, 14, 0 ], - "to": [ 16, 16, 12 ], - "faces": { - "north": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 6 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 4, 4, 16, 6 ] }, - "south": { "texture": "#encased_belt", "uv": [ 0, 0, 16, 2 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 12, 6 ] }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] } - } - }, - { - "name": "Back", - "from": [ 0, 2, 0 ], - "to": [ 2, 14, 2 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] }, - "east": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] }, - "west": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] } - } - }, - { - "name": "Inner", - "from": [ 0, 2, 2 ], - "to": [ 16, 14, 11 ], - "faces": { - "east": { "texture": "#andesite_casing_short", "uv": [ 2, 6, 14, 15 ], "rotation": 90 }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 2, 16, 14 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 2, 6, 14, 15 ], "rotation": 270 } - } - }, - { - "name": "SawSlit", - "from": [ 1, 7, 11.062 ], - "to": [ 15, 9, 11.062 ], - "faces": { - "south": { "texture": "#slit", "uv": [ 1, 7, 15, 9 ] } - } - }, - { - "name": "Blade", - "from": [ 1, 8, 11 ], - "to": [ 15, 8.062, 18 ], - "faces": { - "up": { "texture": "#stonecutter_saw", "uv": [ 1, 9, 15, 16 ], "rotation": 180 }, - "down": { "texture": "#stonecutter_saw", "uv": [ 1, 9, 15, 16 ] } - } - }, - { - "name": "Back", - "from": [ 14, 2, 0 ], - "to": [ 16, 14, 2 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] }, - "east": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] }, - "west": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] } - } - }, - { - "name": "Back", - "from": [ 2, 2, 1 ], - "to": [ 14, 14, 2 ], - "faces": { - "north": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] } - } - } - ] + "textures": { + "slit": "create:block/mechanical_saw_top", + "stonecutter_saw": "block/stonecutter_saw", + "particle": "create:block/gearbox_top", + "gearbox_top": "create:block/gearbox_top", + "encased_belt": "create:block/encased_chain_drive", + "gearbox": "create:block/gearbox", + "andesite_casing_short": "create:block/andesite_casing_short" + }, + "elements": [ + { + "name": "Bottom", + "from": [0, 0, 0], + "to": [16, 2, 12], + "faces": { + "north": {"uv": [0, 14, 16, 16], "texture": "#andesite_casing_short"}, + "east": {"uv": [4, 14, 16, 16], "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 14, 16, 16], "texture": "#encased_belt"}, + "west": {"uv": [0, 14, 12, 16], "texture": "#andesite_casing_short"}, + "up": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Top", + "from": [0, 14, 0], + "to": [16, 16, 12], + "faces": { + "north": {"uv": [0, 4, 16, 6], "texture": "#andesite_casing_short"}, + "east": {"uv": [4, 4, 16, 6], "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 0, 16, 2], "texture": "#encased_belt"}, + "west": {"uv": [0, 4, 12, 6], "texture": "#andesite_casing_short"}, + "up": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Back", + "from": [0, 2, 0], + "to": [2, 14, 2], + "faces": { + "north": {"uv": [14, 2, 16, 14], "texture": "#gearbox_top"}, + "east": {"uv": [14, 2, 16, 14], "texture": "#gearbox_top"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"}, + "west": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"} + } + }, + { + "name": "Inner", + "from": [0, 2, 2], + "to": [16, 14, 11], + "faces": { + "east": {"uv": [2, 6, 14, 15], "rotation": 90, "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 2, 16, 14], "texture": "#gearbox_top"}, + "west": {"uv": [2, 6, 14, 15], "rotation": 270, "texture": "#andesite_casing_short"} + } + }, + { + "name": "SawSlit", + "from": [1, 7, 11.062], + "to": [15, 9, 11.062], + "faces": { + "south": {"uv": [1, 7, 15, 9], "texture": "#slit"} + } + }, + { + "name": "Blade", + "from": [1, 8, 11], + "to": [15, 8.062, 18], + "faces": { + "up": {"uv": [1, 9, 15, 16], "rotation": 180, "texture": "#stonecutter_saw"}, + "down": {"uv": [1, 9, 15, 16], "texture": "#stonecutter_saw"} + } + }, + { + "name": "Back", + "from": [14, 2, 0], + "to": [16, 14, 2], + "faces": { + "north": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"}, + "east": {"uv": [14, 2, 16, 14], "texture": "#gearbox_top"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"}, + "west": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"} + } + }, + { + "name": "Back", + "from": [2, 2, 1], + "to": [14, 14, 2], + "faces": { + "north": {"uv": [2, 2, 14, 14], "texture": "#gearbox"} + } + } + ], + "display": { + "fixed": { + "rotation": [0, 180, 0], + "translation": [0, 0, -1.5], + "scale": [0.5, 0.5, 0.5] + } + } } \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/contraption_controls.png b/src/main/resources/assets/create/textures/block/contraption_controls.png new file mode 100644 index 0000000000000000000000000000000000000000..49dd879026c95007d00913002685f1b7338b0fdf GIT binary patch literal 7358 zcmeHLd0dR^+n@Gbij!Od6t$zQVUu>Oj72quORi*n~!_ns_LtPc!LY7@@V6LqCfKO{s%nSI>KCHhtpty}Eg& zYP*q3_uDl!_lE%gQo*8GN*e|tFD#QDhN^lkj{&@oQXI2d<|wEg@@rbIMqh5yZMpEu z0ymR7NOq#}1#g*EvlUN}AlzDZ)FZpV_10}_T5OV%$M01%VW-E$?cr{_O-s6W^I&0X)b*+F^8Jt4ivobmr9!d%wP~hy!*SmNIz2! zif?@aQQNQNr=w^v)|?nauFX)f^yMr*&9-Xwy3+EvaCh#-C(FB5tqpFvkijsm@;bgt zb_L2Ub6(Qvm05{}nN)A_&G=F^^+WF-2oO1&`ios!IWnVjfT2^z)Rf3OZ)4uZxi=Eq z(h8b&;hwAmHAQDGFIo3Fm4vmaSSjnZ2V8~MX}sGeaNBKh;2QV-9pbs>(8ozNGom$rN7yuu|e_(RShZ}DXY-LJ{?V&D8# z@cQJ0d+i3>qWq}5b6Yt14X3#S4-Z{L>*(6-frjDB@YMdC5^kDLygF^2J$y%Rji@%@ z5xjq(bfu}M&AzAA+6wDJ0yEF|yktVO-2F>l*=?+EbGl>N^%Ok#32Z3K!&)yjsXV;!?$4f2a?iLxcTA2Bty+0R*U1lbhC_w#EQ zd?2sBGq!xz&VhWFU3HmZu4m%^NU`|z@_w*t_Z-uc_mx_yxNPq&g$ z_3OZwRcDij<)}MPK8hE&Xve!YcQjo$xP#9Kf@s6hxC`pXHrh#Chl7AN!dm1&rricq;^;vgGmz;c253T!Fx8h z6DsD2Pv%tZ!CoJE)3-Ra(q|k;A2Y8h6|A_w`1wSa4|4YNnsmq0wLwy0%c73QRcdHB zzQ~+_BqcIUBex3s&>iAu4%)cUXq7cp5p~D4YTX&fI=QdQ%oNjiZ2fI*sqTrq!@h^F zRO>f#p?N{aJw8eiTE{~BjSLR7*&2EevZI&Y;J6o`mwy+PnEUiW@A-gF-Gw7&PRTvq z%@zFx%Fphzb8g?WgsqMqjK$}vk1*#h^A*m%x=uH~YTnK0>PnTlrIEKASOHg^Y}(z8 zd~bV=>kXM?*2wgQOWP!%hJR+Q;E(Yo31%_VuR^juMgcu%WM?~TsHtSxC`?BkEy zj2ERvL36kHJiB`?eyc|7>{X-V`d?*HpYjQhLsz>%AX0HGGTDG5AHz3L*rB7u)fzgXX=b`N>{#X(`Zn-i>0wyTUjBx1t=qO6?_Q~(7Z_mV zFK0U>Q+>aIa^GS3_KgwoD^;(-;xywl z?QLi$4mU1lb`q`)bauTC*b^9;`&lq*Dwis?G$kVGRlGxmE$KY#RrZHnCZ`vhR`*tS z$p<8lrMxb=#m#n^r9!f#F`D02YtsIBP{Y?dUvgB-W44pd%45;z( zcj7SX!v`5Sfxp}N-Q0~3h{h%sc&G7mb0yNbAr@2ymj+lwgz&&S4+KJ57Qv&^g8?Cw z1_ZJ=*090yN*I*Iu!i|sxgp(nWFUy;9K{E`quhPyQNeTq1Ga3bGARPASY8Mqq(UP? z*c<^d!WuToO9Y=K(+C)J5+V$?hWWX9Ldje{0L55fERb-A2v#^6wp1BP;xm{;FMG#n z3UFi%3la)>Lh)5~UP-Yna4d zB7;k3F^H3omS_|nZ;3*~sdNAZ$55FVIDv*i!s!GixPT=v893|=Dhfv+q;lwhgbF0L zV1YbzD-;@oBGBM?D@zOt0YtmkP44O zVysYjD>#mZWx_FZ3>HqnV$g6r4uhrQu~v91G-i@Y5(lEKC&e0uwm|-v@nlnlOfEkJ zEH4&^!4(O9EcviP0B<2x;x-f(iy~lfIE)n%2ilDO0a^v{1z?&>SW!p|^wbK2PILr0 zsbIRXLa2cNg2xG*6p;jm2yO>-Emcw-AoJurxEmsw4^V|%z7LnnwuVWpg-R$Viwa7b zE*GLJmp&;t2?iLFikq%EJ8B?ea!5k_75Lwnyo0zR&i{_*2lP9OEng_&@`FA29<+@B zUHI2Le+K@}HIVO*&0z0AW1GH*loc+h{pP$ zQA7-mh{3|9qCFk`e`b4hIuc7o(HU?mfG5B)R#pr+fq`SdEon$B4Uf07!c*}-oBMy; zo+Zi$Wl2O5h)An%+an<)2gtWzk|ZtG&5bxS+$2d0CQ>AI<{if4u~`8B=QQ|M7XJfo zhWvC1{wML7uqkOWmlp{(sUV?;i1U}~{{%S2;L4%{90B*QOrHsva?6Z!7PNV44m`iX z>j2{WePFr>Bz@u^{7e_uKd1qu{-xw^`S+K*e!1&!dEjq>e`VJ%cl|97{4MaW?D~Im zm-3G{3IGSZ){4OQ1x4@^H1J)6Jk7<)e)6pY}`Gg#Qg`Y_Zc|+R=4%@!0_rTZA%pP^R%=)9hPe< z#a1tLF3Uf1WT|OD;qJ6(S^Ywx^G8|jPL+Ew&3P-57ll=|KO#JT_&P!q9^SG<+rZ<_ z!{N{fIl1xU|GM@vqdo9&FK+8?;-=E~s^;^LUud;c%uf^aDm+`t^CK_4UT3_y>h8WR z1S`D9`nI zQssknabIb^wFUAW9W@EV^H0KIaT>u3JESXKesMf%h2w7B+o;p!(`=l-$2(--B2~y( z-yK|BtcN#WD*U;H&(P3U>-?tQynUg!R7xt2=p43|&FMCZ7y9{$scM`+^-Xm^l+)FBYtQL$ zSM)TYlZ&d*$R+8hj#7KeqU-6yYBK$+ViNlHEl{@L#Ha7DzX}{_1Wc6t^vZ`no*`7W zQ^|2`Zg@R|vhIc8M*pgM{7S>oozWA`vCW6nA$#6R|I0vAw8ZdzDnT(;ziJC@9(y@9 z_PpK0Q|b`iD&K||IgV-F4qc9n&tu(s#`<+(mq(ux?6sk5G$FOW8P?77wMuZRqq_oQ z19gG7(Mab7DP8<0BYJ!4(Y&gJuLi2)j}pFW%DVzDtFy2h(5`R3Fb*Mivl3$`-VFv% z3|u3G1Xj3$@oW6rzWMxnw4s`lVC`UKVWlOLCGB)qUF!0d{>+@cEzMCZ-34}Wm(P$h z3vmvmFy_51y@)3;w&xeMIKZXD-aMHDn9 zmgp(2Sn~XqZBw?+UFK5rw|!4rDG`Tv`;WZkGtJMKZSTEe9(WB|A9l#SsK*SsDMO>v zKjYcEVf_bu;7Nwoy|VmP&hHHRKxf0_EiwwjnthBqjtVObsB_A@DEo}L~2E%Ii$rhHhVs~vF zhB0;w*c^t$B-4~MEs3dVIR>aX0t7H;pd^NHggdp9bea&?fSW?034JTuilL-o+U|^Y z_1^yf_aE>7-@bZVX6o>v(L*H?$#6@WIU7C^@i#aM-px%bPDmsJYFs9h&0;bkHjZ_= z+(06UYkT80Yn*vj%<(E`Y13; z;17Iv;a}bgT^%y&-AwHbw>vb=c=67{nX3!gkbUf<@vBdPPiv#Cfy-w|UHjzr)^F$J z-Pz_lHs@U9k>(>e8s^yU7k`yfKW}vN;t`w9)HT+v8Jt?XOL%_#827gLH*YWTrGBz= zaw1mL(bO^gc-|ED`|CL$UND~u=57h@qNbmrGLINJQmnQ=TX&6kx|KhYl ziiAakGJ~|hYC}vc2N0E9CCAX@fUAO#LI{HBImSt5n^SrraAc5{3WASRDExlE+^>|g zT!{kL>2wN=P!I$PB~U)-6{rB}6=OGb~$OFp5D5c&8aa=qN4S z$FX>Mf%4KorB-S&2Gs$~fvO0&cn%S#0}iD_OUJ8e4C~X+;#{!IDR+N= zL=GczoLbzW)TmL4hSpU&0-!nu$5AJ6XbDCGa9Rtbh?sBEXtNlkgdAeSLz|ltoGj;o zUE}gHte@|lx4S$bN1((c;TjFDQ)#s-ty+WQYE`d99^iObu_6q|O4 z%R`j_h0j|eMa0aL(0Q0bN-S{*42MLTI6w(3XJ=WrK`J_fh@`&GfW6UM_+$o4hc&|r zfC={>628J+m_(HzipZp1@l$I5#?2{Z{oV+mw<&*$`nXbrY2*Yy%avtuS&jvO7M_** zV`>p@Hr(TQfeTumIsB(+=zA(U4U$+c_@r++U}3+h-ZZ#fNO)HuDY|Fzc&Y+0(%wnB zl=7AUxaGnQ>=AQ4rOI_mbv(`}l_-HZ0jg4}wWv<(pi!}6Da@fHXjO#BvrfTJallvt z>jjntY`Ab)AaT9*DeJT3F9l-pVQ_DS+a95@6F8~Xk*auUziJSxBwQr_mpCX)r6sfs zss{05mpLiafopM8tQwS&RqY1m~wdH8SRP~vu6Nn$z@(>@-DULk%O`md2*+)&{L z_2hEu#Z8yAh#ivmirD2;wWv(X-(wX|_%VF&iY(pOH^emih#uI+*qN8B5VKW$n!{lWJmcQtBc>Hfs5qw7At zr`5T#s*lBw`B=9%wyt|k5@ORtCpO%E@y-`5)y=lKmA|?2Ab81}{89JH%>6Izk{&*L zd&a%HzxOZZuXTR6@BOdK6|Av#*&zG%eE*KTSKB|xBQG6Jij};#;p>zB5Vq>#FG`_? zq;+57gRK_>O(#R<8KnWlGUfbNwIlMIEd!-!w56k3wb*y`jX^(`nf&kKcV>9TZP`6c zZDStXsm~bk*D;M7+N(E>G8}5TYA=4&vi?`v!?!<+Qa9dTZIO@6c(eJ@txCy3E$Yj4f0Det z-o3j(J}&6|^Xs`YWKBB?*I#+P1>3B?)@G}ld3XEG%L6~`T$I~+Bnqi+KjD18$Whjr za$&&yFB00iJ1f?M-I}O@jq`Q~CB71F&$W$zyJo$4{$ABv$J*+DHb{cDZhY90v?9T< vDf>C(%jR_ZM^Wg+m2v+t=PLdf74vA|u~!?1Sh<7?;tA4{oN3;cG{5Fw+-%5U literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/contraption_controls_indicator.png b/src/main/resources/assets/create/textures/block/contraption_controls_indicator.png new file mode 100644 index 0000000000000000000000000000000000000000..33f1fdd9dd263d21950efdf7d9a0b1c82bbed727 GIT binary patch literal 2945 zcmb_eeQXow88@0x16@cZO6f>8Zq5R6>G?i{(28R{*K8sXQ$}# z1brS45>%v!7y~9#e*sv!V9f#x2$J-fi$4@{7Hn9R2wHQro2y z(X_OzbRBpAT;=(`zSkqI+~KD`d8q%5elvY>a!|VD-}>~%H>bw0Y_I$5;GK_#-+AN8 z=%&7F&o5lMZ|g7B$%p^))AZ=Pg)h}P#$vJb{Z+rezHQx}hoyArp6Sv(?}GPsEeWLl zc%F4$t++b$_vWVSN95DZBTt=r<Y})l=a^z0%+DE2m>8scJfANh6R?YOw2c~;^goX53Qh0E&1;Rfsy|@QH7HAE1 zjnjo6Q}tU{&cdB}a_t5c0#51QIg2XScAHE^2gT5OZGFJc@>1N&2~rqXQ*jxhO(xf> zl+5w1KtsYHDkj|KiQ|K2L=@cS@7V)*K=yzZu{N!M#&lhXPq*?;!Mti^@qAZ`g$!|^ zaY!m2OQ>whZ8nHm_+J-eX2gJKt#0%BKoIdr3P30;WyR6zl-N$1Aqj%G6d}Skc-Le} z;L2@o(KMOGuw*i6P1>xI62%Co(~03EMv^E*plU}#<5FlsEzgi-X}mz?6;akiDS_y; zTv%$;+-B&9;UL`Mt5Z;r<=58+yQ&G84=yMe5CmW(jx#7uqNG!gAro9&4g~U=2{oHT zm`yCj$rxe9v3NX>R<-K(n|5xCRzn>!z#4!mwJAKPZU+giJZDUfwW)=++Ek#63}0hH z1cPoG7IXL-Um%#r>sgD6aoIrY$Q(-G^BB2Ji5dF>kAWD7L*puBB=T5IjNCkj8UE`# zGmJwMdEObwTwZkhFnO$3;@fmfKCj!XJID$WFAA*j*G3WyVqfKzW|QagJspq(J2K z>lG1}ITtJRN9PeB597coJHgmdN0^SF6i?Bplcq?NaZohJ(00a7Qf5TYH(M3-xy_^% z&n|;8PK!uN9CnSE5TvASP3NC81d0 z*)@=ggC!)!xhTNoMAVGvnP;K%Fom36;*ih?iS;Oe(3SdPyep31cY z!JHNHEnFfB;K+p?n1PA6sd9(F2{a?vP{s*plyYz!8g?)Q%2Na&93&nQ2w0sNeN~ER zNlpP(QCKgqEMUVKWr0*?>(i1$CR>1Bd^nt~aO{zEh$L9b!BVi{ZdQX{B}S3_KjPqd zoaP8#KsmrTQOa%?P^aJ!P+J(M!wh4$GaQri?thKLMuZ3(i#u7|J~Iv%roS2r&&Z_@ zR5+k+Jx-TCbXlL?fsJjl920?3aIQu+AWcD%T-blnC}7Jr?Ci;IRmgC8B)J35vKFmA znV6+(U!s!X^NT!4sM73$yak-eYQYQG2reUqZ+EzYSy#&9=%7=&jh-klm{Oi-#Du5?>|sBw{~E8c&p`^P0!qK zdg;8zVx>1 zvtvuYUgq*o4ZXF()%%-a_xb6rv67XmuD$q&lIADwOLksh`}J#-ue#2AWc8Mv{{|Sc BNS%G}}0G|+7O-)T}YwN12s{a1|)YR1Q@NiQT6J=#(O*OR=DaRCHvuHm3je6nz zNNS%Lh(0G|+7O-)T}YwN12s{a1|)YR1Q@NiQT6J=#(O*OS*3A-Kzk2-0mvuXL8 z9HUq11W!@+o3G)w_Snjf?#isZ_Skb;E>}o}o!q(_iy)0K7iF>#8 z&m_<6=Mj6j(kxc+h4HaD&S&3$ys=yC%Wu)${{s_wII17-3;;To!PC{xWt~$(699>r BhFt&v literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/elevator_contact_side_powered.png b/src/main/resources/assets/create/textures/block/elevator_contact_side_powered.png new file mode 100644 index 0000000000000000000000000000000000000000..afc7fd5d747fe2e087d6c9dd35167db6248cb521 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}N0G|+7O-)T}YwN12s{a1|)YR1Q@NiQT6J=#(O*OS>KK)gi;U|nz{=dHX zf9bUUt*yVaYreY{{fsJKdu(M#cV$*ya!^>Xm5XbWoO{2L&#WaAEDxz}0h-KN;1OBO zz`%C^gc-B0b#ej)7kIijhG+!K_A-hcR^V{HnDu(WinW(^{*EtMSoy8bv*7;&`e)1vTzDR(Sp12!a6C79&1?FMzq+Acxi5VKhOUv*Q19G5wkt^->BYo zd`8g3YT@^pvu2t+S$)c&I-}<14rTMy=+iIMYbC<3PHs0XEcj#+Z=Lg!dyD>T^Jmv1 yWfRit*U!Fo&Mnz+3j<5?k1N-mK3ATdXYV_odv?}dxW?khbnnaSqxbZ>$tkKC$njaJ2-;~1 zY3UgUTS)mENqFju8<<(Ty0`=c1Ox^Ks;j9=U^YfdO zZ(8J|t*&h#E-9m|rtRYGlai4f7#37gUE&`W*4W-Weby8gPmiehxU{UyqS6vWd+YTZ zmK{5`18B&+Gqu@3%BUpBFZe&HfPpt)#(SV{&H|6fVg?31B@kv@_2}*-V1Qikba4!^ z@XwvxUAD?Vz;&|8;l&G&G+d2{&Sn*SQTy}1effEn3yW5#>+%+srJdsm$S7HL+&sd%oI!gy60w|`T41)3{$=Zi+l=Nd1X!6Z1IfX^**QM-Zd=Q z@O4^aZf^I3M9u?;g$z#i%e}Fhc4Hw6^J%m1ClYc@enu^1nH`gMBY9Hm)~oN<#=T!- znmFk+PtXQWIiZlGfS4r9tO|vmn`fF{-k!cyJgYu}W8S^|`0u~>9%=NL+}6S8ZvN8Z zD4#XDBJj^cd z&eYDcWTI@#wfnhpv9A|ila)+x@?QC}I^dl3lB^9K0rrn&Tyn2}kG-EL*;e=BqO*+1 z|IQt~DKa~^7rr?zCiR=)!}T@Aw;xti%WZg+`QUyX%d*@FClXietoiq=_iT((+oB`$ o1)u+V_})GzZL;B!U2*@Jezopr02I(+>Hq)$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/elevator_pulley_belt.png b/src/main/resources/assets/create/textures/block/elevator_pulley_belt.png new file mode 100644 index 0000000000000000000000000000000000000000..f9dd15f2808df547b6f154ea7177d72b34437a23 GIT binary patch literal 394 zcmV;50d@X~P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0Ut?3K~y+T-BPhi z13?gdcX)S$=2%7W11v2ByFfz3P794?I{(c|>lAiE8Wqwhwic2`L6Xg>>|PGnnZ0b0 zE`<>A!7Rh<%zKZWjgHy}&e{rh!>8!{r0u493^R+Na>C8+Fao1{+;YWqf{fOolya}5 zx0uULdSXh~q{oAZd=n)<$g*r+1+2A98o`=x7-QyDz?2nYIRfO;H?ad53J@|%Tusg* z0V4k29B8d^*1N#rX>WN4#>`NB)vUTOc>frq_|!fRD9aMN`%UaMJ6Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0WL{IK~zXf?NmKW z1TheOySTf9x6yz?qD#_kr%*FMtT4NS%G}B0G|+7M;k*+6CEQxjQ~#@Co63$Q(aFd)0B+lz_6f*K$q#WrZl!UmsFPo zdfDn~sVXbTN{EX9wVpe=j~7S@l?3?(|3?Q5kM{2u0?Kk0ctjR6FmMZlFeAgPITAp@ zbWaz@5RKr{UT?kw3LLDgqFZk9f8U?u+Ii6=c0zopr0MQ_4E&u=k literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/elevator_pulley_coil_scroll.png b/src/main/resources/assets/create/textures/block/elevator_pulley_coil_scroll.png new file mode 100644 index 0000000000000000000000000000000000000000..b5364418d025f4c446c66c2992eea35673418b28 GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!3-pI!a4o{DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheS^+*Gu8uZ_mL@tzdKv+qHcnRBR;Ie1PNpdt$$?=(5rHn#XH98rZ!W1W z0V?OZ8g~jv@s$Mm1^-6|46X<6oB+yj7I;J!0~H(wVaDV6D^h@hQJyZ2AsWF?CpdB) zP~c&?8#;N*tpD}fBbH>i{%VjbI$_|WaPTg(M6lSSxLYe^Cn+`Zt=MKLx54DVPR4+9 zM$$X4*f6gAb@4`wq=T_fe4D2Ai{7IVQp`VI+uzZ@s=)iX{!#Y=pe+oZu6{1-oD!M< D*2ZE} literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/rose_quartz_lamp_dim.png b/src/main/resources/assets/create/textures/block/rose_quartz_lamp_dim.png new file mode 100644 index 0000000000000000000000000000000000000000..dee04668f21bdfd1b6f830503f60bf7978d67651 GIT binary patch literal 320 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}Z0G|-oj_%4?OD3#6wlXU(Ihs#DMcAxF$}uP`xJSWblVkMRwEPY^mpW;u zVhOudI>A$v{pM@Ealo5ghC9 z$kc4W(VfJpQ2Oe>y!DH`#{nLxs|J_ue+Za4u L{an^LB{Ts58LW0@ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/gui/display_link.png b/src/main/resources/assets/create/textures/gui/display_link.png index 35c88f4640b743bd2e441b0f7b3014d0f4aa1d7e..216ab336a7c39d8e9ca734108f295cc825143dc7 100644 GIT binary patch literal 2037 zcmb7F30D)@60Y0n1Ofx7xQvKH93e_jb_84?C|eXT0w%12j<|p3lto2BQ1Uv=FL-^vKHsf-s_ItNsk-+FKfuR8 z&qNOZ40yhtfdGhFBG9E#6n8l!SSuw5`mBV~d#1gVfN%Bi_W-zdT>tAvIwj}u{erzH zrqk&dhA|ingwTiDcxA4q&=NM-qewf5w1o%?HV{t18p0?nhOk8tO2G<3C~!c?0UXCq zoH&t^l9HI1SXEWUceC_xV7a=w3WY*vXJ?5-A`*!-8cktgp-QD%zkdCeEnB*~yE{7{ zb#``kbaWII6O70+UtGf`#%=C<>ncE+wB;9Yk$mBS@_#K#}x6Lqd)a? zqMb^+-;9p#ZCdI&4??68&?P_@s{5v+DS*h>h|huFSNA<^Xqb9g6$5AT^S?i9(hy%& z{$t;HWdel$DgCZ1^ND?WE6?Mqu30U6!cO7nvy2%;FBu;KWAOm)R4<@L-k=W^Ws{Q4EGjo4L^6|OxCYATiO#@1J z(})F^%;ARz&4#d39s3wp!>jgGCfWDYWHHL_5Y%%slF5p_I?_)GP%?VX3N?(LvqZh4 zW;Q5;7Q7OW`6n8J(et-tq=ab{= za2b!UYNWFaBMkgW;yQQpxL@vaG?EwT6n~EQPjHe4)0rWeGJ?j2bG&;trpJwqlj>br zT=%^6wYPF0pDv>UJ<5#6)a4$2KqYC5o=r?H>Z^>1q4@fUzn!yKY&F3Q=?QxDAE$0b zoov!-_6QKi&0o*TxP64_^1}4Qt3&6tRkGcV1x}~j9Ht2=FHmf-38QL8Fo!;G#bksB z)A!@5b=m`E_UK63LXKgC9XfRnS!yGw+iyiF60Hn7 zt3MX(9gew+KG@5+%k_sAQCU-paAwJ2%2q}U;A**V#e;<61%?sQ--&nQI%Nm&RN?A5 zgiDf>Ez0@jq=!SruEn=qq3PkB3T^qRqTd{2vU|iA@S+~^pZIsVv!A&I_;!^cCGUuRlXETT z;T%nTe%G@kG!lmO1wFA!XW9&TTl>Su8BMnCGvwn}N~Cl1Hl}d|M&UsggpR_}W-3Hs zI12;}#I+ZLr zsI-WOq;G@bSgWs2JB>kOleyj)~RpK$*OJZGSQOLE~($zqa8cmfE3^e`&`` zn~M$Ph*#myi(0Hk%a78?m?FU^L@=hWSsxxGEo-$!(X$VOE>{OSB3pz-PpT5&%_Tv@ z?pgZP(yh9zcT4i;69uiJEJ($^Kv|PFo$z7JfzPIV+Qn+=YmB5?B)F#10rAI1kS^+n z)jdOIz%5+y4PI=~AskH}8j`tJzwU)g-jY7#g59fGM=wZlEHNYIsb>l>GOj!a!CFv% zxj&5)oa=neGDW P83UeIfM@B-==A>qICgZQ literal 1164 zcmZWoX;4#F6h80eJxIcmus9ToG@Ys~R2D%bv;`6-NEpf@f(fBe&^Cb3vPFpC;B#kj z5U@q4HrRm?1SUXb)8Y_10y0>ZDnmdbfwF`Fl(ryag`_Xk_D}D8cfNb(eCOQn+?ksn z8tiXEx1j@oNdTW027r)91gI2}k{X2JBw_K~ATB`j6{F2KoQ!Fy{KyOd({BAnI!cmO z^d%W#{=Og|v|S{Fg3wRH{Ycj7bTczEO69mxsT>;{`=k4--rnAhj*jZ;>Z+=$uJ3ro z#l?k%g;J?hB9Ww|q=?00fj|%u5fSQbALEL6dU{6hgJ>7{jD$0Icz8rPLzEMUNH_x5 zjV0O(kt99@AqfW%kgx{>0|Ok#F$_ad6hZXk6z;Z)(_55;1s?{^yiyE6$qnFf!=)3; z!};`cF2)Ax^n8~R*LnBJ+fm;ic%jPR|@-`8phBy0AzWD`no=Vp8@q9>R*$D4sjAf7A zw{zWW+2w)J+PZtsUyQU24x6Y(JEmW+F!1S7Un4J7X#4vsZhP)8Efr;U?bKNJRh;-T zMQ))AJsot1=94$WJ?}T`+fzn;K&56aWW_dGMC?LBh4g%#yHImOtut zz_RMh#RnYY-ZbQ>yJIVzvY`z*DM0D-lK88^+R6;7aQ&*J;PNwOlaDKv11OUK?9>s? zPraS8T~8B`Uz|z;z1Xfi&Jaa9mv^2fo#Wqtfs!jU;o76Hc0*0}!5n;ly`!Su9has# zAzG{@gPs?(M^Q;+h9DK8iky+torVvSQ7J>cceSdnbqKw8eB}-y7s(AJRF}K+BF10> z^2+T9M~l%ooPp90kTs$${^3iN9Raugal-;++gQ_z_0dBpvnjGD`CXK$u++=R6o37Y zg!Jr!>z)6rC5W|m{3sZU^}GMb>uvFyUa`W>YeoGQn60+)YX*C;>sK!|yBw{+|0}-| zUDKz91AJpMg?Bd^^~I?Qk;+az@FW{=nRq(eDH0G?OE00>y1jo3(a2EON}^r1n9E=u zyKeg$tJ$FtCk~=(M4$ZeZx?CL-{QWxR^3LJdjzL1XqA z2FGg=7RR8tl)@qCECl*@zs-QZJ_o*ij}(Td$Q%@xZs>5${R~h~!?Vg6s@l|;X!Suj ze`;Y>YYQe@hj}nD6x8vm& z&F13G3!Y~6Ai<;v=HlR?sGWqWQVK7VV2&fVh?sL|Y@z&Tbl9w1wZLm|?mwNA$|AoU fz^rb9TKB)@us+GNxsklTKradK3+BmvW6%B#x{}Xp