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();
}
}
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;
}
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));
}
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);
});
}
}
}
Aggregations