add a temporary kludge to make the now-known-to-need-a-revamp pickblock hook work

This commit is contained in:
asie 2019-02-10 17:04:08 +01:00
parent 8eb2bd8e35
commit 0c62493b3f

View file

@ -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;