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