nageyqma·git
HTTPS https://git.nageyqma.icu/nageyqma/blade-addons-next.git SSH git@git.nageyqma.icu:nageyqma/blade-addons-next.git

HTTPS 链接可直接 git clone;推送代码请使用 SSH。

4.9 KB · 110 行raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
package blade.addon.mixin;

import blade.addon.features.item.ProtectItem;
import blade.addon.features.other.SearchBar;
import blade.addon.utils.events.Events;
import blade.addon.utils.rendering.DrawEvents;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.input.MouseButtonEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerInput;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(AbstractContainerScreen.class)
public abstract class AbstractContainerScreenMixin<T extends AbstractContainerMenu> extends Screen {

    @Shadow
    @Final
    protected T menu;
    @Unique
    private static final int INVALID_SLOT_ID = -999;

    protected AbstractContainerScreenMixin(Component title) {
        super(title);
    }

    @Inject(method = "extractRenderState", at = @At("TAIL"))
    private static void render(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float deltaTicks, CallbackInfo ci) {
        SearchBar.render(graphics, mouseX, mouseY, deltaTicks);
    }

    //"Lnet/minecraft/client/gui/GuiGraphics;renderItem(Lnet/minecraft/world/item/ItemStack;III)V"
    @Inject(method = "extractSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphicsExtractor;item(Lnet/minecraft/world/item/ItemStack;III)V"))
    public void drawBackground(GuiGraphicsExtractor graphics, Slot slot, int mouseX, int mouseY, CallbackInfo ci) {
        int x = slot.x;
        int y = slot.y;
        ItemStack stack = slot.getItem();
        DrawEvents.INVENTORY_SLOT_BEFORE.invoke(event -> event.draw(graphics, stack, x, y));
    }

    @Inject(method = "extractSlot", at = @At(value = "TAIL"))
    public void drawStarCount(GuiGraphicsExtractor graphics, Slot slot, int mouseX, int mouseY, CallbackInfo ci) {
        int x = slot.x;
        int y = slot.y;
        ItemStack stack = slot.getItem();
        DrawEvents.INVENTORY_SLOT_AFTER.invoke(event -> event.draw(graphics, stack, x, y));
    }

    @Inject(method = "keyPressed", at = @At("HEAD"), cancellable = true)
    private void keyPressed(KeyEvent input, CallbackInfoReturnable<Boolean> cir) {
        if (SearchBar.keyPressed(input)) cir.setReturnValue(false);
    }

    @Inject(method = "mouseClicked", at = @At("HEAD"))
    private void onMouseClick(MouseButtonEvent click, boolean doubled, CallbackInfoReturnable<Boolean> cir) {
        SearchBar.onMouseClick(click);
    }

    // 26.3 added a private slotClicked(Slot, int, MouseButtonEvent, ContainerInput) overload, so the
    // descriptor of the vanilla protected entry point has to be spelled out to stay unambiguous.
    @Inject(method = "slotClicked(Lnet/minecraft/world/inventory/Slot;IILnet/minecraft/world/inventory/ContainerInput;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;onMouseClickAction(Lnet/minecraft/world/inventory/Slot;Lnet/minecraft/world/inventory/ContainerInput;)V"), cancellable = true)
    public void protectItem(Slot slot, int slotId, int buttonNum, ContainerInput containerInput, CallbackInfo ci) {

        ItemStack held = menu.getCarried();

        if (slotId == INVALID_SLOT_ID && ProtectItem.protect(held)) {
            ci.cancel();
            return;
        }

        if (containerInput == ContainerInput.THROW && slot != null) {
            if (ProtectItem.protect(slot.getItem())) {
                ci.cancel();
                return;
            }
        }

        AbstractContainerScreen screen = (AbstractContainerScreen) (Object) this;
        if (slot != null) {
            if (ProtectItem.blockGUI(screen, slot.getItem())) {
                ci.cancel();
            }
        }
    }

    @Inject(method = "slotClicked(Lnet/minecraft/world/inventory/Slot;IILnet/minecraft/world/inventory/ContainerInput;)V", at = @At("HEAD"), cancellable = true)
    public void slotClicked(Slot slot, int slotId, int buttonNum, ContainerInput containerInput, CallbackInfo ci) {
        if (Events.ON_SLOT_CLICKED.invoke(slotEvent -> slotEvent.onSlot(slot, slotId, buttonNum, containerInput, this))) {
            ci.cancel();
        }
    }

    @Inject(method = "init", at = @At("HEAD"))
    public void init(CallbackInfo ci) {
        Events.ON_SCREEN.invoke(screenEvent -> screenEvent.onScreen(this));
    }
}