Search in sources :

Example 11 with AbstractContainerMenu

use of net.minecraft.world.inventory.AbstractContainerMenu in project SpongeCommon by SpongePowered.

the class AbstractContainerMenuMixin_Inventory method bridge$detectAndSendChanges.

@Override
public void bridge$detectAndSendChanges(final boolean captureOnly) {
    // Code-Flow changed from vanilla completely!
    final SpongeInventoryMenu menu = ((MenuBridge) this).bridge$getMenu();
    // We first collect all differences and check if cancelled for readonly menu changes
    final List<Integer> changes = new ArrayList<>();
    for (int i = 0; i < this.slots.size(); ++i) {
        final Slot slot = this.slots.get(i);
        final ItemStack newStack = slot.getItem();
        final ItemStack oldStack = this.lastSlots.get(i);
        if (!ItemStack.matches(oldStack, newStack)) {
            changes.add(i);
        }
    }
    // For each change
    for (final Integer i : changes) {
        final Slot slot = this.slots.get(i);
        final ItemStack newStack = slot.getItem();
        ItemStack oldStack = this.lastSlots.get(i);
        // Only call Menu Callbacks when clicking
        if (this.impl$isClicking && menu != null && !menu.onChange(newStack, oldStack, (org.spongepowered.api.item.inventory.Container) this, i, slot)) {
            // revert changes
            this.lastSlots.set(i, oldStack.copy());
            // Send reverted slots to clients
            this.impl$sendSlotContents(i, oldStack);
        } else {
            // Capture changes for inventory events
            this.impl$capture(i, newStack, oldStack);
            if (captureOnly) {
                continue;
            }
            // Perform vanilla logic - updating inventory stack - notify listeners
            oldStack = newStack.isEmpty() ? ItemStack.EMPTY : newStack.copy();
            this.lastSlots.set(i, oldStack);
            // TODO forge checks !itemstack1.equals(itemstack, true) before doing this
            for (final ContainerListener listener : this.containerListeners) {
                listener.slotChanged(((AbstractContainerMenu) (Object) this), i, oldStack);
            }
        }
    }
    // like vanilla send property changes
    this.impl$detectAndSendPropertyChanges();
    if (this instanceof InventoryMenuBridge) {
        ((InventoryMenuBridge) this).bridge$markClean();
    }
}
Also used : InventoryMenuBridge(org.spongepowered.common.bridge.world.inventory.InventoryMenuBridge) MenuBridge(org.spongepowered.common.bridge.world.inventory.container.MenuBridge) ArrayList(java.util.ArrayList) AbstractContainerMenu(net.minecraft.world.inventory.AbstractContainerMenu) InventoryMenuBridge(org.spongepowered.common.bridge.world.inventory.InventoryMenuBridge) ResultSlot(net.minecraft.world.inventory.ResultSlot) DataSlot(net.minecraft.world.inventory.DataSlot) Slot(net.minecraft.world.inventory.Slot) ContainerListener(net.minecraft.world.inventory.ContainerListener) SpongeInventoryMenu(org.spongepowered.common.inventory.custom.SpongeInventoryMenu) ItemStack(net.minecraft.world.item.ItemStack)

Example 12 with AbstractContainerMenu

use of net.minecraft.world.inventory.AbstractContainerMenu in project SpongeCommon by SpongePowered.

the class ResultSlotMixin_Inventory method impl$afterTake.

@Inject(method = "onTake", cancellable = true, at = @At("RETURN"))
private void impl$afterTake(final Player thePlayer, final ItemStack stack, final CallbackInfoReturnable<ItemStack> cir) {
    if (((LevelBridge) thePlayer.level).bridge$isFake()) {
        return;
    }
    final AbstractContainerMenu container = thePlayer.containerMenu;
    final Inventory craftInv = ((Inventory) container).query(QueryTypes.INVENTORY_TYPE.get().of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        SpongeCommon.logger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    transactor.logCrafting(thePlayer, this.impl$craftedStack, (CraftingInventory) craftInv, this.impl$onTakeRecipe);
    this.impl$craftedStack = null;
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) LevelBridge(org.spongepowered.common.bridge.world.level.LevelBridge) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) AbstractContainerMenu(net.minecraft.world.inventory.AbstractContainerMenu) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 13 with AbstractContainerMenu

use of net.minecraft.world.inventory.AbstractContainerMenu in project MinecraftForge by MinecraftForge.

the class NetworkHooks method openGui.

/**
 * Request to open a GUI on the client, from the server
 *
 * Refer to {@link ConfigGuiFactory} for how to provide a function to consume
 * these GUI requests on the client.
 *
 * The maximum size for #extraDataWriter is 32600 bytes.
 *
 * @param player The player to open the GUI for
 * @param containerSupplier A supplier of container properties including the registry name of the container
 * @param extraDataWriter Consumer to write any additional data the GUI needs
 */
