use of net.minecraft.world.inventory.ContainerListener in project SpongeCommon by SpongePowered.
the class SpongeInventoryMenu method setCurrentInventory.
@Override
public void setCurrentInventory(ViewableInventory inventory) {
if (inventory.getClass().equals(this.inventory.getClass()) && inventory instanceof ViewableCustomInventory && inventory.capacity() == this.inventory.capacity()) {
this.inventory = inventory;
for (Map.Entry<Container, ServerPlayer> entry : this.tracked.entrySet()) {
final net.minecraft.world.inventory.AbstractContainerMenu container = (net.minecraft.world.inventory.AbstractContainerMenu) entry.getKey();
final ServerPlayer player = entry.getValue();
// create a new container for the viewable inventory
final net.minecraft.world.inventory.AbstractContainerMenu newContainer = ((ViewableCustomInventory) inventory).createMenu(-1, ((Player) player).inventory, (Player) player);
for (int i = 0; i < inventory.capacity(); i++) {
// And put its slots into the old container
final Slot slot = newContainer.slots.get(i);
container.slots.set(i, slot);
// Update Container items
((AbstractContainerMenuAccessor) container).accessor$lastSlots().set(i, slot.getItem());
}
// send update to Client
for (ContainerListener listener : ((AbstractContainerMenuAccessor) container).accessor$containerListeners()) {
listener.refreshContainer(container, ((AbstractContainerMenuAccessor) container).accessor$lastSlots());
}
}
} else {
// Get all distinct players and reopen inventory for them
this.inventory = inventory;
this.reopen();
}
}
use of net.minecraft.world.inventory.ContainerListener in project SpongeCommon by SpongePowered.
the class AbstractContainerMenuMixin_Inventory method impl$sendSlotContents.
private void impl$sendSlotContents(final Integer i, final ItemStack oldStack) {
for (final ContainerListener listener : this.containerListeners) {
boolean isChangingQuantityOnly = true;
if (listener instanceof ServerPlayer) {
isChangingQuantityOnly = ((ServerPlayer) listener).ignoreSlotUpdateHack;
((ServerPlayer) listener).ignoreSlotUpdateHack = false;
}
listener.slotChanged(((AbstractContainerMenu) (Object) this), i, oldStack);
if (listener instanceof ServerPlayer) {
((ServerPlayer) listener).ignoreSlotUpdateHack = isChangingQuantityOnly;
}
}
}
use of net.minecraft.world.inventory.ContainerListener in project SpongeCommon by SpongePowered.
the class AbstractContainerMenuMixin_Menu_Inventory method impl$onClick.
// Called when clicking in an inventory
// InventoryMenu Callback
@Inject(method = "doClick", at = @At(value = "HEAD"), cancellable = true)
private void impl$onClick(int slotId, int dragType, ClickType clickTypeIn, Player player, CallbackInfoReturnable<ItemStack> cir) {
final SpongeInventoryMenu menu = this.bridge$getMenu();
if (menu != null) {
if (!menu.onClick(slotId, dragType, clickTypeIn, player, (org.spongepowered.api.item.inventory.Container) this)) {
cir.setReturnValue(ItemStack.EMPTY);
// Accept all changes made by plugin
for (int i = 0; i < this.slots.size(); i++) {
Slot slot = this.slots.get(i);
this.lastSlots.set(i, slot.getItem().copy());
}
// and update client
for (ContainerListener listener : this.containerListeners) {
listener.refreshContainer((AbstractContainerMenu) (Object) this, this.lastSlots);
}
}
}
}
use of net.minecraft.world.inventory.ContainerListener 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();
}
}
Aggregations