Search in sources :

Example 1 with CraftingInventory

use of org.spongepowered.api.item.inventory.crafting.CraftingInventory in project SpongeCommon by SpongePowered.

the class MixinSlotCrafting method afterTake.

/**
 * Create CraftItemEvent.Post result is also handled by
 * {@link MixinContainer#redirectTransferStackInSlot} or
 * {@link MixinContainer#redirectOnTakeThrow}
 */
@Inject(method = "onTake", cancellable = true, at = @At("RETURN"))
private void afterTake(EntityPlayer thePlayer, ItemStack stack, CallbackInfoReturnable<ItemStack> cir) {
    if (((IMixinWorld) thePlayer.world).isFake()) {
        return;
    }
    ((IMixinContainer) thePlayer.openContainer).detectAndSendChanges(true);
    ((IMixinContainer) thePlayer.openContainer).setCaptureInventory(false);
    Container container = thePlayer.openContainer;
    Inventory craftInv = ((Inventory) container).query(QueryOperationTypes.INVENTORY_TYPE.of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        SpongeImpl.getLogger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    // retain only last slot-transactions on output slot
    SlotTransaction first = null;
    List<SlotTransaction> capturedTransactions = ((IMixinContainer) container).getCapturedTransactions();
    for (Iterator<SlotTransaction> iterator = capturedTransactions.iterator(); iterator.hasNext(); ) {
        SlotTransaction trans = iterator.next();
        Optional<SlotIndex> slotIndex = trans.getSlot().getInventoryProperty(SlotIndex.class);
        if (slotIndex.isPresent() && slotIndex.get().getValue() == 0) {
            iterator.remove();
            if (first == null) {
                first = trans;
            }
        }
    }
    ItemStackSnapshot craftedItem;
    // if we got a transaction on the crafting-slot use this
    if (first != null) {
        capturedTransactions.add(first);
        craftedItem = first.getOriginal().copy();
    } else {
        if (stack.isEmpty()) {
            // if stack is empty this was probably shift-crafting so we use the captured itemstack instead
            craftedItem = ItemStackUtil.snapshotOf(this.craftedStack);
        } else {
            craftedItem = ItemStackUtil.snapshotOf(stack);
        }
    }
    CraftingInventory craftingInventory = (CraftingInventory) craftInv;
    CraftItemEvent.Craft event = SpongeCommonEventFactory.callCraftEventPost(thePlayer, craftingInventory, craftedItem, this.lastRecipe, container, capturedTransactions);
    ((IMixinContainer) container).setLastCraft(event);
    ((IMixinContainer) container).setFirePreview(true);
    this.craftedStack = null;
    SlotTransaction last = new SlotTransaction(craftingInventory.getResult(), ItemStackSnapshot.NONE, ItemStackUtil.snapshotOf(this.getStack()));
    List<SlotTransaction> previewTransactions = ((IMixinContainer) container).getPreviewTransactions();
    CraftingRecipe newRecipe = Sponge.getRegistry().getCraftingRecipeRegistry().findMatchingRecipe(craftingInventory.getCraftingGrid(), ((World) player.world)).orElse(null);
    SpongeCommonEventFactory.callCraftEventPre(thePlayer, craftingInventory, last, newRecipe, container, previewTransactions);
    previewTransactions.clear();
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) CraftingRecipe(org.spongepowered.api.item.recipe.crafting.CraftingRecipe) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) Container(net.minecraft.inventory.Container) IMixinWorld(org.spongepowered.common.interfaces.world.IMixinWorld) SlotIndex(org.spongepowered.api.item.inventory.property.SlotIndex) CraftItemEvent(org.spongepowered.api.event.item.inventory.CraftItemEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) IInventory(net.minecraft.inventory.IInventory) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 2 with CraftingInventory

use of org.spongepowered.api.item.inventory.crafting.CraftingInventory in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callCraftEventPre.

