From 709e8892e85ba9939bd523eb49e89194c6a031f2 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 22 Feb 2021 15:53:13 +0200 Subject: [PATCH] Added tooltips for our own effects --- .../client/ModifierTooltipRenderer.java | 164 ++++++++++++++++++ .../unicopia/client/UnicopiaClient.java | 5 +- .../enchantment/AttributedEnchantment.java | 18 ++ .../item/enchantment/SimpleEnchantment.java | 7 + .../resources/assets/unicopia/lang/en_us.json | 6 +- 5 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java diff --git a/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java new file mode 100644 index 00000000..450172e0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java @@ -0,0 +1,164 @@ +package com.minelittlepony.unicopia.client; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import javax.annotation.Nullable; + +import com.google.common.collect.Multimap; +import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.entity.Living; +import com.minelittlepony.unicopia.entity.player.PlayerAttributes; +import com.minelittlepony.unicopia.item.enchantment.AttributedEnchantment; +import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.attribute.EntityAttribute; +import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.attribute.EntityAttributeModifier.Operation; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; +import net.minecraft.util.Pair; +import net.minecraft.util.registry.Registry; + +public class ModifierTooltipRenderer implements ItemTooltipCallback { + + @Override + public void getTooltip(ItemStack stack, TooltipContext context, List lines) { + + int flags = stack.hasTag() && stack.getTag().contains("HideFlags", 99) ? stack.getTag().getInt("HideFlags") : 0; + + if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS)) { + + Map> modifiers = new HashMap<>(); + + Living living = Equine.of(MinecraftClient.getInstance().player); + getEnchantments(stack).filter(p -> p.getRight() instanceof AttributedEnchantment).forEach(pair -> { + ((AttributedEnchantment)pair.getRight()).getModifiers(living, pair.getLeft(), modifiers); + }); + + modifiers.forEach((slot, modifs) -> { + + List newLines = new ArrayList<>(); + + modifs.entries().stream() + .filter(entry -> entry.getKey().equals(EntityAttributes.GENERIC_MOVEMENT_SPEED) || PlayerAttributes.REGISTRY.contains(entry.getKey())) + .forEach(entry -> describeModifiers(entry.getKey(), entry.getValue(), null, newLines)); + + if (!newLines.isEmpty()) { + Text find = new TranslatableText("item.modifiers." + slot.getName()).formatted(Formatting.GRAY); + int insertPosition = getInsertPosition(stack, find, flags, lines, context.isAdvanced()); + if (insertPosition == -1) { + lines.add(LiteralText.EMPTY); + lines.add(find); + lines.addAll(newLines); + } else { + lines.addAll(insertPosition, newLines); + } + } + }); + } + } + + 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 (insertPosition == -1 && stack.hasTag()) { + if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS) && stack.getTag().getBoolean("Unbreakable")) { + insertPosition = checkFor(lines, new TranslatableText("item.unbreakable").formatted(Formatting.BLUE)); + } + + if (insertPosition == -1 && isShowing(flags, ItemStack.TooltipSection.CAN_DESTROY) && stack.getTag().contains("CanDestroy", 9)) { + insertPosition = checkFor(lines, new TranslatableText("item.canBreak").formatted(Formatting.GRAY)); + } + + if (insertPosition == -1 && isShowing(flags, ItemStack.TooltipSection.CAN_PLACE) && stack.getTag().contains("CanPlaceOn", 9)) { + insertPosition = checkFor(lines, new TranslatableText("item.canPlace").formatted(Formatting.GRAY)); + } + } + + if (insertPosition == -1 && advanced) { + if (stack.isDamaged()) { + insertPosition = checkFor(lines, new TranslatableText("item.durability", stack.getMaxDamage() - stack.getDamage(), stack.getMaxDamage())); + } else { + insertPosition = checkFor(lines, new LiteralText(Registry.ITEM.getId(stack.getItem()).toString()).formatted(Formatting.DARK_GRAY)); + } + } + + return insertPosition; + } + + private int checkFor(List lines, Text category) { + return lines.indexOf(category); + } + + private void describeModifiers(EntityAttribute attribute, EntityAttributeModifier modifier, @Nullable PlayerEntity player, List lines) { + double value = modifier.getValue(); + boolean baseAdjusted = false; + if (player != null) { + value += player.getAttributeBaseValue(attribute); + baseAdjusted = true; + } + + Operation op = modifier.getOperation(); + + double displayValue; + if (op != EntityAttributeModifier.Operation.MULTIPLY_BASE && op != EntityAttributeModifier.Operation.MULTIPLY_TOTAL) { + displayValue = value; + } else { + displayValue = value * 100; + } + + if (baseAdjusted) { + lines.add(new LiteralText(" ").append(getModifierLineBase("equals", displayValue, op, attribute, Formatting.DARK_GREEN))); + } else if (value > 0) { + lines.add(getModifierLineBase("plus", displayValue, op, attribute, attribute == PlayerAttributes.ENTITY_GRAVTY_MODIFIER ? Formatting.RED : Formatting.BLUE)); + } else if (value < 0) { + lines.add(getModifierLineBase("take", -displayValue, op, attribute, attribute == PlayerAttributes.ENTITY_GRAVTY_MODIFIER ? Formatting.BLUE : Formatting.RED)); + } + } + + private Text getModifierLineBase(String root, double displayValue, Operation op, EntityAttribute attribute, Formatting color) { + return new TranslatableText("attribute.modifier." + root + "." + op.getId(), + ItemStack.MODIFIER_FORMAT.format(displayValue), + new TranslatableText(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 -> (CompoundTag)t) + .map(tag -> Registry.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 79d013f0..8dc87935 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java +++ b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.client; import java.util.Optional; - import com.minelittlepony.common.event.ScreenInitCallback; import com.minelittlepony.common.event.ScreenInitCallback.ButtonList; import com.minelittlepony.unicopia.InteractionManager; @@ -11,9 +10,9 @@ import com.minelittlepony.unicopia.client.gui.SettingsScreen; import com.minelittlepony.unicopia.client.gui.UHud; import com.minelittlepony.unicopia.entity.player.PlayerCamera; import com.minelittlepony.unicopia.entity.player.Pony; - 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.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.world.CreateWorldScreen; @@ -57,6 +56,7 @@ public class UnicopiaClient implements ClientModInitializer { ClientTickEvents.END_CLIENT_TICK.register(this::onTick); ScreenInitCallback.EVENT.register(this::onScreenInit); + ItemTooltipCallback.EVENT.register(new ModifierTooltipRenderer()); } private void onTick(MinecraftClient client) { @@ -69,4 +69,5 @@ public class UnicopiaClient implements ClientModInitializer { buttons.add(SettingsScreen.createRaceSelector(screen)); } } + } diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/AttributedEnchantment.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/AttributedEnchantment.java index 64ac79ae..edb150e9 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/AttributedEnchantment.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/AttributedEnchantment.java @@ -2,6 +2,10 @@ package com.minelittlepony.unicopia.item.enchantment; import java.util.HashMap; import java.util.Map; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.minelittlepony.unicopia.AwaitTickQueue; import com.minelittlepony.unicopia.entity.Living; import net.minecraft.enchantment.EnchantmentTarget; @@ -40,6 +44,7 @@ public class AttributedEnchantment extends SimpleEnchantment { instance.removeModifier(modifier.getId()); instance.addPersistentModifier(modifier); }); + entity.calculateDimensions(); } } @@ -52,6 +57,19 @@ public class AttributedEnchantment extends SimpleEnchantment { instance.tryRemoveModifier(modifierSupplier.get(user, 1).getId()); }); user.getEnchants().remove(this); + AwaitTickQueue.scheduleTask(entity.world, w -> { + entity.calculateDimensions(); + }, 1); + } + + public void getModifiers(Living user, int level, Map> output) { + modifiers.forEach((attr, modifierSupplier) -> { + EntityAttributeModifier modif = modifierSupplier.get(user, level); + + for (EquipmentSlot slot : getSlots()) { + output.computeIfAbsent(slot, s -> HashMultimap.create()).put(attr, modif); + } + }); } protected boolean shouldChangeModifiers(Living user, int level) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/SimpleEnchantment.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/SimpleEnchantment.java index fd5ba0d8..cd4da131 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/SimpleEnchantment.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/SimpleEnchantment.java @@ -15,11 +15,14 @@ public class SimpleEnchantment extends Enchantment { private final int maxLevel; + private final EquipmentSlot[] slots; + protected SimpleEnchantment(Rarity rarity, EnchantmentTarget target, boolean cursed, int maxLevel, EquipmentSlot... slots) { super(rarity, target, slots); this.cursed = cursed; this.allItems = false; this.maxLevel = maxLevel; + this.slots = slots; } protected SimpleEnchantment(Rarity rarity, boolean cursed, int maxLevel, EquipmentSlot... slots) { @@ -27,6 +30,7 @@ public class SimpleEnchantment extends Enchantment { this.cursed = cursed; this.allItems = true; this.maxLevel = maxLevel; + this.slots = slots; } public void onUserTick(Living user, int level) { @@ -46,6 +50,9 @@ public class SimpleEnchantment extends Enchantment { return allItems || super.isAcceptableItem(itemStack); } + public EquipmentSlot[] getSlots() { + return slots; + } @Override public int getMaxLevel() { diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 33087a1e..22e72772 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -47,6 +47,10 @@ "effect.food_poisoning": "Food Poisoning", + "player.reachDistance": "Reach Distance", + "player.miningSpeed": "Mining Speed", + "player.gravityModifier": "Gravity", + "effect.unicopia.change_race_earth": "Earth Pony Metamorphosis", "item.minecraft.potion.effect.unicopia.tribe_swap_earth": "Potion of Earth Pony Metamorphosis", "item.minecraft.splash_potion.effect.unicopia.tribe_swap_earth": "Splash Potion of Earth Pony Metamorphosis", @@ -176,7 +180,7 @@ "enchantment.unicopia.gem_finder": "Gem Finder", "enchantment.unicopia.padded": "Padded", "enchantment.unicopia.clingy": "Clings", - "enchantment.unicopia.repulsion": "Repulsive", + "enchantment.unicopia.repulsion": "Repulsion", "enchantment.unicopia.heavy": "Heavy", "enchantment.unicopia.herds": "Herds", "enchantment.unicopia.want_it_need_it": "Want It Need It",