mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Reimplement diet stuff
This commit is contained in:
parent
1601c14d95
commit
0f1c2069e7
28 changed files with 285 additions and 353 deletions
|
@ -28,7 +28,7 @@ public record SpellDuplicatingRecipe (IngredientWithSpell material) implements S
|
||||||
public void buildCraftingTree(CraftingTreeBuilder builder) {
|
public void buildCraftingTree(CraftingTreeBuilder builder) {
|
||||||
ItemStack[] spells = SpellType.REGISTRY.stream()
|
ItemStack[] spells = SpellType.REGISTRY.stream()
|
||||||
.filter(SpellType::isObtainable)
|
.filter(SpellType::isObtainable)
|
||||||
.map(UItems.GEMSTONE::getDefaultStack)
|
.map(i -> EnchantableItem.enchant(UItems.GEMSTONE.getDefaultStack(), i))
|
||||||
.toArray(ItemStack[]::new);
|
.toArray(ItemStack[]::new);
|
||||||
builder.input(UItems.BOTCHED_GEM.getDefaultStack());
|
builder.input(UItems.BOTCHED_GEM.getDefaultStack());
|
||||||
builder.input(spells);
|
builder.input(spells);
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class SpellShapedCraftingRecipe extends ShapedRecipe {
|
||||||
return inventory.getStacks().stream()
|
return inventory.getStacks().stream()
|
||||||
.filter(stack -> stack.getItem() instanceof EnchantableItem)
|
.filter(stack -> stack.getItem() instanceof EnchantableItem)
|
||||||
.filter(EnchantableItem::isEnchanted)
|
.filter(EnchantableItem::isEnchanted)
|
||||||
.map(stack -> ((EnchantableItem)stack.getItem()).getSpellEffect(stack))
|
.map(stack -> EnchantableItem.getSpellEffect(stack))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(spell -> spell.traits().applyTo(EnchantableItem.enchant(super.craft(inventory, registries), spell.type())))
|
.map(spell -> spell.traits().applyTo(EnchantableItem.enchant(super.craft(inventory, registries), spell.type())))
|
||||||
.orElseGet(() -> super.craft(inventory, registries));
|
.orElseGet(() -> super.craft(inventory, registries));
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.client.TextHelper;
|
||||||
import com.minelittlepony.unicopia.entity.effect.EffectUtils;
|
import com.minelittlepony.unicopia.entity.effect.EffectUtils;
|
||||||
|
|
||||||
|
import net.minecraft.item.Item.TooltipContext;
|
||||||
import net.minecraft.item.ItemStack;
|
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.nbt.NbtCompound;
|
||||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||||
import net.minecraft.text.MutableText;
|
import net.minecraft.text.MutableText;
|
||||||
|
@ -27,7 +31,7 @@ public record CustomisedSpellType<T extends Spell> (
|
||||||
SpellType<T> type,
|
SpellType<T> type,
|
||||||
SpellTraits traits,
|
SpellTraits traits,
|
||||||
Supplier<SpellTraits> traitsDifferenceSupplier
|
Supplier<SpellTraits> traitsDifferenceSupplier
|
||||||
) implements SpellPredicate<T> {
|
) implements SpellPredicate<T>, TooltipAppender {
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return type.isEmpty();
|
return type.isEmpty();
|
||||||
|
@ -86,25 +90,25 @@ public record CustomisedSpellType<T extends Spell> (
|
||||||
return traits.applyTo(type.getDefualtStack());
|
return traits.applyTo(type.getDefualtStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void appendTooltip(List<Text> lines) {
|
@Override
|
||||||
|
public void appendTooltip(TooltipContext context, Consumer<Text> tooltip, TooltipType type) {
|
||||||
MutableText lore = Text.translatable(type().getTranslationKey() + ".lore").formatted(type().getAffinity().getColor());
|
MutableText lore = Text.translatable(type().getTranslationKey() + ".lore").formatted(type().getAffinity().getColor());
|
||||||
|
|
||||||
if (!InteractionManager.getInstance().getClientSpecies().canCast()) {
|
if (!InteractionManager.getInstance().getClientSpecies().canCast()) {
|
||||||
lore = lore.formatted(Formatting.OBFUSCATED);
|
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();
|
float corruption = ((int)traits().getCorruption() * 10) + type().getAffinity().getCorruption();
|
||||||
List<Text> modifiers = new ArrayList<>();
|
List<Text> modifiers = new ArrayList<>();
|
||||||
type.getTooltip().appendTooltip(this, modifiers);
|
type().getTooltip().appendTooltip(this, modifiers);
|
||||||
if (corruption != 0) {
|
if (corruption != 0) {
|
||||||
modifiers.add(EffectUtils.formatModifierChange("affinity.unicopia.corruption", corruption, true));
|
modifiers.add(EffectUtils.formatModifierChange("affinity.unicopia.corruption", corruption, true));
|
||||||
}
|
}
|
||||||
if (!modifiers.isEmpty()) {
|
if (!modifiers.isEmpty()) {
|
||||||
lines.add(Text.empty());
|
tooltip.accept(Text.empty());
|
||||||
lines.add(Text.translatable("affinity.unicopia.when_cast").formatted(Formatting.GRAY));
|
tooltip.accept(Text.translatable("affinity.unicopia.when_cast").formatted(Formatting.GRAY));
|
||||||
lines.addAll(modifiers);
|
modifiers.forEach(tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedActionResult<CustomisedSpellType<?>> toAction() {
|
public TypedActionResult<CustomisedSpellType<?>> toAction() {
|
||||||
|
|
|
@ -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.TimeControlAbilitySpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
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.GemstoneItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.util.RegistryUtils;
|
import com.minelittlepony.unicopia.util.RegistryUtils;
|
||||||
|
@ -117,7 +118,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
this.traits = traits;
|
this.traits = traits;
|
||||||
this.stackable = stackable;
|
this.stackable = stackable;
|
||||||
traited = new CustomisedSpellType<>(this, traits, SpellTraits::empty);
|
traited = new CustomisedSpellType<>(this, traits, SpellTraits::empty);
|
||||||
defaultStack = UItems.GEMSTONE.getDefaultStack(this);
|
defaultStack = EnchantableItem.enchant(UItems.GEMSTONE.getDefaultStack(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isObtainable() {
|
public boolean isObtainable() {
|
||||||
|
|
|
@ -9,8 +9,6 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.network.Channel;
|
import com.minelittlepony.unicopia.network.Channel;
|
||||||
|
@ -33,7 +31,6 @@ import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery> {
|
public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery> {
|
||||||
private final Set<Trait> unreadTraits = new HashSet<>();
|
private final Set<Trait> unreadTraits = new HashSet<>();
|
||||||
|
@ -114,7 +111,7 @@ public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip) {
|
public void appendTooltip(ItemStack stack, List<Text> tooltip) {
|
||||||
SpellTraits.getEmbeddedTraits(stack)
|
SpellTraits.getEmbeddedTraits(stack)
|
||||||
.orElseGet(() -> getKnownTraits(stack.getItem()))
|
.orElseGet(() -> getKnownTraits(stack.getItem()))
|
||||||
.appendTooltip(tooltip);
|
.appendTooltip(tooltip);
|
||||||
|
|
|
@ -1,146 +1,52 @@
|
||||||
package com.minelittlepony.unicopia.client;
|
package com.minelittlepony.unicopia.client;
|
||||||
|
|
||||||
import java.util.List;
|
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 com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||||
import net.minecraft.client.MinecraftClient;
|
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.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.tooltip.TooltipAppender;
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
import net.minecraft.item.tooltip.TooltipType;
|
||||||
import net.minecraft.text.Text;
|
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 context, @Nullable PlayerEntity player, TooltipType type, List<Text> lines) {
|
||||||
public void getTooltip(ItemStack stack, Item.TooltipContext tooltipContext, TooltipType tooltipType, List<Text> lines) {
|
@Nullable
|
||||||
|
Pony pony = Pony.of(player);
|
||||||
|
|
||||||
// TODO: Evaluate if we still need this
|
if (pony != null) {
|
||||||
/*int flags = stack.hasNbt() && stack.getNbt().contains("HideFlags", 99) ? stack.getNbt().getInt("HideFlags") : 0;
|
pony.getDiscoveries().appendTooltip(stack, lines);
|
||||||
|
|
||||||
if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS)) {
|
|
||||||
|
|
||||||
Enchantment s;
|
|
||||||
Map<EquipmentSlot, Multimap<EntityAttribute, EntityAttributeModifier>> modifiers = new HashMap<>();
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
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()))
|
|
||||||
.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<Text> lines, boolean advanced) {
|
|
||||||
int insertPosition = lines.indexOf(category);
|
|
||||||
|
|
||||||
if (insertPosition > -1) {
|
|
||||||
return insertPosition + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insertPosition == -1 && stack.hasNbt()) {
|
Consumer<Text> textConsumer = lines::add;
|
||||||
if (isShowing(flags, ItemStack.TooltipSection.MODIFIERS) && stack.getNbt().getBoolean("Unbreakable")) {
|
|
||||||
insertPosition = checkFor(lines, Text.translatable("item.unbreakable").formatted(Formatting.BLUE));
|
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 && isShowing(flags, ItemStack.TooltipSection.CAN_DESTROY) && stack.getNbt().contains("CanDestroy", 9)) {
|
PonyDiets.getInstance().getDiet(pony).appendTooltip(stack, pony, lines, type);
|
||||||
insertPosition = checkFor(lines, Text.translatable("item.canBreak").formatted(Formatting.GRAY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insertPosition == -1 && isShowing(flags, ItemStack.TooltipSection.CAN_PLACE) && stack.getNbt().contains("CanPlaceOn", 9)) {
|
private <T extends TooltipAppender> void appendTooltip(ItemStack stack, ComponentType<T> componentType, Item.TooltipContext context, Consumer<Text> textConsumer, TooltipType type) {
|
||||||
insertPosition = checkFor(lines, Text.translatable("item.canPlace").formatted(Formatting.GRAY));
|
T tooltipAppender = stack.get(componentType);
|
||||||
|
if (tooltipAppender != null) {
|
||||||
|
tooltipAppender.appendTooltip(context, textConsumer, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int checkFor(List<Text> lines, Text category) {
|
|
||||||
return lines.indexOf(category);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void describeModifiers(RegistryEntry<EntityAttribute> attribute, EntityAttributeModifier modifier, @Nullable PlayerEntity player, List<Text> 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 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<Pair<Integer, Enchantment>> 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();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import com.minelittlepony.unicopia.util.Lerp;
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
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.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.screen.OpenToLanScreen;
|
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_CLIENT_TICK.register(this::onTick);
|
||||||
ClientTickEvents.END_WORLD_TICK.register(this::onWorldTick);
|
ClientTickEvents.END_WORLD_TICK.register(this::onWorldTick);
|
||||||
ScreenInitCallback.EVENT.register(this::onScreenInit);
|
ScreenInitCallback.EVENT.register(this::onScreenInit);
|
||||||
ItemTooltipCallback.EVENT.register(new ModifierTooltipRenderer());
|
|
||||||
|
|
||||||
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(ViewportShader.INSTANCE);
|
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(ViewportShader.INSTANCE);
|
||||||
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(SpellEffectsRenderDispatcher.INSTANCE);
|
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(SpellEffectsRenderDispatcher.INSTANCE);
|
||||||
|
|
|
@ -19,6 +19,8 @@ import net.minecraft.client.gui.*;
|
||||||
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
|
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
|
||||||
import net.minecraft.client.sound.PositionedSoundInstance;
|
import net.minecraft.client.sound.PositionedSoundInstance;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
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.screen.ScreenTexts;
|
||||||
import net.minecraft.text.MutableText;
|
import net.minecraft.text.MutableText;
|
||||||
import net.minecraft.text.Text;
|
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));
|
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.spell_type", name));
|
||||||
type.traits().appendTooltip(tooltip);
|
type.traits().appendTooltip(tooltip);
|
||||||
tooltip.add(ScreenTexts.EMPTY);
|
tooltip.add(ScreenTexts.EMPTY);
|
||||||
type.appendTooltip(tooltip);
|
type.appendTooltip(TooltipContext.create(client.world), tooltip::add, TooltipType.BASIC);
|
||||||
tooltip.add(ScreenTexts.EMPTY);
|
tooltip.add(ScreenTexts.EMPTY);
|
||||||
if (spell instanceof TimedSpell timed) {
|
if (spell instanceof TimedSpell timed) {
|
||||||
tooltip.add(ScreenTexts.EMPTY);
|
tooltip.add(ScreenTexts.EMPTY);
|
||||||
|
|
|
@ -32,6 +32,8 @@ import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
|
||||||
import net.minecraft.client.render.GameRenderer;
|
import net.minecraft.client.render.GameRenderer;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
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.screen.slot.Slot;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
@ -209,7 +211,7 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> imple
|
||||||
|
|
||||||
List<Text> tooltip = new ArrayList<>();
|
List<Text> tooltip = new ArrayList<>();
|
||||||
tooltip.add(spell.type().getName());
|
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.drawTooltip(textRenderer, tooltip, x, y);
|
||||||
context.getMatrices().pop();
|
context.getMatrices().pop();
|
||||||
|
|
|
@ -103,11 +103,10 @@ public class Main implements EmiPlugin {
|
||||||
.filter(recipe -> recipe.value() instanceof SpellShapedCraftingRecipe)
|
.filter(recipe -> recipe.value() instanceof SpellShapedCraftingRecipe)
|
||||||
.forEach(recipe -> {
|
.forEach(recipe -> {
|
||||||
ItemStack output = recipe.value().getResult(registries);
|
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 -> {
|
multiItem.getDefaultStacks().forEach(outputVariation -> {
|
||||||
var spellEffect = enchantable.getSpellEffect(outputVariation);
|
if (EnchantableItem.isEnchanted(outputVariation)) {
|
||||||
if (!spellEffect.isEmpty()) {
|
registry.addRecipe(new MagicalShapedEmiRecipe(recipe, EnchantableItem.getSpellEffect(outputVariation), outputVariation));
|
||||||
registry.addRecipe(new MagicalShapedEmiRecipe(recipe, spellEffect, outputVariation));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,12 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.item.ItemDuck;
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
import net.minecraft.component.DataComponentTypes;
|
import net.minecraft.component.DataComponentTypes;
|
||||||
import net.minecraft.component.type.FoodComponent;
|
import net.minecraft.component.type.FoodComponent;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
import net.minecraft.item.tooltip.TooltipType;
|
||||||
import net.minecraft.network.RegistryByteBuf;
|
import net.minecraft.network.RegistryByteBuf;
|
||||||
|
@ -80,7 +78,7 @@ public record DietProfile(
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isForaged(ItemStack stack) {
|
static boolean isForaged(ItemStack stack) {
|
||||||
return ((ItemDuck)stack.getItem()).getOriginalFoodComponent().isEmpty();
|
return stack.getComponents().get(DataComponentTypes.FOOD) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -125,10 +123,17 @@ public record DietProfile(
|
||||||
return Pair.of(hungerMultiplier, saturationMultiplier);
|
return Pair.of(hungerMultiplier, saturationMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> tooltip, TooltipType context) {
|
public void appendTooltip(ItemStack stack, @Nullable Pony pony, List<Text> tooltip, TooltipType context) {
|
||||||
var food = stack.get(DataComponentTypes.FOOD);
|
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);
|
var ratios = getRatios(stack);
|
||||||
|
|
||||||
if (food == null || isInedible(ratios)) {
|
if (food == null || isInedible(ratios)) {
|
||||||
if (stack.getUseAction() != UseAction.DRINK) {
|
if (stack.getUseAction() != UseAction.DRINK) {
|
||||||
tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.not_edible")).formatted(Formatting.DARK_GRAY));
|
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());
|
float baseMultiplier = (isForaged(stack) ? foragingMultiplier() : defaultMultiplier());
|
||||||
|
|
||||||
if (context.isAdvanced()) {
|
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.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.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));
|
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<FoodComponent> getNonAdjustedFoodComponent(ItemStack stack, @Nullable PlayerEntity user) {
|
private Optional<FoodComponent> getNonAdjustedFoodComponent(ItemStack stack, @Nullable Pony pony) {
|
||||||
@Nullable
|
FoodComponent food = stack.getComponents().get(DataComponentTypes.FOOD);
|
||||||
Pony pony = Pony.of(user);
|
|
||||||
Optional<FoodComponent> food = ((ItemDuck)stack.getItem()).getOriginalFoodComponent();
|
|
||||||
|
|
||||||
if (food.isEmpty() && pony.getObservedSpecies().hasIronGut()) {
|
if (food != null) {
|
||||||
|
return Optional.ofNullable(food);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pony != null && pony.getObservedSpecies().hasIronGut()) {
|
||||||
return findEffect(stack)
|
return findEffect(stack)
|
||||||
.flatMap(Effect::foodComponent)
|
.flatMap(Effect::foodComponent)
|
||||||
.or(() -> PonyDiets.getInstance().getEffects(stack).foodComponent());
|
.or(() -> PonyDiets.getInstance().getEffects(stack).foodComponent());
|
||||||
}
|
}
|
||||||
|
|
||||||
return food;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Multiplier(
|
public record Multiplier(
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
package com.minelittlepony.unicopia.diet;
|
package com.minelittlepony.unicopia.diet;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
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.Hand;
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -16,12 +11,4 @@ public interface DietView {
|
||||||
TypedActionResult<ItemStack> startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand);
|
TypedActionResult<ItemStack> startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand);
|
||||||
|
|
||||||
void finishUsing(ItemStack stack, World world, LivingEntity entity);
|
void finishUsing(ItemStack stack, World world, LivingEntity entity);
|
||||||
|
|
||||||
void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> tooltip, TooltipType context);
|
|
||||||
|
|
||||||
interface Holder {
|
|
||||||
default DietView getDiets(ItemStack stack) {
|
|
||||||
return PonyDiets.getInstance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.diet;
|
package com.minelittlepony.unicopia.diet;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -9,19 +8,14 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.entity.effect.FoodPoisoningStatusEffect;
|
import com.minelittlepony.unicopia.entity.effect.FoodPoisoningStatusEffect;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.item.ItemDuck;
|
|
||||||
import com.minelittlepony.unicopia.util.serialization.PacketCodecUtils;
|
import com.minelittlepony.unicopia.util.serialization.PacketCodecUtils;
|
||||||
|
|
||||||
import net.minecraft.component.DataComponentTypes;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
|
||||||
import net.minecraft.network.RegistryByteBuf;
|
import net.minecraft.network.RegistryByteBuf;
|
||||||
import net.minecraft.network.codec.PacketCodec;
|
import net.minecraft.network.codec.PacketCodec;
|
||||||
import net.minecraft.network.codec.PacketCodecs;
|
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.Hand;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
@ -57,11 +51,11 @@ public class PonyDiets implements DietView {
|
||||||
this.effects = effects;
|
this.effects = effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DietProfile getDiet(Pony pony) {
|
public DietProfile getDiet(Pony pony) {
|
||||||
return Optional.ofNullable(diets.get(pony.getObservedSpecies())).orElse(DietProfile.EMPTY);
|
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);
|
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
|
@Override
|
||||||
public TypedActionResult<ItemStack> startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand) {
|
public TypedActionResult<ItemStack> startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand) {
|
||||||
return initEdibility(stack, user)
|
return FoodPoisoningStatusEffect.apply(stack, user);
|
||||||
? FoodPoisoningStatusEffect.apply(stack, user)
|
|
||||||
: TypedActionResult.fail(stack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishUsing(ItemStack stack, World world, LivingEntity entity) {
|
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));
|
Pony.of(entity).ifPresent(pony -> getEffects(stack, pony).ailment().effects().afflict(pony.asEntity(), stack));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ public class AmuletItem extends WearableItem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> list, TooltipType type) {
|
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> list, TooltipType type) {
|
||||||
|
|
||||||
for (StringVisitable line : MinecraftClient.getInstance().textRenderer.getTextHandler().wrapLines(
|
for (StringVisitable line : MinecraftClient.getInstance().textRenderer.getTextHandler().wrapLines(
|
||||||
Text.translatable(getTranslationKey(stack) + ".lore"), 150, Style.EMPTY)) {
|
Text.translatable(getTranslationKey(stack) + ".lore"), 150, Style.EMPTY)) {
|
||||||
MutableText compiled = Text.literal("").formatted(Formatting.ITALIC, Formatting.GRAY);
|
MutableText compiled = Text.literal("").formatted(Formatting.ITALIC, Formatting.GRAY);
|
||||||
|
@ -51,8 +50,7 @@ public class AmuletItem extends WearableItem {
|
||||||
});
|
});
|
||||||
list.add(compiled);
|
list.add(compiled);
|
||||||
}
|
}
|
||||||
|
super.appendTooltip(stack, context, list, type);
|
||||||
Charges.of(stack).appendTooltip(context, list::add, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.entity.Creature;
|
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.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
|
||||||
import net.minecraft.particle.ParticleEffect;
|
import net.minecraft.particle.ParticleEffect;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
@ -43,11 +40,6 @@ public class BellItem extends Item {
|
||||||
return UseAction.BOW;
|
return UseAction.BOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> list, TooltipType type) {
|
|
||||||
Charges.of(stack).appendTooltip(context, list::add, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxUseTime(ItemStack stack, LivingEntity user) {
|
public int getMaxUseTime(ItemStack stack, LivingEntity user) {
|
||||||
return 3000;
|
return 3000;
|
||||||
|
|
|
@ -19,12 +19,7 @@ import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
|
||||||
public interface EnchantableItem extends ItemConvertible {
|
public interface EnchantableItem extends ItemConvertible {
|
||||||
|
static CustomisedSpellType<?> getSpellEffect(ItemStack stack) {
|
||||||
default ItemStack getDefaultStack(SpellType<?> spell) {
|
|
||||||
return enchant(asItem().getDefaultStack(), spell);
|
|
||||||
}
|
|
||||||
|
|
||||||
default CustomisedSpellType<?> getSpellEffect(ItemStack stack) {
|
|
||||||
return EnchantableItem.getSpellKey(stack).withTraits(SpellTraits.of(stack));
|
return EnchantableItem.getSpellKey(stack).withTraits(SpellTraits.of(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,6 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu
|
||||||
SpellType<?> key = EnchantableItem.getSpellKey(stack);
|
SpellType<?> key = EnchantableItem.getSpellKey(stack);
|
||||||
lines.add(Text.translatable(key.getTranslationKey()).formatted(key.getAffinity().getColor()));
|
lines.add(Text.translatable(key.getTranslationKey()).formatted(key.getAffinity().getColor()));
|
||||||
}
|
}
|
||||||
Charges.of(stack).appendTooltip(context, lines::add, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -144,7 +143,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu
|
||||||
Pony.of(entity).ifPresent(pony -> {
|
Pony.of(entity).ifPresent(pony -> {
|
||||||
pony.subtractEnergyCost(4);
|
pony.subtractEnergyCost(4);
|
||||||
stack.damage(1, pony.asEntity(), EquipmentSlot.MAINHAND);
|
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);
|
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.of(entity).ifPresent(pony -> {
|
||||||
pony.subtractEnergyCost(4);
|
pony.subtractEnergyCost(4);
|
||||||
stack.damage(1, pony.asEntity(), EquipmentSlot.MAINHAND);
|
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);
|
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)) {
|
if (attacker.isSneaking() && Charges.discharge(stack, 1)) {
|
||||||
stack.damage(50, attacker, EquipmentSlot.MAINHAND);
|
stack.damage(50, attacker, EquipmentSlot.MAINHAND);
|
||||||
Caster.of(attacker).ifPresent(c -> c.subtractEnergyCost(4));
|
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;
|
return false;
|
||||||
|
@ -193,7 +192,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Mu
|
||||||
living.clearActiveItem();
|
living.clearActiveItem();
|
||||||
living.damage(entity.getDamageSources().magic(), 1);
|
living.damage(entity.getDamageSources().magic(), 1);
|
||||||
if (EnchantableItem.isEnchanted(stack) && Charges.discharge(stack, 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
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.AmuletSelectors;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.item.component.Issuer;
|
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.Entity;
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
|
||||||
import net.minecraft.stat.Stats;
|
import net.minecraft.stat.Stats;
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.*;
|
import net.minecraft.util.*;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
@ -69,18 +62,6 @@ public class FriendshipBraceletItem extends WearableItem {
|
||||||
return super.use(world, player, hand);
|
return super.use(world, player, hand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Environment(EnvType.CLIENT)
|
|
||||||
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> 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
|
@Override
|
||||||
public EquipmentSlot getSlotType(ItemStack stack) {
|
public EquipmentSlot getSlotType(ItemStack stack) {
|
||||||
return Issuer.isSigned(stack) ? EquipmentSlot.CHEST : super.getSlotType(stack);
|
return Issuer.isSigned(stack) ? EquipmentSlot.CHEST : super.getSlotType(stack);
|
||||||
|
|
|
@ -14,13 +14,12 @@ import com.minelittlepony.unicopia.item.group.MultiItem;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class GemstoneItem extends Item implements MultiItem, EnchantableItem {
|
public class GemstoneItem extends Item implements MultiItem {
|
||||||
|
|
||||||
public GemstoneItem(Settings settings) {
|
public GemstoneItem(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
@ -71,15 +70,6 @@ public class GemstoneItem extends Item implements MultiItem, EnchantableItem {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> lines, TooltipType type) {
|
|
||||||
super.appendTooltip(stack, context, lines, type);
|
|
||||||
|
|
||||||
if (EnchantableItem.isEnchanted(stack)) {
|
|
||||||
getSpellEffect(stack).appendTooltip(lines);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ItemStack> getDefaultStacks() {
|
public List<ItemStack> getDefaultStacks() {
|
||||||
return SpellType.REGISTRY.stream()
|
return SpellType.REGISTRY.stream()
|
||||||
|
|
|
@ -1,24 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.diet.DietView;
|
|
||||||
import com.minelittlepony.unicopia.entity.ItemImpl;
|
import com.minelittlepony.unicopia.entity.ItemImpl;
|
||||||
|
|
||||||
import net.minecraft.component.type.FoodComponent;
|
|
||||||
import net.minecraft.item.*;
|
import net.minecraft.item.*;
|
||||||
|
|
||||||
public interface ItemDuck extends ItemConvertible, ItemImpl.TickableItem, DietView.Holder {
|
public interface ItemDuck extends ItemConvertible, ItemImpl.TickableItem {
|
||||||
@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<FoodComponent> getOriginalFoodComponent();
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
default void resetFoodComponent() {
|
|
||||||
setFoodComponent(getOriginalFoodComponent().orElse(null));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<ItemStack, ?, ?> 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<ComponentType<?>, BiFunction<ItemStack, ?, ?>> components = new HashMap<>();
|
||||||
|
|
||||||
|
private Optional<Entity> carrier = Optional.empty();
|
||||||
|
|
||||||
|
private TransientComponentMap() {}
|
||||||
|
|
||||||
|
public Optional<Entity> getCarrier() {
|
||||||
|
return carrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCarrier(@Nullable Entity carrier) {
|
||||||
|
this.carrier = Optional.ofNullable(carrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void set(ComponentType<? extends T> type, BiFunction<ItemStack, T, T> getter) {
|
||||||
|
components.put(type, getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> T get(ComponentType<? extends T> type, ItemStack stack, T upstreamValue) {
|
||||||
|
return ((BiFunction<ItemStack, T, T>)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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
import com.minelittlepony.unicopia.container.SpellbookState;
|
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.AirBalloonEntity;
|
||||||
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
@ -25,6 +26,7 @@ public interface UDataComponentTypes {
|
||||||
ComponentType<Issuer> ISSUER = register("issuer", builder -> builder.codec(Issuer.CODEC).packetCodec(Issuer.PACKET_CODEC).cache());
|
ComponentType<Issuer> ISSUER = register("issuer", builder -> builder.codec(Issuer.CODEC).packetCodec(Issuer.PACKET_CODEC).cache());
|
||||||
ComponentType<Charges> CHARGES = register("charges", builder -> builder.codec(Charges.CODEC).packetCodec(Charges.PACKET_CODEC));
|
ComponentType<Charges> CHARGES = register("charges", builder -> builder.codec(Charges.CODEC).packetCodec(Charges.PACKET_CODEC));
|
||||||
ComponentType<Appearance> APPEARANCE = register("appearance", builder -> builder.codec(Appearance.CODEC).packetCodec(Appearance.PACKET_CODEC));
|
ComponentType<Appearance> APPEARANCE = register("appearance", builder -> builder.codec(Appearance.CODEC).packetCodec(Appearance.PACKET_CODEC));
|
||||||
|
ComponentType<DietProfile> DIET_PROFILE = register("diet_profile", builder -> builder.codec(DietProfile.CODEC).packetCodec(DietProfile.PACKET_CODEC));
|
||||||
|
|
||||||
private static <T> ComponentType<T> register(String name, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
|
private static <T> ComponentType<T> register(String name, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
|
||||||
return Registry.register(Registries.DATA_COMPONENT_TYPE, Unicopia.id(name), builderOperator.apply(ComponentType.builder()).build());
|
return Registry.register(Registries.DATA_COMPONENT_TYPE, Unicopia.id(name), builderOperator.apply(ComponentType.builder()).build());
|
||||||
|
|
|
@ -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> enchantment);
|
|
||||||
}
|
|
|
@ -2,36 +2,19 @@ package com.minelittlepony.unicopia.mixin;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import com.google.common.base.Suppliers;
|
|
||||||
import com.minelittlepony.unicopia.entity.ItemImpl;
|
import com.minelittlepony.unicopia.entity.ItemImpl;
|
||||||
import com.minelittlepony.unicopia.entity.ItemImpl.GroundTickCallback;
|
import com.minelittlepony.unicopia.entity.ItemImpl.GroundTickCallback;
|
||||||
import com.minelittlepony.unicopia.item.ItemDuck;
|
import com.minelittlepony.unicopia.item.ItemDuck;
|
||||||
|
|
||||||
import net.minecraft.component.DataComponentTypes;
|
|
||||||
import net.minecraft.component.type.FoodComponent;
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
|
||||||
@Mixin(Item.class)
|
@Mixin(Item.class)
|
||||||
abstract class MixinItem implements ItemDuck {
|
abstract class MixinItem implements ItemDuck {
|
||||||
private final List<ItemImpl.GroundTickCallback> tickCallbacks = new ArrayList<>();
|
private final List<ItemImpl.GroundTickCallback> tickCallbacks = new ArrayList<>();
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private final Supplier<Optional<FoodComponent>> originalFoodComponent = Suppliers.memoize(() -> {
|
|
||||||
return Optional.ofNullable(((Item)(Object)this).getComponents().get(DataComponentTypes.FOOD));
|
|
||||||
});
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<GroundTickCallback> getCallbacks() {
|
public List<GroundTickCallback> getCallbacks() {
|
||||||
return tickCallbacks;
|
return tickCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public Optional<FoodComponent> getOriginalFoodComponent() {
|
|
||||||
return originalFoodComponent.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,89 @@
|
||||||
package com.minelittlepony.unicopia.mixin;
|
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.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
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.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.LivingEntity;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
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.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@Mixin(ItemStack.class)
|
@Mixin(ItemStack.class)
|
||||||
abstract class MixinItemStack {
|
abstract class MixinItemStack implements ItemStackDuck {
|
||||||
|
private final TransientComponentMap transientComponents = TransientComponentMap.INITIAL.createCopy();
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
abstract <T extends TooltipAppender> void appendTooltip(
|
||||||
|
ComponentType<T> componentType, Item.TooltipContext context, Consumer<Text> textConsumer, TooltipType type
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransientComponentMap getTransientComponents() {
|
||||||
|
return transientComponents;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "use", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "use", at = @At("HEAD"), cancellable = true)
|
||||||
private void onUse(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> info) {
|
private void onUse(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> info) {
|
||||||
ItemStack self = (ItemStack)(Object)this;
|
transientComponents.setCarrier(user);
|
||||||
TypedActionResult<ItemStack> result = ((DietView.Holder)self.getItem()).getDiets(self).startUsing(self, world, user, hand);
|
TypedActionResult<ItemStack> result = PonyDiets.getInstance().startUsing((ItemStack)(Object)this, world, user, hand);
|
||||||
if (result.getResult() != ActionResult.PASS) {
|
if (result.getResult() != ActionResult.PASS) {
|
||||||
info.setReturnValue(result);
|
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"))
|
@Inject(method = "finishUsing", at = @At("HEAD"))
|
||||||
private void onFinishUsing(World world, LivingEntity user, CallbackInfoReturnable<ItemStack> info) {
|
private void beforeFinishUsing(World world, LivingEntity user, CallbackInfoReturnable<ItemStack> info) {
|
||||||
ItemStack self = (ItemStack)(Object)this;
|
transientComponents.setCarrier(user);
|
||||||
((DietView.Holder)self.getItem()).getDiets(self).finishUsing(self, world, user);
|
PonyDiets.getInstance().finishUsing((ItemStack)(Object)this, world, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "finishUsing", at = @At("RETURN"))
|
||||||
|
private void afterFinishUsing(World world, LivingEntity user, CallbackInfoReturnable<ItemStack> info) {
|
||||||
|
transientComponents.setCarrier(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "getTooltip", at = @At("HEAD"))
|
||||||
|
public void beforeGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable<List<Text>> info) {
|
||||||
|
transientComponents.setCarrier(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "getTooltip", at = @At("RETURN"))
|
||||||
|
public void afterGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable<List<Text>> 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<List<Text>> info) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "takesDamageFrom", at = @At("HEAD"))
|
@Inject(method = "takesDamageFrom", at = @At("HEAD"))
|
||||||
|
@ -41,4 +93,28 @@ abstract class MixinItemStack {
|
||||||
info.setReturnValue(checker.takesDamageFrom(source));
|
info.setReturnValue(checker.takesDamageFrom(source));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "get", at = @At("RETURN"))
|
||||||
|
private <T> void unicopia_onGet(ComponentType<? extends T> type, CallbackInfoReturnable<T> 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 <T> void unicopia_onGetOrDefault(ComponentType<? extends T> type, T fallback, CallbackInfoReturnable<T> 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<Boolean> info) {
|
||||||
|
Object o = this;
|
||||||
|
if (o instanceof ItemStack stack && ItemStackDuck.of(stack).getTransientComponents().get(type, stack, null) != null) {
|
||||||
|
info.setReturnValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<List<Text>> info) {
|
|
||||||
ItemStack self = (ItemStack)(Object)this;
|
|
||||||
((DietView.Holder)self.getItem()).getDiets(self).appendTooltip(self, player, info.getReturnValue(), type);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -94,7 +94,6 @@
|
||||||
"client.MixinInGameHud",
|
"client.MixinInGameHud",
|
||||||
"client.MixinInGameHud$HeartType",
|
"client.MixinInGameHud$HeartType",
|
||||||
"client.MixinItemModels",
|
"client.MixinItemModels",
|
||||||
"client.MixinItemStack",
|
|
||||||
"client.MixinKeyboardInput",
|
"client.MixinKeyboardInput",
|
||||||
"client.MixinLivingEntityRenderer",
|
"client.MixinLivingEntityRenderer",
|
||||||
"client.MixinMinecraftClient",
|
"client.MixinMinecraftClient",
|
||||||
|
|
Loading…
Reference in a new issue