public static CraftItemEvent.Preview callCraftEventPre(EntityPlayer player, CraftingInventory inventory, SlotTransaction previewTransaction, @Nullable CraftingRecipe recipe, Container container, List<SlotTransaction> transactions) {
    CraftItemEvent.Preview event = SpongeEventFactory.createCraftItemEventPreview(Sponge.getCauseStackManager().getCurrentCause(), inventory, previewTransaction, Optional.ofNullable(recipe), ((Inventory) container), transactions);
    SpongeImpl.postEvent(event);
    PacketPhaseUtil.handleSlotRestore(player, container, new ArrayList<>(transactions), event.isCancelled());
    if (player instanceof EntityPlayerMP) {
        if (event.getPreview().getCustom().isPresent() || event.isCancelled() || !event.getPreview().isValid()) {
            ItemStackSnapshot stack = event.getPreview().getFinal();
            if (event.isCancelled() || !event.getPreview().isValid()) {
                stack = event.getPreview().getOriginal();
            }
            // Resend modified output
            ((EntityPlayerMP) player).connection.sendPacket(new SPacketSetSlot(0, 0, ItemStackUtil.fromSnapshotToNative(stack)));
        }
    }
    return event;
}
Also used : CraftItemEvent(org.spongepowered.api.event.item.inventory.CraftItemEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) IMixinInventory(org.spongepowered.common.interfaces.IMixinInventory) OrderedInventory(org.spongepowered.api.item.inventory.type.OrderedInventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) CarriedInventory(org.spongepowered.api.item.inventory.type.CarriedInventory) Inventory(org.spongepowered.api.item.inventory.Inventory) CustomInventory(org.spongepowered.common.item.inventory.custom.CustomInventory) IInventory(net.minecraft.inventory.IInventory)

Example 3 with CraftingInventory

use of org.spongepowered.api.item.inventory.crafting.CraftingInventory in project SpongeCommon by SpongePowered.

the class PlaceRecipePacketState method unwind.

@Override
public void unwind(InventoryPacketContext context) {
    CPacketPlaceRecipe packet = context.getPacket();
    boolean shift = packet.func_194319_c();
    IRecipe recipe = packet.func_194317_b();
    final EntityPlayerMP player = context.getPacketPlayer();
    ((IMixinContainer) player.openContainer).detectAndSendChanges(true);
    ((IMixinContainer) player.openContainer).setCaptureInventory(false);
    ((IMixinContainer) player.openContainer).setFirePreview(true);
    Inventory craftInv = ((Inventory) player.openContainer).query(QueryOperationTypes.INVENTORY_TYPE.of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        SpongeImpl.getLogger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    List<SlotTransaction> previewTransactions = ((IMixinContainer) player.openContainer).getPreviewTransactions();
    if (previewTransactions.isEmpty()) {
        CraftingOutput slot = ((CraftingInventory) craftInv).getResult();
        SlotTransaction st = new SlotTransaction(slot, ItemStackSnapshot.NONE, ItemStackUtil.snapshotOf(slot.peek().orElse(ItemStack.empty())));
        previewTransactions.add(st);
    }
    SpongeCommonEventFactory.callCraftEventPre(player, ((CraftingInventory) craftInv), previewTransactions.get(0), ((CraftingRecipe) recipe), player.openContainer, previewTransactions);
    previewTransactions.clear();
    final Entity spongePlayer = EntityUtil.fromNative(player);
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        frame.pushCause(spongePlayer);
        frame.pushCause(player.openContainer);
        List<SlotTransaction> transactions = ((IMixinContainer) player.openContainer).getCapturedTransactions();
        ItemStackSnapshot cursor = ItemStackUtil.snapshotOf(player.inventory.getItemStack());
        Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(cursor, cursor);
        ClickInventoryEvent event;
        if (shift) {
            event = SpongeEventFactory.createClickInventoryEventShiftPrimary(frame.getCurrentCause(), cursorTransaction, ((Container) player.openContainer), transactions);
        } else {
            event = SpongeEventFactory.createClickInventoryEventPrimary(frame.getCurrentCause(), cursorTransaction, ((Container) player.openContainer), transactions);
        }
        SpongeImpl.postEvent(event);
        if (event.isCancelled() || !event.getCursorTransaction().isValid()) {
            PacketPhaseUtil.handleCustomCursor(player, event.getCursorTransaction().getOriginal());
        } else {
            PacketPhaseUtil.handleCustomCursor(player, event.getCursorTransaction().getFinal());
        }
        PacketPhaseUtil.handleSlotRestore(player, player.openContainer, event.getTransactions(), event.isCancelled());
        event.getTransactions().clear();
    }
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) Entity(org.spongepowered.api.entity.Entity) IRecipe(net.minecraft.item.crafting.IRecipe) CraftingOutput(org.spongepowered.api.item.inventory.crafting.CraftingOutput) CraftingRecipe(org.spongepowered.api.item.recipe.crafting.CraftingRecipe) ClickInventoryEvent(org.spongepowered.api.event.item.inventory.ClickInventoryEvent) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) CauseStackManager(org.spongepowered.api.event.CauseStackManager) CPacketPlaceRecipe(net.minecraft.network.play.client.CPacketPlaceRecipe) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory)

