package com.minelittlepony.unicopia.entity; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Supplier; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.item.enchantment.SimpleEnchantment; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.Tickable; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtString; import net.minecraft.util.Identifier; import net.minecraft.registry.Registries; public class Enchantments implements NbtSerialisable, Tickable { private final Living entity; private final Set equippedEnchantments = new HashSet<>(); private final Map data = new HashMap<>(); Enchantments(Living entity) { this.entity = entity; } @SuppressWarnings("unchecked") public Optional getOrEmpty(Enchantment enchantment) { return Optional.ofNullable((T)data.get(enchantment)); } @SuppressWarnings("unchecked") public T computeIfAbsent(Enchantment enchantment, Supplier factory) { return (T)data.computeIfAbsent(enchantment, e -> factory.get()); } @Nullable @SuppressWarnings("unchecked") public T remove(Enchantment enchantment) { return (T)data.remove(enchantment); } @Override public void tick() { UEnchantments.REGISTRY.forEach(ench -> { int level = EnchantmentHelper.getEquipmentLevel(ench, entity.asEntity()); boolean active = level > 0; if (active != equippedEnchantments.contains(ench)) { if (active) { equippedEnchantments.add(ench); ench.onEquipped(entity); } else { equippedEnchantments.remove(ench); ench.onUnequipped(entity); } } if (active) { ench.onUserTick(entity, level); } }); } @Override public void toNBT(NbtCompound compound) { NbtList list = new NbtList(); equippedEnchantments.forEach(enchant -> { Identifier id = Registries.ENCHANTMENT.getId(enchant); if (id != null) { list.add(NbtString.of(id.toString())); } }); compound.put("enchants", list); } @Override public void fromNBT(NbtCompound compound) { equippedEnchantments.clear(); if (compound.contains("enchants")) { compound.getList("enchants", 8).forEach(tag -> { Registries.ENCHANTMENT.getOrEmpty(new Identifier(tag.asString())).ifPresent(equippedEnchantments::add); }); } } }