Fix items with heartbound not being restored if it had only 1 enchantment level before dying

This commit is contained in:
Sollace 2024-02-11 20:31:37 +00:00
parent 623d231f2f
commit 80c31b4a1d
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
4 changed files with 64 additions and 32 deletions

View file

@ -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<PlayerEntity> implements Copyable<Pony>, 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);
}
}

View file

@ -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);
}

View file

@ -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<DefaultedList<ItemStack>> combinedInventory) {
List<DefaultedList<ItemStack>> 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<DefaultedList<ItemStack>> combinedInventory) {
public static InventorySnapshot EMPTY = new InventorySnapshot(List.of());
public boolean empty() {
return combinedInventory.isEmpty();
}
public void restoreInto(List<DefaultedList<ItemStack>> 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);
}
}
}
}
}
}

View file

@ -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<DefaultedList<ItemStack>> combinedInventory;
@Nullable
private List<DefaultedList<ItemStack>> 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;
}
}
}