Example 4 with CraftingInventory

use of org.spongepowered.api.item.inventory.crafting.CraftingInventory in project SpongeCommon by SpongePowered.

the class MixinContainer method afterSlotChangedCraftingGrid.

@Inject(method = "slotChangedCraftingGrid", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetHandlerPlayServer;sendPacket(Lnet/minecraft/network/Packet;)V"))
private void afterSlotChangedCraftingGrid(World world, EntityPlayer player, InventoryCrafting craftingInventory, InventoryCraftResult output, CallbackInfo ci) {
    if (this.firePreview && !this.capturedCraftPreviewTransactions.isEmpty()) {
        Inventory inv = this.query(QueryOperationTypes.INVENTORY_TYPE.of(CraftingInventory.class));
        if (!(inv instanceof CraftingInventory)) {
            SpongeImpl.getLogger().warn("Detected crafting but Sponge could not get a CraftingInventory for " + this.getClass().getName());
            return;
        }
        SlotTransaction previewTransaction = this.capturedCraftPreviewTransactions.get(this.capturedCraftPreviewTransactions.size() - 1);
        IRecipe recipe = CraftingManager.findMatchingRecipe(craftingInventory, world);
        SpongeCommonEventFactory.callCraftEventPre(player, ((CraftingInventory) inv), previewTransaction, ((CraftingRecipe) recipe), ((Container) (Object) this), this.capturedCraftPreviewTransactions);
        this.capturedCraftPreviewTransactions.clear();
    }
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) Container(net.minecraft.inventory.Container) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) PluginContainer(org.spongepowered.api.plugin.PluginContainer) IRecipe(net.minecraft.item.crafting.IRecipe) CraftingRecipe(org.spongepowered.api.item.recipe.crafting.CraftingRecipe) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) CarriedInventory(org.spongepowered.api.item.inventory.type.CarriedInventory) Inventory(org.spongepowered.api.item.inventory.Inventory) IInventory(net.minecraft.inventory.IInventory) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 5 with CraftingInventory

use of org.spongepowered.api.item.inventory.crafting.CraftingInventory in project SpongeCommon by SpongePowered.

the class ServerGamePacketListenerImplMixin_Forge method forge$onPlaceRecipe.

@SuppressWarnings({ "UnresolvedMixinReference", "unchecked", "rawtypes" })
@Redirect(method = "lambda$handlePlaceRecipe$11", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/RecipeBookMenu;handlePlacement(ZLnet/minecraft/world/item/crafting/Recipe;Lnet/minecraft/server/level/ServerPlayer;)V"))
private void forge$onPlaceRecipe(final RecipeBookMenu recipeBookMenu, final boolean shift, final Recipe<?> recipe, final net.minecraft.server.level.ServerPlayer player) {
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    final Inventory craftInv = ((Inventory) player.containerMenu).query(QueryTypes.INVENTORY_TYPE.get().of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        recipeBookMenu.handlePlacement(shift, recipe, player);
        SpongeCommon.logger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    try (final EffectTransactor ignored = transactor.logPlaceRecipe(shift, recipe, player, (CraftingInventory) craftInv)) {
        recipeBookMenu.handlePlacement(shift, recipe, player);
        player.containerMenu.broadcastChanges();
    }
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Aggregations

CraftingInventory (org.spongepowered.api.item.inventory.crafting.CraftingInventory)11 Inventory (org.spongepowered.api.item.inventory.Inventory)9 SlotTransaction (org.spongepowered.api.item.inventory.transaction.SlotTransaction)6 IInventory (net.minecraft.inventory.IInventory)3 Transaction (org.spongepowered.api.data.Transaction)3 Entity (org.spongepowered.api.entity.Entity)3 ItemStackSnapshot (org.spongepowered.api.item.inventory.ItemStackSnapshot)3 CraftingRecipe (org.spongepowered.api.item.recipe.crafting.CraftingRecipe)3 IMixinContainer (org.spongepowered.common.interfaces.IMixinContainer)3 Preconditions.checkState (com.google.common.base.Preconditions.checkState)2 Streams (com.google.common.collect.Streams)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Optional (java.util.Optional)2 Collectors (java.util.stream.Collectors)2 Nullable (javax.annotation.Nullable)2 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)2 Container (net.minecraft.inventory.Container)2 IRecipe (net.minecraft.item.crafting.IRecipe)2 LanternPlayer (org.lanternpowered.server.entity.living.player.LanternPlayer)2