Search in sources :

Example 1 with InventoryMenu

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

the class TransactionSink method logSlotTransaction.

/**
 * Called with a created {@link SlotTransaction} that's been created and
 * possibly already recorded by {@link TrackedContainerBridge#bridge$detectAndSendChanges(boolean)}
 * performing transaction handling and submitting to be recorded through
 * here. The caveat with this system is that since it's reliant on having
 * the transactions created as a side effect of {@link AbstractContainerMenu#broadcastChanges()},
 * it's possible that certain transactions are "too late" or remain uncaptured
 * until the next tick.
 *
 * @param phaseContext The context
 * @param newTransaction The slot transaction in relation to the menu
 * @param abstractContainerMenu The container menu
 */
/*
     Non-Javadoc: Known areas where we are keeping transactions recorded:
     - commands - during CommandPhaseContext see below
     - place/use ServerPlayerGameModeMixin_Tracker#useItemOn
     - Dispenser equip PlayerEntityMixin_Inventory#setItemSlot
     - eating etc. LivingEntityMixin_Inventory#completeUsingItem
     - throw/use ServerGamePacketListenerImplMixin_Inventory#impl$onHandleUseItem
     - breaking blocks ServerPlayerGameModeMixin_Tracker#impl$onMineBlock
     - exp pickup with mending PlayerEntityMixin_Inventory#inventory$onTouch
     - attack PlayerMixin#attack
     - armor/shield damage LivingEntityMixin#bridge$damageEntity
     - elytra damage LivingEntityMixin#inventory$onElytraUse
     - consume arrow (BowItem#releaseUsing - shrink on stack) LivingEntityMixin#impl$onStopPlayerUsing
     - villager trade select ServerGamePacketListenerImplMixin_Inventory#impl$onHandleSelectTrade
     - close inventory adding back to inventory ServerPlayerEntityMixin_Inventory#impl$onCloseContainer
     - use on entity - ServerGamePacketListenerImplMixin_Inventory#impl$onInteractAt/impl$onInteractOn
     */
default void logSlotTransaction(final PhaseContext<@NonNull ?> phaseContext, final SlotTransaction newTransaction, final AbstractContainerMenu abstractContainerMenu) {
    // Inventory change during command
    if (abstractContainerMenu instanceof InventoryMenu) {
        if (phaseContext instanceof CommandPhaseContext) {
            this.logPlayerInventoryChange(((InventoryMenuAccessor) abstractContainerMenu).accessor$owner(), PlayerInventoryTransaction.EventCreator.STANDARD);
        }
        if (phaseContext instanceof UnwindingPhaseContext) {
            return;
        }
        if (phaseContext instanceof EntityTickContext) {
            // TODO remove warning when we got all cases covered
            SpongeCommon.logger().warn("Ignoring slot transaction on InventoryMenu during {}. {}\nNo Event will be fired for this", phaseContext.getClass().getSimpleName(), newTransaction);
            return;
        }
    }
    final ContainerSlotTransaction transaction = new ContainerSlotTransaction(abstractContainerMenu, newTransaction);
    this.logTransaction(transaction);
}
Also used : EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) InventoryMenu(net.minecraft.world.inventory.InventoryMenu) CommandPhaseContext(org.spongepowered.common.event.tracking.phase.general.CommandPhaseContext) ContainerSlotTransaction(org.spongepowered.common.event.tracking.context.transaction.inventory.ContainerSlotTransaction) UnwindingPhaseContext(org.spongepowered.common.event.tracking.UnwindingPhaseContext)

Example 2 with InventoryMenu

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

the class CloseMenuTransaction method reopen.

private void reopen(final ServerPlayer player, final AbstractContainerMenu container) {
    if (container.getSlot(0) == null) {
        return;
    }
    if (!(container instanceof InventoryMenu)) {
        // Inventory closed by client, reopen window and send container
        player.containerMenu = container;
        final Slot slot = container.getSlot(0);
        final net.minecraft.world.Container slotInventory = slot.container;
        final net.minecraft.network.chat.@Nullable Component title;
        // TODO get name from last open
        if (slotInventory instanceof MenuProvider) {
            title = ((MenuProvider) slotInventory).getDisplayName();
        } else {
            // expected fallback for unknown types
            title = null;
        }
        slotInventory.startOpen(player);
        player.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), title));
        // resync data to client
        player.refreshContainer(container);
    } else {
    // TODO: Maybe print a warning or throw an exception here?
    // The player gui cannot be opened from the
    // server so allowing this event to be cancellable when the
    // GUI has been closed already would result
    // in opening the wrong GUI window.
    }
}
Also used : InventoryMenu(net.minecraft.world.inventory.InventoryMenu) Slot(net.minecraft.world.inventory.Slot) ClientboundOpenScreenPacket(net.minecraft.network.protocol.game.ClientboundOpenScreenPacket) MenuProvider(net.minecraft.world.MenuProvider) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with InventoryMenu

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

the class RecipeManagerMixin_API method findMatchingRecipe.

