diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index fab87347..181fd53d 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -28,6 +28,7 @@ import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar; import com.minelittlepony.unicopia.item.FriendshipBraceletItem; import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.util.*; import com.minelittlepony.unicopia.network.*; @@ -39,7 +40,6 @@ import com.minelittlepony.common.util.animation.Interpolator; import com.mojang.authlib.GameProfile; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.*; import net.minecraft.entity.attribute.DefaultAttributeContainer; @@ -919,7 +919,7 @@ public class Pony extends Living implements Copyable, Update PlayerInventory inventory = oldPlayer.asEntity().getInventory(); for (int i = 0; i < inventory.size(); i++) { ItemStack stack = inventory.getStack(i); - if (EnchantmentHelper.getLevel(UEnchantments.HEART_BOUND, stack) > 0) { + if (EnchantmentUtil.consumeEnchantment(UEnchantments.HEART_BOUND, 1, stack, entity.getWorld().random, EnchantmentUtil.getLuck(3, oldPlayer.asEntity()))) { asEntity().getInventory().setStack(i, stack); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java index 5bc6d8f2..f518d5d3 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java @@ -16,6 +16,7 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.random.Random; public interface EnchantmentUtil { + String HEART_BOUND_CONSUMED_FLAG = "unicopia:heart_bound_consumed"; static boolean consumeEnchantment(Enchantment enchantment, int levels, ItemStack stack) { return consumeEnchantment(enchantment, levels, stack, null, 0); @@ -33,7 +34,7 @@ public interface EnchantmentUtil { if (level == 0) { enchantments.remove(enchantment); } else { - enchantments.put(enchantment, level - 1); + enchantments.put(enchantment, level); } EnchantmentHelper.set(enchantments, stack); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/HeartboundEnchantmentUtil.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/HeartboundEnchantmentUtil.java new file mode 100644 index 00000000..b27dd3ad --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/HeartboundEnchantmentUtil.java @@ -0,0 +1,51 @@ +package com.minelittlepony.unicopia.item.enchantment; + +import java.util.List; + +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.enchantment.Enchantments; +import net.minecraft.item.ItemStack; +import net.minecraft.util.collection.DefaultedList; + +public interface HeartboundEnchantmentUtil { + static InventorySnapshot createSnapshot(List> combinedInventory) { + List> storedCombinedInventory = combinedInventory.stream().map(l -> DefaultedList.ofSize(l.size(), ItemStack.EMPTY)).toList(); + boolean empty = true; + for (int group = 0; group < combinedInventory.size(); group++) { + var original = combinedInventory.get(group); + for (int i = 0; i < original.size(); i++) { + ItemStack stack = original.get(i); + if (EnchantmentHelper.getLevel(Enchantments.BINDING_CURSE, stack) == 0 + && EnchantmentHelper.getLevel(UEnchantments.HEART_BOUND, stack) > 0) { + original.set(i, ItemStack.EMPTY); + storedCombinedInventory.get(group).set(i, stack); + empty = false; + } + } + } + return empty ? InventorySnapshot.EMPTY : new InventorySnapshot(storedCombinedInventory); + } + + public record InventorySnapshot(List> combinedInventory) { + public static InventorySnapshot EMPTY = new InventorySnapshot(List.of()); + + public boolean empty() { + return combinedInventory.isEmpty(); + } + + public void restoreInto(List> combinedInventory) { + if (empty()) { + return; + } + for (int group = 0; group < combinedInventory.size(); group++) { + var original = combinedInventory.get(group); + for (int i = 0; i < original.size(); i++) { + ItemStack stored = this.combinedInventory.get(group).get(i); + if (!stored.isEmpty()) { + original.set(i, stored); + } + } + } + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerInventory.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerInventory.java index 5debbac8..e2311fef 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerInventory.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerInventory.java @@ -11,11 +11,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.advancement.UCriteria; -import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; -import com.minelittlepony.unicopia.item.enchantment.UEnchantments; - -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.enchantment.Enchantments; +import com.minelittlepony.unicopia.item.enchantment.HeartboundEnchantmentUtil; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; @@ -31,37 +27,21 @@ abstract class MixinPlayerInventory implements Inventory, Nameable { private @Final List> combinedInventory; @Nullable - private List> storedCombinedInventory; + private HeartboundEnchantmentUtil.InventorySnapshot inventorySnapshot; @Inject(method = "dropAll()V", at = @At("HEAD")) public void beforeDropAll(CallbackInfo info) { - storedCombinedInventory = combinedInventory.stream().map(l -> DefaultedList.ofSize(l.size(), ItemStack.EMPTY)).toList(); - for (int group = 0; group < combinedInventory.size(); group++) { - var original = combinedInventory.get(group); - for (int i = 0; i < original.size(); i++) { - ItemStack stack = original.get(i); - if (EnchantmentHelper.getLevel(Enchantments.BINDING_CURSE, stack) == 0 - && EnchantmentUtil.consumeEnchantment(UEnchantments.HEART_BOUND, 1, stack, player.getWorld().random, EnchantmentUtil.getLuck(3, player))) { - original.set(i, ItemStack.EMPTY); - UCriteria.USE_SOULMATE.trigger(player); - storedCombinedInventory.get(group).set(i, stack); - } - } + inventorySnapshot = HeartboundEnchantmentUtil.createSnapshot(combinedInventory); + if (!inventorySnapshot.empty()) { + UCriteria.USE_SOULMATE.trigger(player); } } - @Inject(method = "dropAll()V", at = @At("TAIL")) + @Inject(method = "dropAll()V", at = @At("RETURN")) public void afterDropAll(CallbackInfo info) { - if (storedCombinedInventory != null) { - for (int group = 0; group < combinedInventory.size(); group++) { - var original = combinedInventory.get(group); - for (int i = 0; i < original.size(); i++) { - ItemStack stored = storedCombinedInventory.get(group).get(i); - if (!stored.isEmpty()) { - original.set(i, stored); - } - } - } + if (inventorySnapshot != null) { + inventorySnapshot.restoreInto(combinedInventory); + inventorySnapshot = null; } } }