forked from FabricMC/fabric
add a temporary kludge to make the now-known-to-need-a-revamp pickblock hook work
This commit is contained in:
parent
8eb2bd8e35
commit
0c62493b3f
1 changed files with 65 additions and 1 deletions
|
@ -17,20 +17,84 @@
|
|||
package net.fabricmc.fabric.mixin.events.playerinteraction;
|
||||
|
||||
import net.fabricmc.fabric.api.event.client.player.ClientPickBlockCallback;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Screen;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
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.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(MinecraftClient.class)
|
||||
public class MixinMinecraftClient {
|
||||
public abstract class MixinMinecraftClient {
|
||||
private boolean fabric_itemPickSucceeded;
|
||||
private boolean fabric_itemPickCancelled;
|
||||
|
||||
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;doItemPick()V"), method = "method_1508")
|
||||
private void sillyRedirection() {
|
||||
fabric_doItemPickWrapper();
|
||||
}
|
||||
|
||||
private void fabric_doItemPickWrapper() {
|
||||
// I HATE EVERYTHING THAT STANDS FOR THIS CODE
|
||||
fabric_itemPickSucceeded = false;
|
||||
doItemPick();
|
||||
if (!fabric_itemPickSucceeded) {
|
||||
// vanilla method bailed early, so we have to do this absurd kludge
|
||||
ClientPickBlockCallback.Container ctr = new ClientPickBlockCallback.Container(ItemStack.EMPTY);
|
||||
//noinspection ConstantConditions
|
||||
MinecraftClient client = (MinecraftClient) (Object) this;
|
||||
|
||||
if (ClientPickBlockCallback.EVENT.invoker().pick(client.player, client.hitResult, ctr)) {
|
||||
// we cannot just jump into the middle of doItemPick, so we have to
|
||||
// mimic vanilla logic here
|
||||
|
||||
ItemStack stack = ctr.getStack();
|
||||
PlayerInventory playerInventory = client.player.inventory;
|
||||
|
||||
if (client.player.abilities.creativeMode && Screen.isControlPressed() && client.hitResult.getType() == HitResult.Type.BLOCK) {
|
||||
BlockEntity be = client.world.getBlockEntity(((BlockHitResult) client.hitResult).getBlockPos());
|
||||
if (be != null) {
|
||||
stack = addBlockEntityNbt(stack, be);
|
||||
}
|
||||
}
|
||||
|
||||
if (client.player.abilities.creativeMode) {
|
||||
playerInventory.addPickBlock(stack);
|
||||
client.interactionManager.method_2909(client.player.getStackInHand(Hand.MAIN), 36 + playerInventory.selectedSlot);
|
||||
} else {
|
||||
int slot = playerInventory.getSlotWithStack(stack);
|
||||
if (slot >= 0) {
|
||||
if (PlayerInventory.isValidHotbarIndex(slot)) {
|
||||
playerInventory.selectedSlot = slot;
|
||||
} else {
|
||||
client.interactionManager.pickFromInventory(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract void doItemPick();
|
||||
@Shadow
|
||||
public abstract ItemStack addBlockEntityNbt(ItemStack itemStack_1, BlockEntity blockEntity_1);
|
||||
|
||||
@ModifyVariable(at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isEmpty()Z", ordinal = 2), method = "doItemPick", ordinal = 0)
|
||||
public ItemStack modifyItemPick(ItemStack stack) {
|
||||
fabric_itemPickSucceeded = true;
|
||||
|
||||
ClientPickBlockCallback.Container ctr = new ClientPickBlockCallback.Container(stack);
|
||||
//noinspection ConstantConditions
|
||||
MinecraftClient client = (MinecraftClient) (Object) this;
|
||||
|
|
Loading…
Reference in a new issue