@Override
@SuppressWarnings("unchecked")
public Optional<Recipe> findMatchingRecipe(final Inventory inventory, final ServerWorld world) {
    Preconditions.checkNotNull(inventory);
    Preconditions.checkNotNull(world);
    if (inventory instanceof AbstractFurnaceBlockEntity) {
        final net.minecraft.world.item.crafting.RecipeType<? extends AbstractCookingRecipe> type = ((AbstractFurnaceBlockEntityAccessor) inventory).accessor$recipeType();
        return this.<Container, AbstractCookingRecipe>shadow$getRecipeFor((net.minecraft.world.item.crafting.RecipeType<AbstractCookingRecipe>) type, (Container) inventory, (net.minecraft.world.level.Level) world).map(Recipe.class::cast);
    }
    if (inventory instanceof CampfireBlockEntity) {
        return this.shadow$getRecipeFor(net.minecraft.world.item.crafting.RecipeType.CAMPFIRE_COOKING, (Container) inventory, (net.minecraft.world.level.Level) world).map(Recipe.class::cast);
    }
    if (inventory instanceof CraftingMenu) {
        final CraftingContainer craftingInventory = ((CraftingMenuAccessor) inventory).accessor$craftSlots();
        return this.shadow$getRecipeFor(net.minecraft.world.item.crafting.RecipeType.CRAFTING, craftingInventory, (net.minecraft.world.level.Level) world).map(Recipe.class::cast);
    }
    if (inventory instanceof InventoryMenu) {
        final CraftingContainer craftingInventory = ((InventoryMenuAccessor) inventory).accessor$craftSlots();
        return this.shadow$getRecipeFor(net.minecraft.world.item.crafting.RecipeType.CRAFTING, craftingInventory, (net.minecraft.world.level.Level) world).map(Recipe.class::cast);
    }
    if (inventory instanceof StonecutterMenu) {
        final Container stonecutterInventory = ((StonecutterMenu) inventory).container;
        return this.shadow$getRecipeFor(net.minecraft.world.item.crafting.RecipeType.STONECUTTING, stonecutterInventory, (net.minecraft.world.level.Level) world).map(Recipe.class::cast);
    }
    return Optional.empty();
}
Also used : Recipe(org.spongepowered.api.item.recipe.Recipe) CookingRecipe(org.spongepowered.api.item.recipe.cooking.CookingRecipe) AbstractCookingRecipe(net.minecraft.world.item.crafting.AbstractCookingRecipe) CraftingMenu(net.minecraft.world.inventory.CraftingMenu) StonecutterMenu(net.minecraft.world.inventory.StonecutterMenu) InventoryMenuAccessor(org.spongepowered.common.accessor.world.inventory.InventoryMenuAccessor) Container(net.minecraft.world.Container) CraftingContainer(net.minecraft.world.inventory.CraftingContainer) CraftingContainer(net.minecraft.world.inventory.CraftingContainer) InventoryMenu(net.minecraft.world.inventory.InventoryMenu) RecipeType(org.spongepowered.api.item.recipe.RecipeType) AbstractFurnaceBlockEntity(net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity) CampfireBlockEntity(net.minecraft.world.level.block.entity.CampfireBlockEntity) CraftingMenuAccessor(org.spongepowered.common.accessor.world.inventory.CraftingMenuAccessor) AbstractFurnaceBlockEntityAccessor(org.spongepowered.common.accessor.world.level.block.entity.AbstractFurnaceBlockEntityAccessor)

Aggregations

InventoryMenu (net.minecraft.world.inventory.InventoryMenu)3 ClientboundOpenScreenPacket (net.minecraft.network.protocol.game.ClientboundOpenScreenPacket)1 Container (net.minecraft.world.Container)1 MenuProvider (net.minecraft.world.MenuProvider)1 CraftingContainer (net.minecraft.world.inventory.CraftingContainer)1 CraftingMenu (net.minecraft.world.inventory.CraftingMenu)1 Slot (net.minecraft.world.inventory.Slot)1 StonecutterMenu (net.minecraft.world.inventory.StonecutterMenu)1 AbstractCookingRecipe (net.minecraft.world.item.crafting.AbstractCookingRecipe)1 AbstractFurnaceBlockEntity (net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity)1 CampfireBlockEntity (net.minecraft.world.level.block.entity.CampfireBlockEntity)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1 Recipe (org.spongepowered.api.item.recipe.Recipe)1 RecipeType (org.spongepowered.api.item.recipe.RecipeType)1 CookingRecipe (org.spongepowered.api.item.recipe.cooking.CookingRecipe)1 CraftingMenuAccessor (org.spongepowered.common.accessor.world.inventory.CraftingMenuAccessor)1 InventoryMenuAccessor (org.spongepowered.common.accessor.world.inventory.InventoryMenuAccessor)1 AbstractFurnaceBlockEntityAccessor (org.spongepowered.common.accessor.world.level.block.entity.AbstractFurnaceBlockEntityAccessor)1 UnwindingPhaseContext (org.spongepowered.common.event.tracking.UnwindingPhaseContext)1 ContainerSlotTransaction (org.spongepowered.common.event.tracking.context.transaction.inventory.ContainerSlotTransaction)1