|
9 | 9 | import net.minecraft.world.item.Item;
|
10 | 10 | import net.minecraft.world.level.ClipContext;
|
11 | 11 | import net.minecraft.world.level.Level;
|
| 12 | +import net.minecraft.world.phys.BlockHitResult; |
12 | 13 | import org.spongepowered.asm.mixin.Mixin;
|
13 |
| -import org.spongepowered.asm.mixin.injection.Constant; |
14 |
| -import org.spongepowered.asm.mixin.injection.ModifyConstant; |
| 14 | +import org.spongepowered.asm.mixin.Unique; |
| 15 | +import org.spongepowered.asm.mixin.injection.At; |
| 16 | +import org.spongepowered.asm.mixin.injection.Inject; |
| 17 | +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; |
15 | 18 |
|
16 | 19 | @Mixin(Item.class)
|
17 | 20 | class ItemMixin {
|
18 | 21 | /**
|
19 | 22 | * Replace the reach distance in {@link Item#getPlayerPOVHitResult(Level, Player, ClipContext.Fluid)}.
|
20 | 23 | *
|
21 |
| - * @param reach The original reach distance. |
22 |
| - * @param level The current level. |
23 |
| - * @param player The current player. |
24 |
| - * @return The new reach distance. |
| 24 | + * @param level The current level. |
| 25 | + * @param player The current player. |
| 26 | + * @param fluidMode The current clip-context fluid mode. |
| 27 | + * @param cir Callback info to store the new reach distance. |
25 | 28 | * @see FakePlayer#getBlockReach()
|
26 | 29 | */
|
27 |
| - @ModifyConstant(method = "getPlayerPOVHitResult", constant = @Constant(doubleValue = 5)) |
| 30 | + @Inject(method = "getPlayerPOVHitResult", at = @At("HEAD"), cancellable = true) |
28 | 31 | @SuppressWarnings("UnusedMethod")
|
29 |
| - private static double getReachDistance(double reach, Level level, Player player) { |
30 |
| - return player instanceof FakePlayer fp ? fp.getBlockReach() : reach; |
| 32 | + private static void getReachDistance(Level level, Player player, ClipContext.Fluid fluidMode, CallbackInfoReturnable<BlockHitResult> cir) { |
| 33 | + // It would theoretically be cleaner to use @ModifyConstant here, but as it's treated as a @Redirect, it doesn't |
| 34 | + // compose with other mods. Instead, we replace the method when working with our fake player. |
| 35 | + if (player instanceof FakePlayer fp) cir.setReturnValue(getHitResult(level, fp, fluidMode)); |
| 36 | + } |
| 37 | + |
| 38 | + @Unique |
| 39 | + private static BlockHitResult getHitResult(Level level, FakePlayer player, ClipContext.Fluid fluidMode) { |
| 40 | + var start = player.getEyePosition(); |
| 41 | + var reach = player.getBlockReach(); |
| 42 | + var direction = player.getViewVector(1.0f); |
| 43 | + var end = start.add(direction.x() * reach, direction.y() * reach, direction.z() * reach); |
| 44 | + return level.clip(new ClipContext(start, end, ClipContext.Block.OUTLINE, fluidMode, player)); |
31 | 45 | }
|
32 | 46 | }
|
0 commit comments