Skip to content

Commit

Permalink
Merge pull request #212 from lonefelidae16/refactor/reacharound
Browse files Browse the repository at this point in the history
[refactor] reacharound placement feature
  • Loading branch information
juancarloscp52 committed Jan 29, 2023
2 parents 9ce0e7a + 62ed229 commit 40cae82
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.entity.Entity;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Direction;
import org.joml.Vector3f;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.NotNull;

import static net.minecraft.client.gui.DrawableHelper.fill;

Expand All @@ -28,17 +25,51 @@ public void renderIndicator(MatrixStack matrixStack) {
}
}

private boolean canReachAround() {
public boolean canReachAround() {
if (client.player == null || client.world == null || client.crosshairTarget == null)
return false;
return (client.player.isSneaking() || !BedrockifyClient.getInstance().settings.isReacharoundSneakingEnabled()) && client.player.getPitch() > BedrockifyClient.getInstance().settings.getReacharoundPitchAngle() && (!(client.world.getBlockState(client.player.getBlockPos().down()).isAir() || client.world.getBlockState(client.player.getBlockPos().down()).getBlock() instanceof FluidBlock) || isNonFullBlock()) && client.crosshairTarget.getType().equals(HitResult.Type.MISS) && checkRelativeBlockPosition() && ((client.world.getBlockState(client.player.getBlockPos().down().offset(client.player.getHorizontalFacing())).getBlock() instanceof FluidBlock) || (client.world.getBlockState(client.player.getBlockPos().down().offset(client.player.getHorizontalFacing())).getBlock() instanceof AirBlock));
}

private boolean isNonFullBlock(){
if(client.world == null || client.player == null)
// crosshairTarget must be MISS.
if (!client.crosshairTarget.getType().equals(HitResult.Type.MISS)) {
return false;
}

final ClientPlayerEntity player = client.player;
final BlockPos targetPos = getFacingSteppingBlockPos(player);

// Not sneaking and must sneak in settings.
if (!player.isSneaking() && BedrockifyClient.getInstance().settings.isReacharoundSneakingEnabled()) {
return false;
Block playerPosBlock = client.world.getBlockState(client.player.getBlockPos()).getBlock();
return playerPosBlock instanceof SoulSandBlock || playerPosBlock instanceof MudBlock || playerPosBlock instanceof SlabBlock || playerPosBlock instanceof StairsBlock || playerPosBlock instanceof ChainBlock || playerPosBlock instanceof EndRodBlock || playerPosBlock instanceof BedBlock || playerPosBlock instanceof SkullBlock || playerPosBlock instanceof StonecutterBlock || playerPosBlock instanceof AbstractChestBlock;
}
// Player may be flying, climbing the ladder or vines, or on the Fluid with sneaking.
if (!player.isOnGround() || !isSolidBlock(client.world.getBlockState(player.getSteppingPos()))) {
return false;
}
// There is already a block at the ReachAround target position.
if (isSolidBlock(client.world.getBlockState(targetPos))) {
return false;
}

return player.getPitch() > BedrockifyClient.getInstance().settings.getReacharoundPitchAngle() && checkRelativeBlockPosition();
}

/**
* Helper method that retrieves Reach-Around block position.
*
* @return The position of the block to be placed.
*/
public static BlockPos getFacingSteppingBlockPos(@NotNull Entity player) {
return player.getSteppingPos().offset(player.getHorizontalFacing());
}

/**
* Helper method that checks the BlockState is not AIR and FLUIDS.
*
* @param blockState The target blockState.
* @return <code>true</code> if the block is not AIR and FLUIDS.
*/
private static boolean isSolidBlock(@NotNull BlockState blockState) {
return !blockState.isAir() && !(blockState.getBlock() instanceof FluidBlock);
}

private boolean checkRelativeBlockPosition() {
Expand All @@ -56,30 +87,4 @@ private boolean checkRelativeBlockPosition(double pos, float direction) {
}
return false;
}

public void checkReachAroundAndExecute(Hand hand, ItemStack itemStack) {
ClientPlayerEntity player = client.player;
if (player == null || client.interactionManager == null)
return;
int count = itemStack.getCount();
Vector3f facing = player.getHorizontalFacing().getUnitVector();
if (canReachAround()) {
BlockHitResult blockHitResult;
if(isNonFullBlock()){
blockHitResult = new BlockHitResult(player.getPos().add(facing.x(), facing.y()-1, facing.z()), Direction.fromVector((int) -facing.x(), 0, (int) -facing.z()), player.getBlockPos().offset(player.getHorizontalFacing()), false);
}else{
blockHitResult = new BlockHitResult(player.getPos().add(facing.x(), facing.y(), facing.z()), Direction.fromVector((int) -facing.x(), 0, (int) -facing.z()), player.getBlockPos().down().offset(player.getHorizontalFacing()), false);
}
ActionResult result = client.interactionManager.interactBlock(player, hand, blockHitResult);
if (result.isAccepted()) {
if (result.shouldSwingHand()) {
player.swingHand(hand);
if (!itemStack.isEmpty() && (itemStack.getCount() != count || client.interactionManager.hasCreativeInventory())) {
client.gameRenderer.firstPersonRenderer.resetEquipProgress(hand);
}
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,30 @@


import me.juancarloscp52.bedrockify.client.BedrockifyClient;
import me.juancarloscp52.bedrockify.client.features.reacharoundPlacement.ReachAroundPlacement;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.thread.ReentrantThreadExecutor;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;


@Mixin(MinecraftClient.class)
public abstract class MinecraftClientMixin extends ReentrantThreadExecutor<Runnable> {

@Shadow public ClientPlayerEntity player;
@Shadow public abstract boolean isInSingleplayer();
@Shadow
public ClientPlayerEntity player;
@Shadow
@Nullable
public HitResult crosshairTarget;
@Shadow
public abstract boolean isInSingleplayer();

public MinecraftClientMixin(String string) {
super(string);
Expand All @@ -27,13 +35,19 @@ public MinecraftClientMixin(String string) {
/**
* Allows the player to use the reachAround placement feature if enabled.
*/
@Redirect(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;"))
private ItemStack onItemUse(ClientPlayerEntity player, Hand hand) {
ItemStack itemStack = this.player.getStackInHand(hand);

if (BedrockifyClient.getInstance().settings.isReacharoundEnabled() && (isInSingleplayer() || BedrockifyClient.getInstance().settings.isReacharoundMultiplayerEnabled()))
BedrockifyClient.getInstance().reachAroundPlacement.checkReachAroundAndExecute(hand, itemStack);

return itemStack;
@Inject(method = "doItemUse", at = @At("HEAD"))
private void bedrockify$modifyCrosshairTarget(CallbackInfo ci) {
if (this.player == null) {
return;
}
if (!BedrockifyClient.getInstance().settings.isReacharoundEnabled() || (!isInSingleplayer() && !BedrockifyClient.getInstance().settings.isReacharoundMultiplayerEnabled())) {
return;
}

if (BedrockifyClient.getInstance().reachAroundPlacement.canReachAround()) {
final ClientPlayerEntity player = this.player;
final BlockPos targetPos = ReachAroundPlacement.getFacingSteppingBlockPos(player);
this.crosshairTarget = new BlockHitResult(player.getPos(), player.getHorizontalFacing(), targetPos, false);
}
}
}

0 comments on commit 40cae82

Please sign in to comment.