From c1954b40715d36f9727def99458c0038d4c79645 Mon Sep 17 00:00:00 2001 From: Samuel Williams <33094920+samuelWilliams99@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:38:35 +0000 Subject: [PATCH] Backport of TURTLE_CAN_USE (#1656) --- .../tags/blocks/turtle_can_use.json | 1 + .../computercraft/api/ComputerCraftTags.java | 8 +++++ .../data/BlockTagsGenerator.java | 5 ++++ .../turtle/core/TurtlePlaceCommand.java | 30 ++++++++++++------- .../computercraft/gametest/Turtle_Test.kt | 4 +-- .../turtle_test.cleaned_with_cauldrons.snbt | 8 ++--- 6 files changed, 38 insertions(+), 18 deletions(-) create mode 100644 src/generated/resources/data/computercraft/tags/blocks/turtle_can_use.json diff --git a/src/generated/resources/data/computercraft/tags/blocks/turtle_can_use.json b/src/generated/resources/data/computercraft/tags/blocks/turtle_can_use.json new file mode 100644 index 000000000..4e60430bf --- /dev/null +++ b/src/generated/resources/data/computercraft/tags/blocks/turtle_can_use.json @@ -0,0 +1 @@ +{"values": ["#minecraft:cauldrons", "#minecraft:beehives", "minecraft:composter"]} diff --git a/src/main/java/dan200/computercraft/api/ComputerCraftTags.java b/src/main/java/dan200/computercraft/api/ComputerCraftTags.java index c9b317fd7..c57c398e7 100644 --- a/src/main/java/dan200/computercraft/api/ComputerCraftTags.java +++ b/src/main/java/dan200/computercraft/api/ComputerCraftTags.java @@ -12,6 +12,8 @@ import net.minecraft.tags.ItemTags; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; /** * Tags provided by ComputerCraft. @@ -58,6 +60,12 @@ public class ComputerCraftTags */ public static final TagKey TURTLE_HOE_BREAKABLE = make( "turtle_hoe_harvestable" ); + /** + * Block which can be {@linkplain BlockState#use(Level, Player, InteractionHand, BlockHitResult) used} when + * calling {@code turtle.place()}. + */ + public static final TagKey TURTLE_CAN_USE = make( "turtle_can_use" ); + private static TagKey make( String name ) { return BlockTags.create( new ResourceLocation( ComputerCraft.MOD_ID, name ) ); diff --git a/src/main/java/dan200/computercraft/data/BlockTagsGenerator.java b/src/main/java/dan200/computercraft/data/BlockTagsGenerator.java index 4ac2b55b7..571bc1e66 100644 --- a/src/main/java/dan200/computercraft/data/BlockTagsGenerator.java +++ b/src/main/java/dan200/computercraft/data/BlockTagsGenerator.java @@ -60,6 +60,11 @@ class BlockTagsGenerator extends BlockTagsProvider tag( TURTLE_SWORD_BREAKABLE ).addTags( BlockTags.WOOL ).add( Blocks.COBWEB ); + tag( TURTLE_CAN_USE ) + .addTag( BlockTags.CAULDRONS ) + .addTag( BlockTags.BEEHIVES ) + .add( Blocks.COMPOSTER ); + // Make all blocks aside from command computer mineable. tag( BlockTags.MINEABLE_WITH_PICKAXE ).add( Registry.ModBlocks.COMPUTER_NORMAL.get(), diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java index 0ac262f57..3e6e8a4ed 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java @@ -43,6 +43,8 @@ import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; +import static dan200.computercraft.api.ComputerCraftTags.Blocks.TURTLE_CAN_USE; + public class TurtlePlaceCommand implements ITurtleCommand { private final InteractDirection direction; @@ -210,7 +212,7 @@ public class TurtlePlaceCommand implements ITurtleCommand private static boolean deployOnBlock( @Nonnull ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, Direction side, - Object[] extraArguments, boolean allowReplace, ErrorMessage outErrorMessage + Object[] extraArguments, boolean adjacent, ErrorMessage outErrorMessage ) { // Re-orient the fake player @@ -227,7 +229,7 @@ public class TurtlePlaceCommand implements ITurtleCommand // Check if there's something suitable to place onto BlockHitResult hit = new BlockHitResult( new Vec3( hitX, hitY, hitZ ), side, position, false ); UseOnContext context = new UseOnContext( turtlePlayer, InteractionHand.MAIN_HAND, hit ); - if( !canDeployOnBlock( new BlockPlaceContext( context ), turtle, turtlePlayer, position, side, allowReplace, outErrorMessage ) ) + if( !canDeployOnBlock( new BlockPlaceContext( context ), turtle, turtlePlayer, position, side, adjacent, outErrorMessage ) ) { return false; } @@ -235,7 +237,7 @@ public class TurtlePlaceCommand implements ITurtleCommand Item item = stack.getItem(); BlockEntity existingTile = turtle.getLevel().getBlockEntity( position ); - boolean placed = doDeployOnBlock( stack, turtlePlayer, position, context, hit ).consumesAction(); + boolean placed = doDeployOnBlock( stack, turtlePlayer, position, context, hit, adjacent ).consumesAction(); // Set text on signs if( placed && item instanceof SignItem && extraArguments != null && extraArguments.length >= 1 && extraArguments[0] instanceof String message ) @@ -261,11 +263,13 @@ public class TurtlePlaceCommand implements ITurtleCommand * @param position The block we're deploying against's position. * @param context The context of this place action. * @param hit Where the block we're placing against was clicked. + * @param adjacent If the block is directly adjacent to the turtle, and so can be interacted with via + * {@link BlockState#use(Level, Player, InteractionHand, BlockHitResult)}. * @return If this item was deployed. * @see net.minecraft.server.level.ServerPlayerGameMode#useItemOn For the original implementation. */ private static InteractionResult doDeployOnBlock( - @Nonnull ItemStack stack, TurtlePlayer turtlePlayer, BlockPos position, UseOnContext context, BlockHitResult hit + @Nonnull ItemStack stack, TurtlePlayer turtlePlayer, BlockPos position, UseOnContext context, BlockHitResult hit, boolean adjacent ) { PlayerInteractEvent.RightClickBlock event = ForgeHooks.onRightClickBlock( turtlePlayer, InteractionHand.MAIN_HAND, position, hit ); @@ -273,14 +277,18 @@ public class TurtlePlaceCommand implements ITurtleCommand if( event.getUseItem() != Result.DENY ) { - InteractionResult result = stack.onItemUseFirst( context ); - if( result != InteractionResult.PASS ) return result; - } + InteractionResult resultUseFirst = stack.onItemUseFirst( context ); + if( resultUseFirst != InteractionResult.PASS ) return resultUseFirst; - if( event.getUseItem() != Result.DENY ) - { - InteractionResult result = stack.useOn( context ); - if( result != InteractionResult.PASS ) return result; + var block = turtlePlayer.level.getBlockState( hit.getBlockPos() ); + if ( event.getUseBlock() != Result.DENY && !block.isAir() && adjacent && block.is( TURTLE_CAN_USE ) ) + { + var useResult = block.use( turtlePlayer.level, turtlePlayer, InteractionHand.MAIN_HAND, hit ); + if ( useResult.consumesAction() ) return useResult; + } + + InteractionResult resultUseOn = stack.useOn( context ); + if( resultUseOn != InteractionResult.PASS ) return resultUseOn; } Item item = stack.getItem(); diff --git a/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt b/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt index 7d29eb39a..0548fbd46 100644 --- a/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt +++ b/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt @@ -151,10 +151,8 @@ class Turtle_Test { /** * Checks turtles can be cleaned in cauldrons. - * - * Currently not required as turtles can no longer right-click cauldrons. */ - @GameTest(required = false) + @GameTest fun Cleaned_with_cauldrons(helper: GameTestHelper) = helper.sequence { thenOnComputer { val details = getTurtleItemDetail(1, true) diff --git a/src/testMod/resources/data/cctest/structures/turtle_test.cleaned_with_cauldrons.snbt b/src/testMod/resources/data/cctest/structures/turtle_test.cleaned_with_cauldrons.snbt index a208024a5..cb9f5c194 100644 --- a/src/testMod/resources/data/cctest/structures/turtle_test.cleaned_with_cauldrons.snbt +++ b/src/testMod/resources/data/cctest/structures/turtle_test.cleaned_with_cauldrons.snbt @@ -1,5 +1,5 @@ { - DataVersion: 2730, + DataVersion: 3218, size: [3, 3, 3], data: [ {pos: [0, 0, 0], state: "minecraft:polished_andesite"}, @@ -15,7 +15,7 @@ {pos: [0, 1, 1], state: "minecraft:air"}, {pos: [0, 1, 2], state: "minecraft:air"}, {pos: [1, 1, 0], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 1b, Slot: 0b, id: "computercraft:turtle_normal", tag: {Color: 13388876, ComputerId: 0, display: {Name: '{"text":"Clean turtle"}'}}}], Label: "turtle_test.cleaned_with_cauldrons", On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}}, - {pos: [1, 1, 1], state: "minecraft:cauldron{level:3}"}, + {pos: [1, 1, 1], state: "minecraft:water_cauldron{level:3}"}, {pos: [1, 1, 2], state: "minecraft:air"}, {pos: [2, 1, 0], state: "minecraft:air"}, {pos: [2, 1, 1], state: "minecraft:air"}, @@ -33,8 +33,8 @@ entities: [], palette: [ "minecraft:polished_andesite", - "computercraft:turtle_normal{facing:south,waterlogged:false}", "minecraft:air", - "minecraft:cauldron{level:3}" + "minecraft:water_cauldron{level:3}", + "computercraft:turtle_normal{facing:south,waterlogged:false}" ] }