package com.minelittlepony.unicopia.item; import java.util.List; import java.util.Optional; import java.util.UUID; import org.jetbrains.annotations.Nullable; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import com.minelittlepony.unicopia.trinkets.TrinketsDelegate; import net.fabricmc.fabric.api.item.v1.FabricItemSettings; import net.minecraft.client.MinecraftClient; import net.minecraft.client.item.TooltipContext; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.item.ArmorMaterials; import net.minecraft.item.ItemStack; import net.minecraft.sound.SoundEvent; import net.minecraft.text.MutableText; import net.minecraft.text.StringVisitable; import net.minecraft.text.Style; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.world.World; public class AmuletItem extends WearableItem { private final int maxEnergy; private final ImmutableMultimap modifiers; public AmuletItem(FabricItemSettings settings, int maxEnergy) { this(settings, maxEnergy, ImmutableMultimap.of()); } public AmuletItem(FabricItemSettings settings, int maxEnergy, ImmutableMultimap modifiers) { super(settings); this.maxEnergy = maxEnergy; this.modifiers = modifiers; } @Override public void appendTooltip(ItemStack stack, @Nullable World world, List list, TooltipContext tooltipContext) { for (StringVisitable line : MinecraftClient.getInstance().textRenderer.getTextHandler().wrapLines( Text.translatable(getTranslationKey(stack) + ".lore"), 150, Style.EMPTY)) { MutableText compiled = Text.literal("").formatted(Formatting.ITALIC, Formatting.GRAY); line.visit(s -> { compiled.append(s); return Optional.empty(); }); list.add(compiled); } if (isChargable()) { list.add(Text.translatable("item.unicopia.amulet.energy", (int)Math.floor(getEnergy(stack)), maxEnergy)); } } @Override public SoundEvent getEquipSound() { return ArmorMaterials.IRON.getEquipSound(); } @Override public EquipmentSlot getPreferredSlot(ItemStack stack) { return EquipmentSlot.CHEST; } @Override public boolean hasGlint(ItemStack stack) { return !isChargable() || stack.hasEnchantments() || getEnergy(stack) > 0; } @Override public Multimap getAttributeModifiers(EquipmentSlot slot) { return slot == EquipmentSlot.CHEST ? modifiers : ImmutableMultimap.of(); } public boolean isApplicable(ItemStack stack) { return stack.getItem() == this && (!isChargable() || getEnergy(stack) > 0); } public boolean isApplicable(LivingEntity entity) { return isApplicable(getForEntity(entity)); } public static ItemStack getForEntity(LivingEntity entity) { return TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.NECKLACE) .filter(stack -> stack.getItem() instanceof AmuletItem) .findFirst() .orElse(ItemStack.EMPTY); } public boolean isChargable() { return maxEnergy > 0; } public boolean canCharge(ItemStack stack) { return isChargable() && getEnergy(stack) < maxEnergy; } public float getChargeRemainder(ItemStack stack) { return Math.max(0, maxEnergy - getEnergy(stack)); } public static void consumeEnergy(ItemStack stack, float amount) { setEnergy(stack, getEnergy(stack) - amount); } public static float getEnergy(ItemStack stack) { return stack.hasNbt() && stack.getNbt().contains("energy") ? stack.getNbt().getFloat("energy") : 0; } public static void setEnergy(ItemStack stack, float energy) { if (energy <= 0) { stack.removeSubNbt("energy"); } else { stack.getOrCreateNbt().putFloat("energy", energy); } } public static class ModifiersBuilder { private static final UUID SLOT_UUID = UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"); private final ImmutableMultimap.Builder modifiers = new ImmutableMultimap.Builder<>(); public ModifiersBuilder add(EntityAttribute attribute, double amount) { modifiers.put(attribute, new EntityAttributeModifier(SLOT_UUID, "Armor modifier", amount, EntityAttributeModifier.Operation.ADDITION)); return this; } public ImmutableMultimap build() { return modifiers.build(); } } }