1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2026-06-02 02:42:06 +00:00

Add potion effects to item details

There's some nasty hacks here around potion durations on other items.
This should get a bit cleaner in newer versions of the game, once we
switch to data components.

Fixes #2266.
This commit is contained in:
Jonathan Coates
2025-12-15 22:16:53 +00:00
parent 1ea84fe7d7
commit 60bcb9d4d3
2 changed files with 45 additions and 0 deletions
@@ -13,6 +13,9 @@ import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.EnchantedBookItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.LingeringPotionItem;
import net.minecraft.world.item.TippedArrowItem;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.Block;
@@ -72,6 +75,9 @@ public class ItemDetails {
var enchants = getAllEnchants(stack, hideFlags);
if (!enchants.isEmpty()) data.put("enchantments", enchants);
var effects = getAllEffects(stack);
if (!effects.isEmpty()) data.put("potionEffects", effects);
if (tag != null && tag.getBoolean("Unbreakable") && (hideFlags & 4) == 0) {
data.put("unbreakable", true);
}
@@ -137,4 +143,41 @@ public class ItemDetails {
enchants.add(enchant);
}
}
/**
* Retrieve all potions from given stack.
*
* @param stack Stack to analyse.
* @return A filled list that contain all visible potions.
*/
private static List<Map<String, Object>> getAllEffects(ItemStack stack) {
return PotionUtils.getMobEffects(stack).stream().map(p -> {
Map<String, Object> potion = new HashMap<>(4);
potion.put("name", DetailHelpers.getId(RegistryWrappers.MOB_EFFECTS, p.getEffect()));
potion.put("displayName", Component.translatable(p.getDescriptionId()).getString());
// Expose the roman numerals (e.g. Instant Health II), rather than the raw amplifier value.
if (p.getAmplifier() > 0) potion.put("potency", p.getAmplifier() + 1);
if (p.isInfiniteDuration()) {
potion.put("duration", Double.POSITIVE_INFINITY);
} else if (p.getDuration() > 1) {
potion.put("duration", p.getDuration() / 20.0 * getPotionDurationMultiplier(stack));
}
return potion;
}).toList();
}
/**
* Get the potion duration multiplier for an item, to handle items which have a shorter duration than a normal
* potion.
*
* @param stack The current stack.
* @return The duration multiplier.
*/
private static double getPotionDurationMultiplier(ItemStack stack) {
if (stack.getItem() instanceof LingeringPotionItem) return 0.25;
if (stack.getItem() instanceof TippedArrowItem) return 0.125;
return 1.0;
}
}
@@ -10,6 +10,7 @@ import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.crafting.RecipeSerializer;
@@ -31,6 +32,7 @@ public final class RegistryWrappers {
public static final RegistryWrapper<BlockEntityType<?>> BLOCK_ENTITY_TYPES = PlatformHelper.get().wrap(Registries.BLOCK_ENTITY_TYPE);
public static final RegistryWrapper<Fluid> FLUIDS = PlatformHelper.get().wrap(Registries.FLUID);
public static final RegistryWrapper<Enchantment> ENCHANTMENTS = PlatformHelper.get().wrap(Registries.ENCHANTMENT);
public static final RegistryWrapper<MobEffect> MOB_EFFECTS = PlatformHelper.get().wrap(Registries.MOB_EFFECT);
public static final RegistryWrapper<ArgumentTypeInfo<?, ?>> COMMAND_ARGUMENT_TYPES = PlatformHelper.get().wrap(Registries.COMMAND_ARGUMENT_TYPE);
public static final RegistryWrapper<RecipeSerializer<?>> RECIPE_SERIALIZERS = PlatformHelper.get().wrap(Registries.RECIPE_SERIALIZER);
public static final RegistryWrapper<MenuType<?>> MENU = PlatformHelper.get().wrap(Registries.MENU);