mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-25 01:20:31 +00:00
Rewrite turtle.dig tool actions
- Move the tool action before the "is block present" check, fixes #1527. This is where it was before, but we flipped it around in the tool rewrite. - Don't reuse as much turtle.place logic for tool actions. This fixes some instances where tools could till/level dirt through solid blocks.
This commit is contained in:
parent
1b88213eca
commit
0ad399a528
@ -74,7 +74,7 @@ public class TurtlePlaceCommand implements TurtleCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean deploy(
|
private static boolean deploy(
|
||||||
ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, Direction direction,
|
ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, Direction direction,
|
||||||
@Nullable Object[] extraArguments, @Nullable ErrorMessage outErrorMessage
|
@Nullable Object[] extraArguments, @Nullable ErrorMessage outErrorMessage
|
||||||
) {
|
) {
|
||||||
@ -140,6 +140,22 @@ public class TurtlePlaceCommand implements TurtleCommand {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate where a turtle would interact with a block.
|
||||||
|
*
|
||||||
|
* @param position The position of the block.
|
||||||
|
* @param side The side the turtle is clicking on.
|
||||||
|
* @return The hit result.
|
||||||
|
*/
|
||||||
|
public static BlockHitResult getHitResult(BlockPos position, Direction side) {
|
||||||
|
var hitX = 0.5 + side.getStepX() * 0.5;
|
||||||
|
var hitY = 0.5 + side.getStepY() * 0.5;
|
||||||
|
var hitZ = 0.5 + side.getStepZ() * 0.5;
|
||||||
|
if (Math.abs(hitY - 0.5) < 0.01) hitY = 0.45;
|
||||||
|
|
||||||
|
return new BlockHitResult(new Vec3(position.getX() + hitX, position.getY() + hitY, position.getZ() + hitZ), side, position, false);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean deployOnBlock(
|
private static boolean deployOnBlock(
|
||||||
ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, Direction side,
|
ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, Direction side,
|
||||||
@Nullable Object[] extraArguments, boolean adjacent, @Nullable ErrorMessage outErrorMessage
|
@Nullable Object[] extraArguments, boolean adjacent, @Nullable ErrorMessage outErrorMessage
|
||||||
@ -149,14 +165,8 @@ public class TurtlePlaceCommand implements TurtleCommand {
|
|||||||
var playerPosition = position.relative(side);
|
var playerPosition = position.relative(side);
|
||||||
turtlePlayer.setPosition(turtle, playerPosition, playerDir);
|
turtlePlayer.setPosition(turtle, playerPosition, playerDir);
|
||||||
|
|
||||||
// Calculate where the turtle would hit the block
|
|
||||||
var hitX = 0.5f + side.getStepX() * 0.5f;
|
|
||||||
var hitY = 0.5f + side.getStepY() * 0.5f;
|
|
||||||
var hitZ = 0.5f + side.getStepZ() * 0.5f;
|
|
||||||
if (Math.abs(hitY - 0.5f) < 0.01f) hitY = 0.45f;
|
|
||||||
|
|
||||||
// Check if there's something suitable to place onto
|
// Check if there's something suitable to place onto
|
||||||
var hit = new BlockHitResult(new Vec3(position.getX() + hitX, position.getY() + hitY, position.getZ() + hitZ), side, position, false);
|
var hit = getHitResult(position, side);
|
||||||
var context = new UseOnContext(turtlePlayer.player(), InteractionHand.MAIN_HAND, hit);
|
var context = new UseOnContext(turtlePlayer.player(), InteractionHand.MAIN_HAND, hit);
|
||||||
if (!canDeployOnBlock(new BlockPlaceContext(context), turtle, turtlePlayer, position, side, adjacent, outErrorMessage)) {
|
if (!canDeployOnBlock(new BlockPlaceContext(context), turtle, turtlePlayer, position, side, adjacent, outErrorMessage)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -294,19 +294,20 @@ public class TurtleTool extends AbstractTurtleUpgrade {
|
|||||||
private TurtleCommandResult dig(ITurtleAccess turtle, TurtleSide side, Direction direction) {
|
private TurtleCommandResult dig(ITurtleAccess turtle, TurtleSide side, Direction direction) {
|
||||||
var level = (ServerLevel) turtle.getLevel();
|
var level = (ServerLevel) turtle.getLevel();
|
||||||
|
|
||||||
var blockPosition = turtle.getPosition().relative(direction);
|
|
||||||
if (level.isEmptyBlock(blockPosition) || WorldUtil.isLiquidBlock(level, blockPosition)) {
|
|
||||||
return TurtleCommandResult.failure("Nothing to dig here");
|
|
||||||
}
|
|
||||||
|
|
||||||
return withEquippedItem(turtle, side, direction, turtlePlayer -> {
|
return withEquippedItem(turtle, side, direction, turtlePlayer -> {
|
||||||
var stack = turtlePlayer.player().getItemInHand(InteractionHand.MAIN_HAND);
|
var stack = turtlePlayer.player().getItemInHand(InteractionHand.MAIN_HAND);
|
||||||
|
|
||||||
// Right-click the block when using a shovel/hoe.
|
// Right-click the block when using a shovel/hoe. Important that we do this before checking the block is
|
||||||
if (PlatformHelper.get().hasToolUsage(item) && TurtlePlaceCommand.deploy(stack, turtle, turtlePlayer, direction, null, null)) {
|
// present, as we allow doing these actions from slightly further away.
|
||||||
|
if (PlatformHelper.get().hasToolUsage(stack) && useTool(level, turtle, turtlePlayer, stack, direction)) {
|
||||||
return TurtleCommandResult.success();
|
return TurtleCommandResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var blockPosition = turtle.getPosition().relative(direction);
|
||||||
|
if (level.isEmptyBlock(blockPosition) || WorldUtil.isLiquidBlock(level, blockPosition)) {
|
||||||
|
return TurtleCommandResult.failure("Nothing to dig here");
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we can break the block
|
// Check if we can break the block
|
||||||
var breakable = checkBlockBreakable(level, blockPosition, turtlePlayer);
|
var breakable = checkBlockBreakable(level, blockPosition, turtlePlayer);
|
||||||
if (!breakable.isSuccess()) return breakable;
|
if (!breakable.isSuccess()) return breakable;
|
||||||
@ -320,6 +321,32 @@ public class TurtleTool extends AbstractTurtleUpgrade {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to use a tool against a block instead.
|
||||||
|
*
|
||||||
|
* @param level The current level.
|
||||||
|
* @param turtle The current turtle.
|
||||||
|
* @param turtlePlayer The turtle player, already positioned and with a stack equipped.
|
||||||
|
* @param stack The current tool's stack.
|
||||||
|
* @param direction The direction this action occurs in.
|
||||||
|
* @return Whether the tool was successfully used.
|
||||||
|
* @see PlatformHelper#hasToolUsage(ItemStack)
|
||||||
|
*/
|
||||||
|
private boolean useTool(ServerLevel level, ITurtleAccess turtle, TurtlePlayer turtlePlayer, ItemStack stack, Direction direction) {
|
||||||
|
var position = turtle.getPosition().relative(direction);
|
||||||
|
// Allow digging one extra block below the turtle, as you can't till dirt/flatten grass if there's a block
|
||||||
|
// above.
|
||||||
|
if (direction == Direction.DOWN && level.isEmptyBlock(position)) position = position.relative(direction);
|
||||||
|
|
||||||
|
if (!level.isInWorldBounds(position) || level.isEmptyBlock(position) || turtlePlayer.isBlockProtected(level, position)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hit = TurtlePlaceCommand.getHitResult(position, direction.getOpposite());
|
||||||
|
var result = PlatformHelper.get().useOn(turtlePlayer.player(), stack, hit, x -> false);
|
||||||
|
return result.consumesAction();
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isTriviallyBreakable(BlockGetter reader, BlockPos pos, BlockState state) {
|
private static boolean isTriviallyBreakable(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||||
return state.is(ComputerCraftTags.Blocks.TURTLE_ALWAYS_BREAKABLE)
|
return state.is(ComputerCraftTags.Blocks.TURTLE_ALWAYS_BREAKABLE)
|
||||||
// Allow breaking any "instabreak" block.
|
// Allow breaking any "instabreak" block.
|
||||||
|
@ -145,11 +145,31 @@ class Turtle_Test {
|
|||||||
*/
|
*/
|
||||||
@GameTest
|
@GameTest
|
||||||
fun Hoe_dirt(helper: GameTestHelper) = helper.sequence {
|
fun Hoe_dirt(helper: GameTestHelper) = helper.sequence {
|
||||||
|
thenOnComputer { turtle.dig(Optional.empty()).await().assertArrayEquals(true, message = "Dug with hoe") }
|
||||||
|
thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 2, 1)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks turtles can hoe dirt with a block gap below them.
|
||||||
|
*
|
||||||
|
* @see [#1527](https://github.com/cc-tweaked/CC-Tweaked/issues/1527)
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
fun Hoe_dirt_below(helper: GameTestHelper) = helper.sequence {
|
||||||
|
thenOnComputer { turtle.digDown(Optional.empty()).await().assertArrayEquals(true, message = "Dug with hoe") }
|
||||||
|
thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 1, 1)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks turtles cannot hoe dirt with a block gap in front of them.
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
fun Hoe_dirt_distant(helper: GameTestHelper) = helper.sequence {
|
||||||
thenOnComputer {
|
thenOnComputer {
|
||||||
turtle.dig(Optional.empty()).await()
|
turtle.dig(Optional.empty()).await()
|
||||||
.assertArrayEquals(true, message = "Dug with hoe")
|
.assertArrayEquals(false, "Nothing to dig here", message = "Dug with hoe")
|
||||||
}
|
}
|
||||||
thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 2, 1)) }
|
thenExecute { helper.assertBlockPresent(Blocks.DIRT, BlockPos(1, 2, 2)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
40
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.hoe_dirt_below.snbt
generated
Normal file
40
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.hoe_dirt_below.snbt
generated
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 2730,
|
||||||
|
size: [3, 3, 3],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:dirt"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [], Label: "turtle_test.hoe_dirt_below", LeftUpgrade: "minecraft:diamond_hoe", On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:dirt",
|
||||||
|
"computercraft:turtle_normal{facing:south,waterlogged:false}",
|
||||||
|
"minecraft:air"
|
||||||
|
]
|
||||||
|
}
|
40
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.hoe_dirt_distant.snbt
generated
Normal file
40
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.hoe_dirt_distant.snbt
generated
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 2730,
|
||||||
|
size: [3, 3, 3],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{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: [], Label: "turtle_test.hoe_dirt_distant", LeftUpgrade: "minecraft:diamond_hoe", On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "minecraft:dirt"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:dirt",
|
||||||
|
"computercraft:turtle_normal{facing:south,waterlogged:false}",
|
||||||
|
"minecraft:air"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user