diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java index 60cc2c08..fffa8c0b 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java @@ -28,7 +28,7 @@ public record SpellDuplicatingRecipe (IngredientWithSpell material) implements S public void buildCraftingTree(CraftingTreeBuilder builder) { ItemStack[] spells = SpellType.REGISTRY.stream() .filter(SpellType::isObtainable) - .map(UItems.GEMSTONE::getDefaultStack) + .map(i -> EnchantableItem.enchant(UItems.GEMSTONE.getDefaultStack(), i)) .toArray(ItemStack[]::new); builder.input(UItems.BOTCHED_GEM.getDefaultStack()); builder.input(spells); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java index a82a6080..c7170066 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java @@ -47,7 +47,7 @@ public class SpellShapedCraftingRecipe extends ShapedRecipe { return inventory.getStacks().stream() .filter(stack -> stack.getItem() instanceof EnchantableItem) .filter(EnchantableItem::isEnchanted) - .map(stack -> ((EnchantableItem)stack.getItem()).getSpellEffect(stack)) + .map(stack -> EnchantableItem.getSpellEffect(stack)) .findFirst() .map(spell -> spell.traits().applyTo(EnchantableItem.enchant(super.craft(inventory, registries), spell.type()))) .orElseGet(() -> super.craft(inventory, registries)); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java index a0a052ff..9490f63f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; import java.util.function.Supplier; import org.jetbrains.annotations.Nullable; @@ -15,7 +16,10 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.client.TextHelper; import com.minelittlepony.unicopia.entity.effect.EffectUtils; +import net.minecraft.item.Item.TooltipContext; import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipAppender; +import net.minecraft.item.tooltip.TooltipType; import net.minecraft.nbt.NbtCompound; import net.minecraft.registry.RegistryWrapper.WrapperLookup; import net.minecraft.text.MutableText; @@ -27,7 +31,7 @@ public record CustomisedSpellType ( SpellType type, SpellTraits traits, Supplier traitsDifferenceSupplier - ) implements SpellPredicate { + ) implements SpellPredicate, TooltipAppender { public boolean isEmpty() { return type.isEmpty(); @@ -86,25 +90,25 @@ public record CustomisedSpellType ( return traits.applyTo(type.getDefualtStack()); } - public void appendTooltip(List lines) { + @Override + public void appendTooltip(TooltipContext context, Consumer tooltip, TooltipType type) { MutableText lore = Text.translatable(type().getTranslationKey() + ".lore").formatted(type().getAffinity().getColor()); if (!InteractionManager.getInstance().getClientSpecies().canCast()) { lore = lore.formatted(Formatting.OBFUSCATED); } - lines.addAll(TextHelper.wrap(lore, 180).toList()); + TextHelper.wrap(lore, 180).forEach(tooltip); float corruption = ((int)traits().getCorruption() * 10) + type().getAffinity().getCorruption(); List modifiers = new ArrayList<>(); - type.getTooltip().appendTooltip(this, modifiers); + type().getTooltip().appendTooltip(this, modifiers); if (corruption != 0) { modifiers.add(EffectUtils.formatModifierChange("affinity.unicopia.corruption", corruption, true)); } if (!modifiers.isEmpty()) { - lines.add(Text.empty()); - lines.add(Text.translatable("affinity.unicopia.when_cast").formatted(Formatting.GRAY)); - lines.addAll(modifiers); + tooltip.accept(Text.empty()); + tooltip.accept(Text.translatable("affinity.unicopia.when_cast").formatted(Formatting.GRAY)); + modifiers.forEach(tooltip); } - } public TypedActionResult> toAction() { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java index 50b8db4b..5db07ede 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java @@ -18,6 +18,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.ThrowableSpell; import com.minelittlepony.unicopia.ability.magic.spell.TimeControlAbilitySpell; import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.item.EnchantableItem; import com.minelittlepony.unicopia.item.GemstoneItem; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.util.RegistryUtils; @@ -117,7 +118,7 @@ public final class SpellType implements Affine, SpellPredicate< this.traits = traits; this.stackable = stackable; traited = new CustomisedSpellType<>(this, traits, SpellTraits::empty); - defaultStack = UItems.GEMSTONE.getDefaultStack(this); + defaultStack = EnchantableItem.enchant(UItems.GEMSTONE.getDefaultStack(), this); } public boolean isObtainable() { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java index c5dd6b8a..37392c61 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java @@ -9,8 +9,6 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; - import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.network.Channel; @@ -33,7 +31,6 @@ import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryWrapper.WrapperLookup; -import net.minecraft.world.World; public class TraitDiscovery implements NbtSerialisable, Copyable { private final Set unreadTraits = new HashSet<>(); @@ -114,7 +111,7 @@ public class TraitDiscovery implements NbtSerialisable, Copyable } @Environment(EnvType.CLIENT) - public void appendTooltip(ItemStack stack, @Nullable World world, List tooltip) { + public void appendTooltip(ItemStack stack, List tooltip) { SpellTraits.getEmbeddedTraits(stack) .orElseGet(() -> getKnownTraits(stack.getItem())) .appendTooltip(tooltip); diff --git a/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java index a58c5bd3..0eed51b1 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java @@ -1,146 +1,52 @@ package com.minelittlepony.unicopia.client; import java.util.List; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.diet.PonyDiets; import com.minelittlepony.unicopia.entity.player.Pony; -import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; -import net.minecraft.client.MinecraftClient; +import com.minelittlepony.unicopia.item.EnchantableItem; +import com.minelittlepony.unicopia.item.GlowableItem; +import com.minelittlepony.unicopia.item.component.UDataComponentTypes; + +import net.minecraft.component.ComponentType; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipAppender; import net.minecraft.item.tooltip.TooltipType; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; -public class ModifierTooltipRenderer implements ItemTooltipCallback { +public class ModifierTooltipRenderer { + public static final ModifierTooltipRenderer INSTANCE = new ModifierTooltipRenderer(); - @Override - public void getTooltip(ItemStack stack, Item.TooltipContext tooltipContext, TooltipType tooltipType, List lines) { + public void getTooltip(ItemStack stack, Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, List lines) { + @Nullable + Pony pony = Pony.of(player); - // TODO: Evaluate if we still need this - /*int flags = stack.hasNbt() && stack.getNbt().contains("HideFlags", 99) ? stack.getNbt().getInt("HideFlags") : 0; - - if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS)) { - - Enchantment s; - Map> modifiers = new HashMap<>(); - - Equine.of(MinecraftClient.getInstance().player).ifPresent(eq -> { - getEnchantments(stack).filter(p -> p.getRight() instanceof AttributedEnchantment).forEach(pair -> { - ((AttributedEnchantment)pair.getRight()).getModifiers(eq, pair.getLeft(), modifiers); - }); - }); - - modifiers.forEach((slot, modifs) -> { - - List newLines = new ArrayList<>(); - - modifs.entries().stream() - .filter(entry -> entry.getKey().equals(EntityAttributes.GENERIC_MOVEMENT_SPEED) || UEntityAttributes.REGISTRY.contains(entry.getKey())) - .forEach(entry -> describeModifiers(entry.getKey(), entry.getValue(), null, newLines)); - - if (!newLines.isEmpty()) { - Text find = Text.translatable("item.modifiers." + slot.getName()).formatted(Formatting.GRAY); - int insertPosition = getInsertPosition(stack, find, flags, lines, tooltipType.isAdvanced()); - if (insertPosition == -1) { - lines.add(ScreenTexts.EMPTY); - lines.add(find); - lines.addAll(newLines); - } else { - lines.addAll(insertPosition, newLines); - } - } - }); - }*/ - - if (MinecraftClient.getInstance().player != null) { - Pony.of(MinecraftClient.getInstance().player).getDiscoveries().appendTooltip(stack, MinecraftClient.getInstance().world, lines); - } - } -/* - private int getInsertPosition(ItemStack stack, Text category, int flags, List lines, boolean advanced) { - int insertPosition = lines.indexOf(category); - - if (insertPosition > -1) { - return insertPosition + 1; + if (pony != null) { + pony.getDiscoveries().appendTooltip(stack, lines); } - if (insertPosition == -1 && stack.hasNbt()) { - if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS) && stack.getNbt().getBoolean("Unbreakable")) { - insertPosition = checkFor(lines, Text.translatable("item.unbreakable").formatted(Formatting.BLUE)); - } + Consumer textConsumer = lines::add; - if (insertPosition == -1 && isShowing(flags, ItemStack.TooltipSection.CAN_DESTROY) && stack.getNbt().contains("CanDestroy", 9)) { - insertPosition = checkFor(lines, Text.translatable("item.canBreak").formatted(Formatting.GRAY)); - } - - if (insertPosition == -1 && isShowing(flags, ItemStack.TooltipSection.CAN_PLACE) && stack.getNbt().contains("CanPlaceOn", 9)) { - insertPosition = checkFor(lines, Text.translatable("item.canPlace").formatted(Formatting.GRAY)); - } + appendTooltip(stack, UDataComponentTypes.CHARGES, context, textConsumer, type); + appendTooltip(stack, UDataComponentTypes.ISSUER, context, textConsumer, type); + EnchantableItem.getSpellEffect(stack).appendTooltip(context, textConsumer, type); + if (GlowableItem.isGlowing(stack)) { + lines.add(Text.translatable("item.unicopia.friendship_bracelet.glowing").formatted(Formatting.ITALIC, Formatting.GRAY)); } - if (insertPosition == -1 && advanced) { - if (stack.isDamaged()) { - insertPosition = checkFor(lines, Text.translatable("item.durability", stack.getMaxDamage() - stack.getDamage(), stack.getMaxDamage())); - } else { - insertPosition = checkFor(lines, Text.literal(Registries.ITEM.getId(stack.getItem()).toString()).formatted(Formatting.DARK_GRAY)); - } - } - - return insertPosition; + PonyDiets.getInstance().getDiet(pony).appendTooltip(stack, pony, lines, type); } - private int checkFor(List lines, Text category) { - return lines.indexOf(category); - } - - private void describeModifiers(RegistryEntry attribute, EntityAttributeModifier modifier, @Nullable PlayerEntity player, List lines) { - double value = modifier.value(); - boolean baseAdjusted = false; - if (player != null) { - value += player.getAttributeBaseValue(attribute); - baseAdjusted = true; - } - - Operation op = modifier.operation(); - - double displayValue; - if (op != EntityAttributeModifier.Operation.ADD_MULTIPLIED_BASE && op != EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL) { - displayValue = value; - } else { - displayValue = value * 100; - } - - if (baseAdjusted) { - lines.add(Text.literal(" ").append(getModifierLineBase("equals", displayValue, op, attribute, Formatting.DARK_GREEN))); - } else if (value > 0) { - lines.add(getModifierLineBase("plus", displayValue, op, attribute, attribute == UEntityAttributes.ENTITY_GRAVITY_MODIFIER ? Formatting.RED : Formatting.BLUE)); - } else if (value < 0) { - lines.add(getModifierLineBase("take", -displayValue, op, attribute, attribute == UEntityAttributes.ENTITY_GRAVITY_MODIFIER ? Formatting.BLUE : Formatting.RED)); + private void appendTooltip(ItemStack stack, ComponentType componentType, Item.TooltipContext context, Consumer textConsumer, TooltipType type) { + T tooltipAppender = stack.get(componentType); + if (tooltipAppender != null) { + tooltipAppender.appendTooltip(context, textConsumer, type); } } - - private Text getModifierLineBase(String root, double displayValue, Operation op, EntityAttribute attribute, Formatting color) { - return Text.translatable("attribute.modifier." + root + "." + op.getId(), - ItemStack.MODIFIER_FORMAT.format(displayValue), - Text.translatable(attribute.getTranslationKey()) - ).formatted(color); - } - - - private static boolean isShowing(int flags, ItemStack.TooltipSection section) { - return (flags & section.getFlag()) == 0; - } - - private static Stream> getEnchantments(ItemStack stack) { - if (!stack.isEmpty()) { - return stack.getEnchantments() - .stream() - .map(t -> (NbtCompound)t) - .map(tag -> Registries.ENCHANTMENT.getOrEmpty(Identifier.tryParse(tag.getString("id"))) - .map(ench -> new Pair<>(tag.getInt("lvl"), ench))) - .filter(Optional::isPresent) - .map(Optional::get); - } - - return Stream.empty(); - } -*/ } diff --git a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java index d3ab795d..2a0da0a6 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java +++ b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java @@ -27,7 +27,6 @@ import com.minelittlepony.unicopia.util.Lerp; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.OpenToLanScreen; @@ -145,7 +144,6 @@ public class UnicopiaClient implements ClientModInitializer { ClientTickEvents.END_CLIENT_TICK.register(this::onTick); ClientTickEvents.END_WORLD_TICK.register(this::onWorldTick); ScreenInitCallback.EVENT.register(this::onScreenInit); - ItemTooltipCallback.EVENT.register(new ModifierTooltipRenderer()); ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(ViewportShader.INSTANCE); ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(SpellEffectsRenderDispatcher.INSTANCE); diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java b/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java index 16511395..aa2f1a03 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java @@ -19,6 +19,8 @@ import net.minecraft.client.gui.*; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.Item.TooltipContext; +import net.minecraft.item.tooltip.TooltipType; import net.minecraft.screen.ScreenTexts; import net.minecraft.text.MutableText; import net.minecraft.text.Text; @@ -205,7 +207,7 @@ public class DismissSpellScreen extends GameGui { tooltip.add(Text.translatable("gui.unicopia.dispell_screen.spell_type", name)); type.traits().appendTooltip(tooltip); tooltip.add(ScreenTexts.EMPTY); - type.appendTooltip(tooltip); + type.appendTooltip(TooltipContext.create(client.world), tooltip::add, TooltipType.BASIC); tooltip.add(ScreenTexts.EMPTY); if (spell instanceof TimedSpell timed) { tooltip.add(ScreenTexts.EMPTY); diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookScreen.java b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookScreen.java index bb01800a..2a7337bc 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookScreen.java @@ -32,6 +32,8 @@ import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.Item.TooltipContext; +import net.minecraft.item.tooltip.TooltipType; import net.minecraft.screen.slot.Slot; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -209,7 +211,7 @@ public class SpellbookScreen extends HandledScreen imple List tooltip = new ArrayList<>(); tooltip.add(spell.type().getName()); - spell.appendTooltip(tooltip); + spell.appendTooltip(TooltipContext.create(client.world), tooltip::add, TooltipType.BASIC); context.drawTooltip(textRenderer, tooltip, x, y); context.getMatrices().pop(); diff --git a/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java b/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java index 8a0fd7e2..165d0080 100644 --- a/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java +++ b/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java @@ -103,11 +103,10 @@ public class Main implements EmiPlugin { .filter(recipe -> recipe.value() instanceof SpellShapedCraftingRecipe) .forEach(recipe -> { ItemStack output = recipe.value().getResult(registries); - if (output.getItem() instanceof MultiItem multiItem && output.getItem() instanceof EnchantableItem enchantable) { + if (output.getItem() instanceof MultiItem multiItem) { multiItem.getDefaultStacks().forEach(outputVariation -> { - var spellEffect = enchantable.getSpellEffect(outputVariation); - if (!spellEffect.isEmpty()) { - registry.addRecipe(new MagicalShapedEmiRecipe(recipe, spellEffect, outputVariation)); + if (EnchantableItem.isEnchanted(outputVariation)) { + registry.addRecipe(new MagicalShapedEmiRecipe(recipe, EnchantableItem.getSpellEffect(outputVariation), outputVariation)); } }); } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java index 74a9ea39..be079459 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java @@ -11,14 +11,12 @@ import java.util.stream.Collectors; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.item.ItemDuck; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.FoodComponent; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.tooltip.TooltipType; import net.minecraft.network.RegistryByteBuf; @@ -80,7 +78,7 @@ public record DietProfile( } static boolean isForaged(ItemStack stack) { - return ((ItemDuck)stack.getItem()).getOriginalFoodComponent().isEmpty(); + return stack.getComponents().get(DataComponentTypes.FOOD) == null; } @Nullable @@ -125,10 +123,17 @@ public record DietProfile( return Pair.of(hungerMultiplier, saturationMultiplier); } - public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List tooltip, TooltipType context) { - var food = stack.get(DataComponentTypes.FOOD); + public void appendTooltip(ItemStack stack, @Nullable Pony pony, List tooltip, TooltipType context) { + if (this == EMPTY) { + return; + } + tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE)); + findEffect(stack).orElseGet(() -> PonyDiets.getInstance().getEffects(stack)).appendTooltip(stack, tooltip, context); + + var food = stack.get(DataComponentTypes.FOOD); var ratios = getRatios(stack); + if (food == null || isInedible(ratios)) { if (stack.getUseAction() != UseAction.DRINK) { tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.not_edible")).formatted(Formatting.DARK_GRAY)); @@ -139,7 +144,7 @@ public record DietProfile( float baseMultiplier = (isForaged(stack) ? foragingMultiplier() : defaultMultiplier()); if (context.isAdvanced()) { - var nonAdjustedFood = getNonAdjustedFoodComponent(stack, user).orElse(food); + var nonAdjustedFood = getNonAdjustedFoodComponent(stack, pony).orElse(food); tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.base_multiplier", baseMultiplier).formatted(Formatting.DARK_GRAY))); tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.hunger.detailed", food.nutrition(), nonAdjustedFood.nutrition(), (int)(ratios.getFirst() * 100))).formatted(Formatting.DARK_GRAY)); tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.saturation.detailed", food.saturation(), nonAdjustedFood.saturation(), (int)(ratios.getSecond() * 100))).formatted(Formatting.DARK_GRAY)); @@ -149,18 +154,20 @@ public record DietProfile( } } - private Optional getNonAdjustedFoodComponent(ItemStack stack, @Nullable PlayerEntity user) { - @Nullable - Pony pony = Pony.of(user); - Optional food = ((ItemDuck)stack.getItem()).getOriginalFoodComponent(); + private Optional getNonAdjustedFoodComponent(ItemStack stack, @Nullable Pony pony) { + FoodComponent food = stack.getComponents().get(DataComponentTypes.FOOD); - if (food.isEmpty() && pony.getObservedSpecies().hasIronGut()) { + if (food != null) { + return Optional.ofNullable(food); + } + + if (pony != null && pony.getObservedSpecies().hasIronGut()) { return findEffect(stack) .flatMap(Effect::foodComponent) .or(() -> PonyDiets.getInstance().getEffects(stack).foodComponent()); } - return food; + return Optional.empty(); } public record Multiplier( diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietView.java b/src/main/java/com/minelittlepony/unicopia/diet/DietView.java index b8dabf0a..6b6328d8 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietView.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietView.java @@ -1,13 +1,8 @@ package com.minelittlepony.unicopia.diet; -import java.util.List; -import org.jetbrains.annotations.Nullable; - import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; @@ -16,12 +11,4 @@ public interface DietView { TypedActionResult startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand); void finishUsing(ItemStack stack, World world, LivingEntity entity); - - void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List tooltip, TooltipType context); - - interface Holder { - default DietView getDiets(ItemStack stack) { - return PonyDiets.getInstance(); - } - } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java index 4c876c60..39e8d687 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.diet; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Optional; import org.jetbrains.annotations.Nullable; @@ -9,19 +8,14 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.entity.effect.FoodPoisoningStatusEffect; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.item.ItemDuck; import com.minelittlepony.unicopia.util.serialization.PacketCodecUtils; -import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; import net.minecraft.util.TypedActionResult; @@ -57,11 +51,11 @@ public class PonyDiets implements DietView { this.effects = effects; } - private DietProfile getDiet(Pony pony) { + public DietProfile getDiet(Pony pony) { return Optional.ofNullable(diets.get(pony.getObservedSpecies())).orElse(DietProfile.EMPTY); } - Effect getEffects(ItemStack stack) { + public Effect getEffects(ItemStack stack) { return effects.values().stream().filter(effect -> effect.test(stack)).findFirst().map(Effect.class::cast).orElse(Effect.EMPTY); } @@ -71,50 +65,11 @@ public class PonyDiets implements DietView { @Override public TypedActionResult startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand) { - return initEdibility(stack, user) - ? FoodPoisoningStatusEffect.apply(stack, user) - : TypedActionResult.fail(stack); + return FoodPoisoningStatusEffect.apply(stack, user); } @Override public void finishUsing(ItemStack stack, World world, LivingEntity entity) { - if (initEdibility(stack, entity)) { - Pony.of(entity).ifPresent(pony -> getEffects(stack, pony).ailment().effects().afflict(pony.asEntity(), stack)); - } - } - - @Override - public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List tooltip, TooltipType context) { - - if (initEdibility(stack, user)) { - if (!((ItemDuck)stack.getItem()).getOriginalFoodComponent().isEmpty() || stack.contains(DataComponentTypes.FOOD)) { - Pony pony = Pony.of(user); - - tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE)); - getEffects(stack, pony).appendTooltip(stack, tooltip, context); - getDiet(pony).appendTooltip(stack, user, tooltip, context); - } - } - } - - private boolean initEdibility(ItemStack stack, LivingEntity user) { - ItemDuck item = (ItemDuck)stack.getItem(); - item.resetFoodComponent(); - return Pony.of(user).filter(pony -> { - DietProfile diet = getDiet(pony); - - if (!stack.contains(DataComponentTypes.FOOD) && pony.getObservedSpecies().hasIronGut()) { - diet.findEffect(stack) - .flatMap(Effect::foodComponent) - .or(() -> getEffects(stack).foodComponent()) - .ifPresent(item::setFoodComponent); - } - - if (stack.contains(DataComponentTypes.FOOD)) { - item.setFoodComponent(diet.getAdjustedFoodComponent(stack)); - } - - return true; - }).isPresent(); + Pony.of(entity).ifPresent(pony -> getEffects(stack, pony).ailment().effects().afflict(pony.asEntity(), stack)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java b/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java index f55a6850..f0aa393f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java @@ -41,7 +41,6 @@ public class AmuletItem extends WearableItem { @Override public void appendTooltip(ItemStack stack, TooltipContext context, List list, TooltipType type) { - 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); @@ -51,8 +50,7 @@ public class AmuletItem extends WearableItem { }); list.add(compiled); } - - Charges.of(stack).appendTooltip(context, list::add, type); + super.appendTooltip(stack, context, list, type); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/item/BellItem.java b/src/main/java/com/minelittlepony/unicopia/item/BellItem.java index 3d34c379..bb85361e 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/BellItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/BellItem.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.item; -import java.util.List; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.entity.Creature; @@ -22,10 +21,8 @@ import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleTypes; -import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; @@ -43,11 +40,6 @@ public class BellItem extends Item { return UseAction.BOW; } - @Override - public void appendTooltip(ItemStack stack, TooltipContext context, List list, TooltipType type) { - Charges.of(stack).appendTooltip(context, list::add, type); - } - @Override public int getMaxUseTime(ItemStack stack, LivingEntity user) { return 3000; diff --git a/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java b/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java index 3183cbde..478d4101 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java @@ -19,12 +19,7 @@ import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; public interface EnchantableItem extends ItemConvertible { - - default ItemStack getDefaultStack(SpellType spell) { - return enchant(asItem().getDefaultStack(), spell); - } - - default CustomisedSpellType getSpellEffect(ItemStack stack) { + static CustomisedSpellType getSpellEffect(ItemStack stack) { return EnchantableItem.getSpellKey(stack).withTraits(SpellTraits.of(stack)); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java b/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java index 79ed1415..b0b1ab73 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java @@ -102,7 +102,6 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu SpellType key = EnchantableItem.getSpellKey(stack); lines.add(Text.translatable(key.getTranslationKey()).formatted(key.getAffinity().getColor())); } - Charges.of(stack).appendTooltip(context, lines::add, type); } @Override @@ -144,7 +143,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu Pony.of(entity).ifPresent(pony -> { pony.subtractEnergyCost(4); stack.damage(1, pony.asEntity(), EquipmentSlot.MAINHAND); - getSpellEffect(stack).create().toThrowable().throwProjectile(pony); + EnchantableItem.getSpellEffect(stack).create().toThrowable().throwProjectile(pony); pony.setAnimation(Animation.ARMS_UP, Animation.Recipient.ANYONE, 10); }); } @@ -153,7 +152,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu Pony.of(entity).ifPresent(pony -> { pony.subtractEnergyCost(4); stack.damage(1, pony.asEntity(), EquipmentSlot.MAINHAND); - getSpellEffect(stack).create().toThrowable().throwProjectile(pony); + EnchantableItem.getSpellEffect(stack).create().toThrowable().throwProjectile(pony); pony.setAnimation(Animation.ARMS_UP, Animation.Recipient.ANYONE, 10); }); } @@ -166,7 +165,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu if (attacker.isSneaking() && Charges.discharge(stack, 1)) { stack.damage(50, attacker, EquipmentSlot.MAINHAND); Caster.of(attacker).ifPresent(c -> c.subtractEnergyCost(4)); - Caster.of(target).ifPresent(c -> getSpellEffect(stack).apply(c, CastingMethod.STAFF)); + Caster.of(target).ifPresent(c -> EnchantableItem.getSpellEffect(stack).apply(c, CastingMethod.STAFF)); } return false; @@ -193,7 +192,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu living.clearActiveItem(); living.damage(entity.getDamageSources().magic(), 1); if (EnchantableItem.isEnchanted(stack) && Charges.discharge(stack, 1)) { - Caster.of(entity).ifPresent(c -> getSpellEffect(stack).apply(c, CastingMethod.STAFF)); + Caster.of(entity).ifPresent(c -> EnchantableItem.getSpellEffect(stack).apply(c, CastingMethod.STAFF)); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java b/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java index c9e94918..ab74dff6 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.item; -import java.util.List; import java.util.UUID; import java.util.function.Predicate; import java.util.stream.Stream; @@ -15,19 +14,13 @@ import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.entity.AmuletSelectors; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.component.Issuer; -import com.minelittlepony.unicopia.item.component.UDataComponentTypes; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; import net.minecraft.entity.Entity; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; import net.minecraft.stat.Stats; -import net.minecraft.text.Text; import net.minecraft.util.*; import net.minecraft.world.World; @@ -69,18 +62,6 @@ public class FriendshipBraceletItem extends WearableItem { return super.use(world, player, hand); } - @Override - @Environment(EnvType.CLIENT) - public void appendTooltip(ItemStack stack, TooltipContext context, List lines, TooltipType type) { - super.appendTooltip(stack, context, lines, type); - if (Issuer.isSigned(stack)) { - stack.get(UDataComponentTypes.ISSUER).appendTooltip(context, lines::add, type); - } - if (GlowableItem.isGlowing(stack)) { - lines.add(Text.translatable("item.unicopia.friendship_bracelet.glowing").formatted(Formatting.ITALIC, Formatting.GRAY)); - } - } - @Override public EquipmentSlot getSlotType(ItemStack stack) { return Issuer.isSigned(stack) ? EquipmentSlot.CHEST : super.getSlotType(stack); diff --git a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java index 566ddc19..a80ebadc 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java @@ -14,13 +14,12 @@ import com.minelittlepony.unicopia.item.group.MultiItem; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; import net.minecraft.text.Text; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; -public class GemstoneItem extends Item implements MultiItem, EnchantableItem { +public class GemstoneItem extends Item implements MultiItem { public GemstoneItem(Settings settings) { super(settings); @@ -71,15 +70,6 @@ public class GemstoneItem extends Item implements MultiItem, EnchantableItem { return result; } - @Override - public void appendTooltip(ItemStack stack, TooltipContext context, List lines, TooltipType type) { - super.appendTooltip(stack, context, lines, type); - - if (EnchantableItem.isEnchanted(stack)) { - getSpellEffect(stack).appendTooltip(lines); - } - } - @Override public List getDefaultStacks() { return SpellType.REGISTRY.stream() diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemDuck.java b/src/main/java/com/minelittlepony/unicopia/item/ItemDuck.java index a0b6380d..d104d95b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ItemDuck.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ItemDuck.java @@ -1,24 +1,7 @@ package com.minelittlepony.unicopia.item; -import java.util.Optional; - -import com.minelittlepony.unicopia.diet.DietView; import com.minelittlepony.unicopia.entity.ItemImpl; - -import net.minecraft.component.type.FoodComponent; import net.minecraft.item.*; -public interface ItemDuck extends ItemConvertible, ItemImpl.TickableItem, DietView.Holder { - @Deprecated - void setFoodComponent(FoodComponent food); - - // TODO: Inject into Item.Settings::getComponents and return our own implementation of ComponentMap to handle food component overrides - // ItemStack(ComponentMapImpl(UnicopiaComponentMap(ItemComponentMap()), Changes)) - @Deprecated - Optional getOriginalFoodComponent(); - - @Deprecated - default void resetFoodComponent() { - setFoodComponent(getOriginalFoodComponent().orElse(null)); - } +public interface ItemDuck extends ItemConvertible, ItemImpl.TickableItem { } diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemStackDuck.java b/src/main/java/com/minelittlepony/unicopia/item/ItemStackDuck.java new file mode 100644 index 00000000..9b63756b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/ItemStackDuck.java @@ -0,0 +1,20 @@ +package com.minelittlepony.unicopia.item; + +import com.minelittlepony.unicopia.item.component.TransientComponentMap; + +import net.minecraft.component.ComponentHolder; +import net.minecraft.item.ItemStack; + +public interface ItemStackDuck extends ComponentHolder, TransientComponentMap.Holder { + default ItemDuck getItemDuck() { + return (ItemDuck)((ItemStack)(Object)this).getItem(); + } + + static ItemStackDuck of(ItemStack stack) { + return (ItemStackDuck)(Object)stack; + } + + static boolean isItemStack(Object o) { + return o instanceof ItemStackDuck; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/component/TransientComponentMap.java b/src/main/java/com/minelittlepony/unicopia/item/component/TransientComponentMap.java new file mode 100644 index 00000000..7f1834fb --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/component/TransientComponentMap.java @@ -0,0 +1,91 @@ +package com.minelittlepony.unicopia.item.component; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiFunction; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.diet.DietProfile; +import com.minelittlepony.unicopia.diet.Effect; +import com.minelittlepony.unicopia.diet.PonyDiets; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.item.ItemStackDuck; + +import net.minecraft.component.ComponentType; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Util; + +public class TransientComponentMap { + private static final BiFunction DEFAULT = (stack, t) -> t; + public static final TransientComponentMap INITIAL = Util.make(new TransientComponentMap(), map -> { + map.set(UDataComponentTypes.DIET_PROFILE, (s, original) -> { + if (original != null) { + return original; + } + return ItemStackDuck.of(s).getTransientComponents().getCarrier() + .flatMap(Pony::of) + .map(pony -> PonyDiets.getInstance().getDiet(pony)) + .orElse(DietProfile.EMPTY); + }); + map.set(DataComponentTypes.FOOD, (s, originalFood) -> { + DietProfile diet = s.get(UDataComponentTypes.DIET_PROFILE); + + if (diet == null) { + return originalFood; + } + + if (originalFood != null) { + return diet.getAdjustedFoodComponent(s); + } + + if (ItemStackDuck.of(s).getTransientComponents().getCarrier() + .flatMap(Pony::of) + .filter(pony -> pony.getObservedSpecies().hasIronGut()) + .isPresent()) { + return diet.findEffect(s) + .flatMap(Effect::foodComponent) + .or(() -> PonyDiets.getInstance().getEffects(s).foodComponent()) + .orElse(originalFood); + } + + return originalFood; + }); + }); + + private final Map, BiFunction> components = new HashMap<>(); + + private Optional carrier = Optional.empty(); + + private TransientComponentMap() {} + + public Optional getCarrier() { + return carrier; + } + + public void setCarrier(@Nullable Entity carrier) { + this.carrier = Optional.ofNullable(carrier); + } + + public void set(ComponentType type, BiFunction getter) { + components.put(type, getter); + } + + @SuppressWarnings("unchecked") + public T get(ComponentType type, ItemStack stack, T upstreamValue) { + return ((BiFunction)components.getOrDefault(type, DEFAULT)).apply(stack, upstreamValue); + } + + public TransientComponentMap createCopy() { + TransientComponentMap copy = new TransientComponentMap(); + copy.components.putAll(components); + return copy; + } + + public interface Holder { + TransientComponentMap getTransientComponents(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java b/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java index 099fce8c..169353c7 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java +++ b/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java @@ -6,6 +6,7 @@ import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.container.SpellbookState; +import com.minelittlepony.unicopia.diet.DietProfile; import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; import com.minelittlepony.unicopia.entity.mob.ButterflyEntity; import com.mojang.serialization.Codec; @@ -25,6 +26,7 @@ public interface UDataComponentTypes { ComponentType ISSUER = register("issuer", builder -> builder.codec(Issuer.CODEC).packetCodec(Issuer.PACKET_CODEC).cache()); ComponentType CHARGES = register("charges", builder -> builder.codec(Charges.CODEC).packetCodec(Charges.PACKET_CODEC)); ComponentType APPEARANCE = register("appearance", builder -> builder.codec(Appearance.CODEC).packetCodec(Appearance.PACKET_CODEC)); + ComponentType DIET_PROFILE = register("diet_profile", builder -> builder.codec(DietProfile.CODEC).packetCodec(DietProfile.PACKET_CODEC)); private static ComponentType register(String name, UnaryOperator> builderOperator) { return Registry.register(Registries.DATA_COMPONENT_TYPE, Unicopia.id(name), builderOperator.apply(ComponentType.builder()).build()); diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/CustomEnchantableItem.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/CustomEnchantableItem.java deleted file mode 100644 index 9a4c6483..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/CustomEnchantableItem.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.minelittlepony.unicopia.item.enchantment; - -import net.minecraft.enchantment.Enchantment; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKey; - -@Deprecated -public interface CustomEnchantableItem { - boolean isAcceptableEnchant(ItemStack stack, RegistryKey enchantment); -} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java index fac8603a..b49e9764 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java @@ -2,36 +2,19 @@ package com.minelittlepony.unicopia.mixin; import java.util.ArrayList; import java.util.List; -import java.util.Optional; -import java.util.function.Supplier; - import org.spongepowered.asm.mixin.Mixin; -import com.google.common.base.Suppliers; import com.minelittlepony.unicopia.entity.ItemImpl; import com.minelittlepony.unicopia.entity.ItemImpl.GroundTickCallback; import com.minelittlepony.unicopia.item.ItemDuck; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.FoodComponent; import net.minecraft.item.Item; @Mixin(Item.class) abstract class MixinItem implements ItemDuck { private final List tickCallbacks = new ArrayList<>(); - @Deprecated - private final Supplier> originalFoodComponent = Suppliers.memoize(() -> { - return Optional.ofNullable(((Item)(Object)this).getComponents().get(DataComponentTypes.FOOD)); - }); - @Override public List getCallbacks() { return tickCallbacks; } - - @Deprecated - @Override - public Optional getOriginalFoodComponent() { - return originalFoodComponent.get(); - } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java index 78ca2dde..cd597868 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java @@ -1,37 +1,89 @@ package com.minelittlepony.unicopia.mixin; +import java.util.List; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.minelittlepony.unicopia.diet.DietView; +import com.minelittlepony.unicopia.diet.PonyDiets; import com.minelittlepony.unicopia.item.DamageChecker; - +import com.minelittlepony.unicopia.item.ItemStackDuck; +import com.minelittlepony.unicopia.item.component.TransientComponentMap; +import net.minecraft.component.ComponentType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipAppender; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; @Mixin(ItemStack.class) -abstract class MixinItemStack { +abstract class MixinItemStack implements ItemStackDuck { + private final TransientComponentMap transientComponents = TransientComponentMap.INITIAL.createCopy(); + + @Shadow + abstract void appendTooltip( + ComponentType componentType, Item.TooltipContext context, Consumer textConsumer, TooltipType type + ); + + @Override + public TransientComponentMap getTransientComponents() { + return transientComponents; + } + @Inject(method = "use", at = @At("HEAD"), cancellable = true) private void onUse(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> info) { - ItemStack self = (ItemStack)(Object)this; - TypedActionResult result = ((DietView.Holder)self.getItem()).getDiets(self).startUsing(self, world, user, hand); + transientComponents.setCarrier(user); + TypedActionResult result = PonyDiets.getInstance().startUsing((ItemStack)(Object)this, world, user, hand); if (result.getResult() != ActionResult.PASS) { info.setReturnValue(result); } } + @Inject(method = "onStoppedUsing", at = @At("RETURN")) + public void onOnStoppedUsing(World world, LivingEntity user, int remainingUseTicks, CallbackInfo info) { + transientComponents.setCarrier(null); + } + @Inject(method = "finishUsing", at = @At("HEAD")) - private void onFinishUsing(World world, LivingEntity user, CallbackInfoReturnable info) { - ItemStack self = (ItemStack)(Object)this; - ((DietView.Holder)self.getItem()).getDiets(self).finishUsing(self, world, user); + private void beforeFinishUsing(World world, LivingEntity user, CallbackInfoReturnable info) { + transientComponents.setCarrier(user); + PonyDiets.getInstance().finishUsing((ItemStack)(Object)this, world, user); + } + + @Inject(method = "finishUsing", at = @At("RETURN")) + private void afterFinishUsing(World world, LivingEntity user, CallbackInfoReturnable info) { + transientComponents.setCarrier(null); + } + + @Inject(method = "getTooltip", at = @At("HEAD")) + public void beforeGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable> info) { + transientComponents.setCarrier(player); + } + + @Inject(method = "getTooltip", at = @At("RETURN")) + public void afterGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable> info) { + transientComponents.setCarrier(null); + } + + @Inject(method = "getTooltip", + at = @At(value = "INVOKE", + target = "net/minecraft/item/ItemStack.appendAttributeModifiersTooltip(Ljava/util/function/Consumer;Lnet/minecraft/entity/player/PlayerEntity;)V" + )) + public void onGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable> info) { + } @Inject(method = "takesDamageFrom", at = @At("HEAD")) @@ -41,4 +93,28 @@ abstract class MixinItemStack { info.setReturnValue(checker.takesDamageFrom(source)); } } + + @Inject(method = "get", at = @At("RETURN")) + private void unicopia_onGet(ComponentType type, CallbackInfoReturnable info) { + Object o = this; + if (o instanceof ItemStack stack) { + info.setReturnValue(ItemStackDuck.of(stack).getTransientComponents().get(type, stack, info.getReturnValue())); + } + } + + @Inject(method = "getOrDefault", at = @At("RETURN")) + private void unicopia_onGetOrDefault(ComponentType type, T fallback, CallbackInfoReturnable info) { + Object o = this; + if (o instanceof ItemStack stack) { + info.setReturnValue(ItemStackDuck.of(stack).getTransientComponents().get(type, stack, info.getReturnValue())); + } + } + + @Inject(method = "contains", at = @At("RETURN")) + private void unicopia_onContains(ComponentType type, CallbackInfoReturnable info) { + Object o = this; + if (o instanceof ItemStack stack && ItemStackDuck.of(stack).getTransientComponents().get(type, stack, null) != null) { + info.setReturnValue(true); + } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemStack.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemStack.java deleted file mode 100644 index 96c4730c..00000000 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemStack.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.minelittlepony.unicopia.mixin.client; - -import java.util.List; -import org.jetbrains.annotations.Nullable; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.minelittlepony.unicopia.diet.DietView; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipType; -import net.minecraft.text.Text; - -@Mixin(ItemStack.class) -abstract class MixinItemStack { - @Inject(method = "getTooltip", at = @At("RETURN")) - private void onGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable> info) { - ItemStack self = (ItemStack)(Object)this; - ((DietView.Holder)self.getItem()).getDiets(self).appendTooltip(self, player, info.getReturnValue(), type); - } -} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 99bd3a70..aa5a993a 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -94,7 +94,6 @@ "client.MixinInGameHud", "client.MixinInGameHud$HeartType", "client.MixinItemModels", - "client.MixinItemStack", "client.MixinKeyboardInput", "client.MixinLivingEntityRenderer", "client.MixinMinecraftClient",