diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/FakePlayerConstants.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/FakePlayerConstants.java
deleted file mode 100644
index a50c8be85..000000000
--- a/projects/common/src/main/java/dan200/computercraft/shared/platform/FakePlayerConstants.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
-//
-// SPDX-License-Identifier: MPL-2.0
-
-package dan200.computercraft.shared.platform;
-
-import com.mojang.authlib.GameProfile;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.item.ItemStack;
-
-/**
- * Shared constants for {@linkplain PlatformHelper#createFakePlayer(ServerLevel, GameProfile) fake player}
- * implementations.
- *
- * @see net.minecraft.server.level.ServerPlayer
- * @see net.minecraft.world.entity.player.Player
- */
-final class FakePlayerConstants {
- private FakePlayerConstants() {
- }
-
- /**
- * The maximum distance this player can reach.
- *
- * This is used in the override of {@link net.minecraft.world.entity.player.Player#mayUseItemAt(BlockPos, Direction, ItemStack)},
- * to prevent the fake player reaching more than 2 blocks away.
- */
- static final double MAX_REACH = 2;
-}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java
index 8288333fd..60f578b7e 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java
@@ -11,8 +11,11 @@
import dan200.computercraft.shared.util.DirectionUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
+import net.minecraft.core.Holder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.entity.ai.attributes.Attribute;
+import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.ItemStack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,6 +31,11 @@ public final class TurtlePlayer {
"[ComputerCraft]"
);
+ /**
+ * The maximum distance this player can reach.
+ */
+ private static final double MAX_REACH = 2;
+
private final ServerPlayer player;
private TurtlePlayer(ServerPlayer player) {
@@ -87,6 +95,15 @@ private void setState(ITurtleAccess turtle) {
setRotation(turtle.getDirection().toYRot(), 0);
player.getInventory().clearContent();
+
+ // Prevent the turtle reaching too far.
+ trySetAttribute(Attributes.BLOCK_INTERACTION_RANGE, MAX_REACH);
+ trySetAttribute(Attributes.ENTITY_INTERACTION_RANGE, MAX_REACH);
+ }
+
+ private void trySetAttribute(Holder attribute, double value) {
+ var instance = player.getAttribute(attribute);
+ if (instance != null) instance.setBaseValue(value);
}
public void setPosition(ITurtleAccess turtle, BlockPos position, Direction direction) {
diff --git a/projects/fabric/src/main/java/dan200/computercraft/mixin/ItemMixin.java b/projects/fabric/src/main/java/dan200/computercraft/mixin/ItemMixin.java
deleted file mode 100644
index 9384c6742..000000000
--- a/projects/fabric/src/main/java/dan200/computercraft/mixin/ItemMixin.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
-//
-// SPDX-License-Identifier: MPL-2.0
-
-package dan200.computercraft.mixin;
-
-import dan200.computercraft.shared.platform.FakePlayer;
-import net.minecraft.world.entity.player.Player;
-import net.minecraft.world.item.Item;
-import net.minecraft.world.level.ClipContext;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.phys.BlockHitResult;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-@Mixin(Item.class)
-class ItemMixin {
- /**
- * Replace the reach distance in {@link Item#getPlayerPOVHitResult(Level, Player, ClipContext.Fluid)}.
- *
- * @param level The current level.
- * @param player The current player.
- * @param fluidMode The current clip-context fluid mode.
- * @param cir Callback info to store the new reach distance.
- * @see FakePlayer#getBlockReach()
- */
- @Inject(method = "getPlayerPOVHitResult", at = @At("HEAD"), cancellable = true)
- @SuppressWarnings("UnusedMethod")
- private static void getReachDistance(Level level, Player player, ClipContext.Fluid fluidMode, CallbackInfoReturnable cir) {
- // It would theoretically be cleaner to use @ModifyConstant here, but as it's treated as a @Redirect, it doesn't
- // compose with other mods. Instead, we replace the method when working with our fake player.
- if (player instanceof FakePlayer fp) cir.setReturnValue(getHitResult(level, fp, fluidMode));
- }
-
- @Unique
- private static BlockHitResult getHitResult(Level level, FakePlayer player, ClipContext.Fluid fluidMode) {
- var start = player.getEyePosition();
- var reach = player.getBlockReach();
- var direction = player.getViewVector(1.0f);
- var end = start.add(direction.x() * reach, direction.y() * reach, direction.z() * reach);
- return level.clip(new ClipContext(start, end, ClipContext.Block.OUTLINE, fluidMode, player));
- }
-}
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakePlayer.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakePlayer.java
index 978970b81..1cbe79ba8 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakePlayer.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakePlayer.java
@@ -12,8 +12,6 @@
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.player.Player;
-import static dan200.computercraft.shared.platform.FakePlayerConstants.MAX_REACH;
-
public final class FakePlayer extends net.fabricmc.fabric.api.entity.FakePlayer {
private static final EntityDimensions DIMENSIONS = EntityDimensions.fixed(0, 0);
@@ -40,11 +38,6 @@ public EntityDimensions getDefaultDimensions(Pose pose) {
return DIMENSIONS;
}
- public double getBlockReach() {
- // TODO: Replace with normal reach attribute
- return MAX_REACH;
- }
-
@Override
public boolean broadcastToPlayer(ServerPlayer player) {
return false;
diff --git a/projects/fabric/src/main/resources/computercraft.fabric.mixins.json b/projects/fabric/src/main/resources/computercraft.fabric.mixins.json
index 91dc2e26b..9cb691ee2 100644
--- a/projects/fabric/src/main/resources/computercraft.fabric.mixins.json
+++ b/projects/fabric/src/main/resources/computercraft.fabric.mixins.json
@@ -11,7 +11,6 @@
"EntityMixin",
"ExplosionDamageCalculatorMixin",
"ItemEntityMixin",
- "ItemMixin",
"PlayerChunkSenderMixin",
"ServerLevelMixin",
"TagEntryAccessor",