Unicopia/src/main/java/com/minelittlepony/unicopia/client/ModifierTooltipRenderer.java

169 lines
7.3 KiB
Java
Raw Normal View History

2021-02-22 14:53:13 +01:00
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;
2021-08-04 15:38:03 +02:00
import org.jetbrains.annotations.Nullable;
2021-02-22 14:53:13 +01:00
import com.google.common.collect.Multimap;
import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
2021-03-06 22:11:17 +01:00
import com.minelittlepony.unicopia.entity.player.Pony;
2021-02-22 14:53:13 +01:00
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;
2021-08-04 15:38:03 +02:00
import net.minecraft.nbt.NbtCompound;
2022-06-25 00:19:55 +02:00
import net.minecraft.screen.ScreenTexts;
2021-02-22 14:53:13 +01:00
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
2022-12-18 22:07:24 +01:00
import net.minecraft.registry.Registries;
2021-02-22 14:53:13 +01:00
public class ModifierTooltipRenderer implements ItemTooltipCallback {
@Override
public void getTooltip(ItemStack stack, TooltipContext context, List<Text> lines) {
2021-12-22 10:15:09 +01:00
int flags = stack.hasNbt() && stack.getNbt().contains("HideFlags", 99) ? stack.getNbt().getInt("HideFlags") : 0;
2021-02-22 14:53:13 +01:00
if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS)) {
Map<EquipmentSlot, Multimap<EntityAttribute, EntityAttributeModifier>> modifiers = new HashMap<>();
2021-03-06 22:11:17 +01:00
Equine.<PlayerEntity, Pony>of(MinecraftClient.getInstance().player).ifPresent(eq -> {
getEnchantments(stack).filter(p -> p.getRight() instanceof AttributedEnchantment).forEach(pair -> {
((AttributedEnchantment)pair.getRight()).getModifiers(eq, pair.getLeft(), modifiers);
});
2021-02-22 14:53:13 +01:00
});
modifiers.forEach((slot, modifs) -> {
List<Text> newLines = new ArrayList<>();
modifs.entries().stream()
.filter(entry -> entry.getKey().equals(EntityAttributes.GENERIC_MOVEMENT_SPEED) || UEntityAttributes.REGISTRY.contains(entry.getKey()))
2021-02-22 14:53:13 +01:00
.forEach(entry -> describeModifiers(entry.getKey(), entry.getValue(), null, newLines));
if (!newLines.isEmpty()) {
2022-06-25 00:19:55 +02:00
Text find = Text.translatable("item.modifiers." + slot.getName()).formatted(Formatting.GRAY);
2021-02-22 14:53:13 +01:00
int insertPosition = getInsertPosition(stack, find, flags, lines, context.isAdvanced());
if (insertPosition == -1) {
2022-06-25 00:19:55 +02:00
lines.add(ScreenTexts.EMPTY);
2021-02-22 14:53:13 +01:00
lines.add(find);
lines.addAll(newLines);
} else {
lines.addAll(insertPosition, newLines);
}
}
});
}
2021-11-21 17:50:02 +01:00
if (MinecraftClient.getInstance().player != null) {
Pony.of(MinecraftClient.getInstance().player).getDiscoveries().appendTooltip(stack, MinecraftClient.getInstance().world, lines);
}
2021-02-22 14:53:13 +01:00
}
private int getInsertPosition(ItemStack stack, Text category, int flags, List<Text> lines, boolean advanced) {
int insertPosition = lines.indexOf(category);
if (insertPosition > -1) {
return insertPosition + 1;
}
2021-12-22 10:15:09 +01:00
if (insertPosition == -1 && stack.hasNbt()) {
if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS) && stack.getNbt().getBoolean("Unbreakable")) {
2022-06-25 00:19:55 +02:00
insertPosition = checkFor(lines, Text.translatable("item.unbreakable").formatted(Formatting.BLUE));
2021-02-22 14:53:13 +01:00
}
2021-12-22 10:15:09 +01:00
if (insertPosition == -1 && isShowing(flags, ItemStack.TooltipSection.CAN_DESTROY) && stack.getNbt().contains("CanDestroy", 9)) {
2022-06-25 00:19:55 +02:00
insertPosition = checkFor(lines, Text.translatable("item.canBreak").formatted(Formatting.GRAY));
2021-02-22 14:53:13 +01:00
}
2021-12-22 10:15:09 +01:00
if (insertPosition == -1 && isShowing(flags, ItemStack.TooltipSection.CAN_PLACE) && stack.getNbt().contains("CanPlaceOn", 9)) {
2022-06-25 00:19:55 +02:00
insertPosition = checkFor(lines, Text.translatable("item.canPlace").formatted(Formatting.GRAY));
2021-02-22 14:53:13 +01:00
}
}
if (insertPosition == -1 && advanced) {
if (stack.isDamaged()) {
2022-06-25 00:19:55 +02:00
insertPosition = checkFor(lines, Text.translatable("item.durability", stack.getMaxDamage() - stack.getDamage(), stack.getMaxDamage()));
2021-02-22 14:53:13 +01:00
} else {
2022-12-18 22:07:24 +01:00
insertPosition = checkFor(lines, Text.literal(Registries.ITEM.getId(stack.getItem()).toString()).formatted(Formatting.DARK_GRAY));
2021-02-22 14:53:13 +01:00
}
}
return insertPosition;
}
private int checkFor(List<Text> lines, Text category) {
return lines.indexOf(category);
}
private void describeModifiers(EntityAttribute attribute, EntityAttributeModifier modifier, @Nullable PlayerEntity player, List<Text> 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) {
2022-06-25 00:19:55 +02:00
lines.add(Text.literal(" ").append(getModifierLineBase("equals", displayValue, op, attribute, Formatting.DARK_GREEN)));
2021-02-22 14:53:13 +01:00
} else if (value > 0) {
2023-08-07 17:42:51 +02:00
lines.add(getModifierLineBase("plus", displayValue, op, attribute, attribute == UEntityAttributes.ENTITY_GRAVITY_MODIFIER ? Formatting.RED : Formatting.BLUE));
2021-02-22 14:53:13 +01:00
} else if (value < 0) {
2023-08-07 17:42:51 +02:00
lines.add(getModifierLineBase("take", -displayValue, op, attribute, attribute == UEntityAttributes.ENTITY_GRAVITY_MODIFIER ? Formatting.BLUE : Formatting.RED));
2021-02-22 14:53:13 +01:00
}
}
private Text getModifierLineBase(String root, double displayValue, Operation op, EntityAttribute attribute, Formatting color) {
2022-06-25 00:19:55 +02:00
return Text.translatable("attribute.modifier." + root + "." + op.getId(),
2021-02-22 14:53:13 +01:00
ItemStack.MODIFIER_FORMAT.format(displayValue),
2022-06-25 00:19:55 +02:00
Text.translatable(attribute.getTranslationKey())
2021-02-22 14:53:13 +01:00
).formatted(color);
}
private static boolean isShowing(int flags, ItemStack.TooltipSection section) {
return (flags & section.getFlag()) == 0;
}
private static Stream<Pair<Integer, Enchantment>> getEnchantments(ItemStack stack) {
if (!stack.isEmpty()) {
return stack.getEnchantments()
.stream()
2021-08-04 15:38:03 +02:00
.map(t -> (NbtCompound)t)
2022-12-18 22:07:24 +01:00
.map(tag -> Registries.ENCHANTMENT.getOrEmpty(Identifier.tryParse(tag.getString("id")))
2021-02-22 14:53:13 +01:00
.map(ench -> new Pair<>(tag.getInt("lvl"), ench)))
.filter(Optional::isPresent)
.map(Optional::get);
}
return Stream.empty();
}
}