public static void openGui(ServerPlayer player, MenuProvider containerSupplier, Consumer<FriendlyByteBuf> extraDataWriter) {
    if (player.level.isClientSide)
        return;
    player.doCloseContainer();
    player.nextContainerCounter();
    int openContainerId = player.containerCounter;
    FriendlyByteBuf extraData = new FriendlyByteBuf(Unpooled.buffer());
    extraDataWriter.accept(extraData);
    // reset to beginning in case modders read for whatever reason
    extraData.readerIndex(0);
    FriendlyByteBuf output = new FriendlyByteBuf(Unpooled.buffer());
    output.writeVarInt(extraData.readableBytes());
    output.writeBytes(extraData);
    if (output.readableBytes() > 32600 || output.readableBytes() < 1) {
        throw new IllegalArgumentException("Invalid PacketBuffer for openGui, found " + output.readableBytes() + " bytes");
    }
    AbstractContainerMenu c = containerSupplier.createMenu(openContainerId, player.getInventory(), player);
    MenuType<?> type = c.getType();
    PlayMessages.OpenContainer msg = new PlayMessages.OpenContainer(type, openContainerId, containerSupplier.getDisplayName(), output);
    NetworkConstants.playChannel.sendTo(msg, player.connection.getConnection(), NetworkDirection.PLAY_TO_CLIENT);
    player.containerMenu = c;
    player.initMenu(player.containerMenu);
    MinecraftForge.EVENT_BUS.post(new PlayerContainerEvent.Open(player, c));
}
Also used : FriendlyByteBuf(net.minecraft.network.FriendlyByteBuf) AbstractContainerMenu(net.minecraft.world.inventory.AbstractContainerMenu) PlayerContainerEvent(net.minecraftforge.event.entity.player.PlayerContainerEvent)

Example 14 with AbstractContainerMenu

use of net.minecraft.world.inventory.AbstractContainerMenu in project MinecraftForge by MinecraftForge.

the class ContainerTypeTest method onRightClick.

private void onRightClick(PlayerInteractEvent.RightClickBlock event) {
    if (!event.getWorld().isClientSide && event.getHand() == InteractionHand.MAIN_HAND) {
        if (event.getWorld().getBlockState(event.getPos()).getBlock() == Blocks.SPONGE) {
            String text = "Hello World!";
            NetworkHooks.openGui((ServerPlayer) event.getPlayer(), new MenuProvider() {

                @Override
                public AbstractContainerMenu createMenu(int p_createMenu_1_, Inventory p_createMenu_2_, Player p_createMenu_3_) {
                    SimpleContainer inv = new SimpleContainer(9);
                    for (int i = 0; i < inv.getContainerSize(); i++) {
                        inv.setItem(i, new ItemStack(Items.DIAMOND));
                    }
                    return new TestContainer(p_createMenu_1_, inv, text);
                }

                @Override
                public Component getDisplayName() {
                    return new TextComponent("Test");
                }
            }, extraData -> {
                extraData.writeUtf(text);
            });
        }
    }
}
Also used : TextComponent(net.minecraft.network.chat.TextComponent) ServerPlayer(net.minecraft.server.level.ServerPlayer) Player(net.minecraft.world.entity.player.Player) AbstractContainerMenu(net.minecraft.world.inventory.AbstractContainerMenu) SimpleContainer(net.minecraft.world.SimpleContainer) ItemStack(net.minecraft.world.item.ItemStack) Component(net.minecraft.network.chat.Component) TextComponent(net.minecraft.network.chat.TextComponent) MenuProvider(net.minecraft.world.MenuProvider) Inventory(net.minecraft.world.entity.player.Inventory)

Aggregations

AbstractContainerMenu (net.minecraft.world.inventory.AbstractContainerMenu)14 ServerPlayer (net.minecraft.server.level.ServerPlayer)5 ItemStack (net.minecraft.world.item.ItemStack)4 Inventory (org.spongepowered.api.item.inventory.Inventory)4 TextComponent (net.minecraft.network.chat.TextComponent)3 MenuProvider (net.minecraft.world.MenuProvider)3 ArrayList (java.util.ArrayList)2 Optional (java.util.Optional)2 ClientboundOpenScreenPacket (net.minecraft.network.protocol.game.ClientboundOpenScreenPacket)2 Player (net.minecraft.world.entity.player.Player)2 ContainerListener (net.minecraft.world.inventory.ContainerListener)2 CarriedInventory (org.spongepowered.api.item.inventory.type.CarriedInventory)2 TransactionalCaptureSupplier (org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier)2 Lens (org.spongepowered.common.inventory.lens.Lens)2 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 OptionalInt (java.util.OptionalInt)1 Supplier (java.util.function.Supplier)1