diff --git a/src/main/java/com/cleanroommc/neverenoughanimations/animations/SwapHolder.java b/src/main/java/com/cleanroommc/neverenoughanimations/animations/SwapHolder.java new file mode 100644 index 0000000..eda1b15 --- /dev/null +++ b/src/main/java/com/cleanroommc/neverenoughanimations/animations/SwapHolder.java @@ -0,0 +1,103 @@ +package com.cleanroommc.neverenoughanimations.animations; + +import com.cleanroommc.neverenoughanimations.IItemLocation; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.SlotItemHandler; +import net.minecraftforge.items.wrapper.PlayerInvWrapper; +import net.minecraftforge.items.wrapper.PlayerMainInvWrapper; + +import java.util.List; + +public class SwapHolder { + + public static final SwapHolder INSTANCE = new SwapHolder(); + + private Slot targetSlot; + private Slot hotbarSlot; + private ItemStack targetStack; + private ItemStack hotbarStack; + + public boolean init(Slot hoveredSlot, List slots, int hotbarIndex) { + this.targetSlot = hoveredSlot; + this.hotbarSlot = findHotbarSlot(slots, hotbarIndex); + if (this.hotbarSlot == null) { + reset(); + return false; + } + this.targetStack = this.targetSlot.getStack(); + this.hotbarStack = this.hotbarSlot.getStack(); + if (this.targetStack.isEmpty() && this.hotbarStack.isEmpty()) { + reset(); + return false; + } + this.targetStack = this.targetStack.copy(); + this.hotbarStack = this.hotbarStack.copy(); + return true; + } + + public void performSwap() { + IItemLocation hotbar = IItemLocation.of(this.hotbarSlot); + IItemLocation hovering = IItemLocation.of(this.targetSlot); + long time = Minecraft.getSystemTime(); + if (this.targetStack.isEmpty()) { + if (!hovering.nea$getStack().isEmpty()) { + ItemMoveAnimation.queueAnimation(hotbar.nea$getSlotNumber(), + new ItemMovePacket(time, hotbar, hovering, hovering.nea$getStack().copy())); + ItemMoveAnimation.updateVirtualStack(hovering.nea$getSlotNumber(), ItemStack.EMPTY, 1); + } + } else if (this.hotbarStack.isEmpty()) { + if (!hotbar.nea$getStack().isEmpty()) { + ItemMoveAnimation.queueAnimation(hovering.nea$getSlotNumber(), + new ItemMovePacket(time, hovering, hotbar, hotbar.nea$getStack().copy())); + ItemMoveAnimation.updateVirtualStack(hotbar.nea$getSlotNumber(), ItemStack.EMPTY, 1); + } + } else { + ItemMoveAnimation.queueAnimation(hotbar.nea$getSlotNumber(), + new ItemMovePacket(time, hotbar, hovering, hovering.nea$getStack().copy())); + ItemMoveAnimation.queueAnimation(hovering.nea$getSlotNumber(), + new ItemMovePacket(time, hovering, hotbar, hotbar.nea$getStack().copy())); + ItemMoveAnimation.updateVirtualStack(hovering.nea$getSlotNumber(), ItemStack.EMPTY, 1); + ItemMoveAnimation.updateVirtualStack(hotbar.nea$getSlotNumber(), ItemStack.EMPTY, 1); + } + reset(); + } + + public void reset() { + this.targetSlot = null; + this.hotbarSlot = null; + this.targetStack = null; + this.hotbarStack = null; + } + + public ItemStack getTargetStack() { + return targetStack; + } + + public ItemStack getHotbarStack() { + return hotbarStack; + } + + public Slot getHotbarSlot() { + return hotbarSlot; + } + + public Slot getTargetSlot() { + return targetSlot; + } + + public static Slot findHotbarSlot(List slots, int index) { + for (Slot slot : slots) { + if (slot.getSlotIndex() != index) continue; + if (slot.inventory instanceof InventoryPlayer || + (slot instanceof SlotItemHandler slotItemHandler && + (slotItemHandler.getItemHandler() instanceof PlayerMainInvWrapper || + slotItemHandler.getItemHandler() instanceof PlayerInvWrapper))) { + return slot; + } + } + return null; + } +} diff --git a/src/main/java/com/cleanroommc/neverenoughanimations/core/mixin/ContainerMixin.java b/src/main/java/com/cleanroommc/neverenoughanimations/core/mixin/ContainerMixin.java index 9450e1a..eeb2075 100644 --- a/src/main/java/com/cleanroommc/neverenoughanimations/core/mixin/ContainerMixin.java +++ b/src/main/java/com/cleanroommc/neverenoughanimations/core/mixin/ContainerMixin.java @@ -4,6 +4,7 @@ import com.cleanroommc.neverenoughanimations.NEAConfig; import com.cleanroommc.neverenoughanimations.animations.ItemMoveAnimation; import com.cleanroommc.neverenoughanimations.animations.ItemMovePacket; +import com.cleanroommc.neverenoughanimations.animations.SwapHolder; import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalRef; @@ -37,7 +38,8 @@ public abstract class ContainerMixin { public abstract ItemStack transferStackInSlot(EntityPlayer playerIn, int index); @Inject(method = "slotClick", at = @At("HEAD"), cancellable = true) - public void slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player, CallbackInfoReturnable cir) { + public void slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player, CallbackInfoReturnable cir, + @Share("swapHolder") LocalRef swapHolder) { if (player == null || player.world == null || !player.world.isRemote) return; if (clickTypeIn == ClickType.QUICK_MOVE && (dragType == 0 || dragType == 1) && dragEvent == 0 && slotId != -999) { if (slotId < 0) { @@ -65,6 +67,19 @@ public void slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPla } if (candidates != null) ItemMoveAnimation.handleMove(slot5, oldStack, candidates); cir.setReturnValue(itemstack); + } else if (clickTypeIn == ClickType.SWAP && dragType >= 0 && dragType < 9) { + Slot targetSlot = this.inventorySlots.get(slotId); + if (SwapHolder.INSTANCE.init(targetSlot, this.inventorySlots, dragType)) { + swapHolder.set(SwapHolder.INSTANCE); + } + } + } + + @Inject(method = "slotClick", at = @At("TAIL")) + public void slotClickPost(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player, CallbackInfoReturnable cir, + @Share("swapHolder") LocalRef swapHolder) { + if (swapHolder.get() != null) { + swapHolder.get().performSwap(); } }