Updating to 1.21 (part 3)

This commit is contained in:
Sollace 2024-09-28 22:27:46 +01:00
parent 259b0cddc4
commit 433149cc99
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
139 changed files with 1446 additions and 1531 deletions

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia; package com.minelittlepony.unicopia;
import net.fabricmc.fabric.api.tag.convention.v2.ConventionalBlockTags;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
@ -9,8 +10,8 @@ import net.minecraft.util.Identifier;
public interface UConventionalTags { public interface UConventionalTags {
interface Blocks { interface Blocks {
TagKey<Block> CONCRETE_POWDERS = block("concrete_powders"); TagKey<Block> CONCRETE_POWDERS = block("concrete_powders");
TagKey<Block> CONCRETES = block("concretes"); TagKey<Block> CONCRETES = ConventionalBlockTags.CONCRETES;
TagKey<Block> GLAZED_TERRACOTTAS = block("glazed_terracottas"); TagKey<Block> GLAZED_TERRACOTTAS = ConventionalBlockTags.GLAZED_TERRACOTTAS;
TagKey<Block> CORAL_BLOCKS = block("coral_blocks"); TagKey<Block> CORAL_BLOCKS = block("coral_blocks");
TagKey<Block> CORAL_FANS = block("coral_fans"); TagKey<Block> CORAL_FANS = block("coral_fans");
TagKey<Block> CORALS = block("corals"); TagKey<Block> CORALS = block("corals");

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia; package com.minelittlepony.unicopia;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.world.World; import net.minecraft.world.World;
public interface WorldConvertable { public interface WorldConvertable {
@ -14,4 +16,8 @@ public interface WorldConvertable {
default boolean isClient() { default boolean isClient() {
return asWorld().isClient(); return asWorld().isClient();
} }
default <T> RegistryEntry<T> entryFor(RegistryKey<T> key) {
return asWorld().getRegistryManager().get(key.getRegistryRef()).getEntry(key).orElseThrow();
}
} }

View file

@ -2,20 +2,21 @@ package com.minelittlepony.unicopia.ability.data.tree;
import java.util.*; import java.util.*;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.util.CodecUtils;
import com.minelittlepony.unicopia.util.Resources; import com.minelittlepony.unicopia.util.Resources;
import com.minelittlepony.unicopia.util.Weighted; import com.minelittlepony.unicopia.util.Weighted;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.resource.JsonDataLoader; import net.minecraft.resource.JsonDataLoader;
import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -45,35 +46,47 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
return ID; return ID;
} }
@SuppressWarnings("unchecked")
@Override @Override
protected void apply(Map<Identifier, JsonElement> resources, ResourceManager manager, Profiler profiler) { protected void apply(Map<Identifier, JsonElement> resources, ResourceManager manager, Profiler profiler) {
entries = resources.entrySet().stream().filter(Objects::nonNull) entries = Map.ofEntries(resources.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> { .filter(Objects::nonNull)
try { .map(entry -> TreeTypeDef.CODEC.decode(JsonOps.INSTANCE, entry.getValue())
return Resources.GSON.fromJson(entry.getValue(), TreeTypeDef.class); .result()
} catch (IllegalArgumentException | JsonParseException e) { .map(p -> p.getFirst())
return null; .map(p -> Map.entry(entry.getKey(), p))
} .orElse(null))
})); .filter(Objects::nonNull)
.toArray(Map.Entry[]::new));
TreeTypes.load(entries); TreeTypes.load(entries);
} }
public static final class TreeTypeDef { public record TreeTypeDef (
final Set<Identifier> logs; Set<Identifier> logs,
final Set<Identifier> leaves; Set<Identifier> leaves,
final Set<Drop> drops; Set<Drop> drops,
final boolean wideTrunk; boolean wideTrunk,
final int rarity; int rarity,
final float leavesRatio; float leavesRatio
) {
public TreeTypeDef(PacketByteBuf buffer) { public static final Codec<TreeTypeDef> CODEC = RecordCodecBuilder.create(instance -> instance.group(
logs = new HashSet<>(buffer.readList(PacketByteBuf::readIdentifier)); CodecUtils.setOf(Identifier.CODEC).fieldOf("logs").forGetter(TreeTypeDef::logs),
leaves = new HashSet<>(buffer.readList(PacketByteBuf::readIdentifier)); CodecUtils.setOf(Identifier.CODEC).fieldOf("leaves").forGetter(TreeTypeDef::leaves),
drops = new HashSet<>(buffer.readList(Drop::new)); CodecUtils.setOf(Drop.CODEC).fieldOf("drops").forGetter(TreeTypeDef::drops),
wideTrunk = buffer.readBoolean(); Codec.BOOL.fieldOf("wideTrunk").forGetter(TreeTypeDef::wideTrunk),
rarity = buffer.readInt(); Codec.INT.fieldOf("rarity").forGetter(TreeTypeDef::rarity),
leavesRatio = buffer.readFloat(); Codec.FLOAT.fieldOf("leavesRatio").forGetter(TreeTypeDef::leavesRatio)
} ).apply(instance, TreeTypeDef::new));
public static final PacketCodec<RegistryByteBuf, TreeTypeDef> PACKET_CODEC = PacketCodec.tuple(
Identifier.PACKET_CODEC.collect(PacketCodecs.toCollection(HashSet::new)), TreeTypeDef::logs,
Identifier.PACKET_CODEC.collect(PacketCodecs.toCollection(HashSet::new)), TreeTypeDef::leaves,
Drop.PACKET_CODEC.collect(PacketCodecs.toCollection(HashSet::new)), TreeTypeDef::drops,
PacketCodecs.BOOL, TreeTypeDef::wideTrunk,
PacketCodecs.INTEGER, TreeTypeDef::rarity,
PacketCodecs.FLOAT, TreeTypeDef::leavesRatio,
TreeTypeDef::new
);
public TreeType toTreeType(Identifier id) { public TreeType toTreeType(Identifier id) {
return new TreeTypeImpl( return new TreeTypeImpl(
@ -87,35 +100,32 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
); );
} }
public void write(PacketByteBuf buffer) { static record Drop (
buffer.writeCollection(logs, PacketByteBuf::writeIdentifier); int weight,
buffer.writeCollection(leaves, PacketByteBuf::writeIdentifier); Optional<Identifier> tag,
buffer.writeCollection(drops, (a, b) -> b.write(a)); Optional<Identifier> item
buffer.writeBoolean(wideTrunk); ) implements Weighted.Buildable<Supplier<ItemStack>> {
buffer.writeInt(rarity); public static final Codec<Drop> CODEC = RecordCodecBuilder.create(instance -> instance.group(
buffer.writeFloat(leavesRatio); Codec.INT.fieldOf("weight").forGetter(Drop::weight),
} Identifier.CODEC.optionalFieldOf("tag").forGetter(Drop::tag),
Identifier.CODEC.optionalFieldOf("item").forGetter(Drop::item)
static class Drop implements Weighted.Buildable<Supplier<ItemStack>> { ).apply(instance, Drop::new));
final int weight; public static final PacketCodec<RegistryByteBuf, Drop> PACKET_CODEC = PacketCodec.tuple(
final @Nullable Identifier tag; PacketCodecs.INTEGER, Drop::weight,
final @Nullable Identifier item; PacketCodecs.optional(Identifier.PACKET_CODEC), Drop::tag,
PacketCodecs.optional(Identifier.PACKET_CODEC), Drop::item,
public Drop(PacketByteBuf buffer) { Drop::new
weight = buffer.readInt(); );
tag = buffer.readOptional(PacketByteBuf::readIdentifier).orElse(null);
item = buffer.readOptional(PacketByteBuf::readIdentifier).orElse(null);
}
@Override @Override
public void appendTo(Weighted.Builder<Supplier<ItemStack>> weighted) { public void appendTo(Weighted.Builder<Supplier<ItemStack>> weighted) {
if (item != null) { if (item.isPresent()) {
Registries.ITEM.getOrEmpty(item).ifPresent(item -> { Registries.ITEM.getOrEmpty(item.get()).ifPresent(item -> {
weighted.put(weight, item::getDefaultStack); weighted.put(weight, item::getDefaultStack);
}); });
} else { } else {
weighted.put(weight, () -> { weighted.put(weight, () -> {
return Registries.ITEM.getOrCreateEntryList(TagKey.of(RegistryKeys.ITEM, tag)) return Registries.ITEM.getOrCreateEntryList(TagKey.of(RegistryKeys.ITEM, tag.get()))
.getRandom(Weighted.getRng()) .getRandom(Weighted.getRng())
.map(RegistryEntry::value) .map(RegistryEntry::value)
.map(Item::getDefaultStack) .map(Item::getDefaultStack)
@ -123,12 +133,6 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
}); });
} }
} }
public void write(PacketByteBuf buffer) {
buffer.writeInt(weight);
buffer.writeOptional(Optional.ofNullable(tag), PacketByteBuf::writeIdentifier);
buffer.writeOptional(Optional.ofNullable(item), PacketByteBuf::writeIdentifier);
}
} }
} }
} }

View file

@ -154,7 +154,7 @@ class MultiSpellSlot implements SpellSlots, NbtSerialisable {
} else { } else {
T spell = this.spell.get(); T spell = this.spell.get();
if (spell != null) { if (spell != null) {
spell.getDataTracker().load(MsgTrackedValues.TrackerEntries.PACKET_CODEC.decode(buffer)); spell.getDataTracker().load(MsgTrackedValues.TrackerEntries.PACKET_CODEC.decode(buffer), lookup);
} }
} }
} }
@ -171,7 +171,7 @@ class MultiSpellSlot implements SpellSlots, NbtSerialisable {
if (spell == null) { if (spell == null) {
return Optional.empty(); return Optional.empty();
} }
return spell.getDataTracker().getDirtyPairs().map(entries -> { return spell.getDataTracker().getDirtyPairs(lookup).map(entries -> {
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer()); PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
buffer.writeByte(0); buffer.writeByte(0);
TrackerEntries.PACKET_CODEC.encode(buffer, entries); TrackerEntries.PACKET_CODEC.encode(buffer, entries);

View file

@ -138,7 +138,7 @@ public interface Spell extends NbtSerialisable, Affine {
static <T extends Spell> T readNbt(@Nullable NbtCompound compound, WrapperLookup lookup) { static <T extends Spell> T readNbt(@Nullable NbtCompound compound, WrapperLookup lookup) {
try { try {
if (compound != null) { if (compound != null) {
return CustomisedSpellType.<T>fromNBT(compound).create(compound); return CustomisedSpellType.<T>fromNBT(compound).create(compound, lookup);
} }
} catch (Exception e) { } catch (Exception e) {
Unicopia.LOGGER.fatal("Invalid spell nbt {}", e); Unicopia.LOGGER.fatal("Invalid spell nbt {}", e);

View file

@ -18,6 +18,7 @@ import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -67,7 +68,7 @@ public class AttractiveSpell extends ShieldSpell implements HomingSpell, TimedSp
source.spawnParticles(origin, new Sphere(false, range), 7, p -> { source.spawnParticles(origin, new Sphere(false, range), 7, p -> {
source.addParticle( source.addParticle(
new FollowingParticleEffect(UParticles.HEALTH_DRAIN, origin, 0.4F) new FollowingParticleEffect(UParticles.HEALTH_DRAIN, origin, 0.4F)
.withChild(ParticleTypes.AMBIENT_ENTITY_EFFECT), .withChild(ParticleTypes.EFFECT),
p, p,
Vec3d.ZERO Vec3d.ZERO
); );
@ -149,16 +150,16 @@ public class AttractiveSpell extends ShieldSpell implements HomingSpell, TimedSp
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
super.toNBT(compound); super.toNBT(compound, lookup);
compound.put("target", target.toNBT()); compound.put("target", target.toNBT(lookup));
timer.toNBT(compound); timer.toNBT(compound, lookup);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
super.fromNBT(compound); super.fromNBT(compound, lookup);
target.fromNBT(compound.getCompound("target")); target.fromNBT(compound.getCompound("target"), lookup);
timer.fromNBT(compound); timer.fromNBT(compound, lookup);
} }
} }

View file

@ -16,6 +16,7 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
public class AwkwardSpell extends AbstractSpell implements TimedSpell { public class AwkwardSpell extends AbstractSpell implements TimedSpell {
@ -65,18 +66,20 @@ public class AwkwardSpell extends AbstractSpell implements TimedSpell {
&& type != ParticleTypes.SMOKE && type != ParticleTypes.SMOKE
&& type != ParticleTypes.EXPLOSION && type != ParticleTypes.EXPLOSION
&& type != ParticleTypes.EXPLOSION_EMITTER && type != ParticleTypes.EXPLOSION_EMITTER
&& type != ParticleTypes.AMBIENT_ENTITY_EFFECT; && type != ParticleTypes.ENTITY_EFFECT
&& type != ParticleTypes.EFFECT
&& type != ParticleTypes.INSTANT_EFFECT;
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
super.toNBT(compound); super.toNBT(compound, lookup);
timer.toNBT(compound); timer.toNBT(compound, lookup);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
super.fromNBT(compound); super.fromNBT(compound, lookup);
timer.fromNBT(compound); timer.fromNBT(compound, lookup);
} }
} }

View file

@ -1,9 +1,8 @@
package com.minelittlepony.unicopia.ability.magic.spell.effect; package com.minelittlepony.unicopia.ability.magic.spell.effect;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.*; import com.minelittlepony.unicopia.ability.magic.spell.*;
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat; import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
@ -28,18 +27,19 @@ import net.minecraft.entity.attribute.*;
import net.minecraft.entity.attribute.EntityAttributeModifier.Operation; import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public class BubbleSpell extends AbstractSpell implements TimedSpell, public class BubbleSpell extends AbstractSpell implements TimedSpell, ProjectileDelegate.EntityHitListener {
ProjectileDelegate.EntityHitListener { private static final Identifier EFFECT_ID = Unicopia.id("bubble_floating_modifier");
private static final EntityAttributeModifier GRAVITY_MODIFIER = private static final EntityAttributeModifier GRAVITY_MODIFIER = new EntityAttributeModifier(EFFECT_ID, 0.02D - 1D, Operation.ADD_MULTIPLIED_TOTAL);
new EntityAttributeModifier(UUID.fromString("9dc7818b-927b-46e0-acbe-48d31a28128f"), "Bubble Floating", 0.02D - 1D, Operation.MULTIPLY_TOTAL); private static final EntityAttributeModifier SPEED_MODIFIER = new EntityAttributeModifier(EFFECT_ID, 0.01D - 1D, Operation.ADD_MULTIPLIED_TOTAL);
private static final EntityAttributeModifier SPEED_MODIFIER =
new EntityAttributeModifier(UUID.fromString("9dc7818b-927b-46e0-acbe-48d31a28128f"), "Bubble Floating", 0.01D - 1D, Operation.MULTIPLY_TOTAL);
private static final Map<EntityAttribute, EntityAttributeModifier> MODIFIERS = Map.of( private static final Map<RegistryEntry<EntityAttribute>, EntityAttributeModifier> MODIFIERS = Map.of(
UEntityAttributes.ENTITY_GRAVITY_MODIFIER, GRAVITY_MODIFIER, UEntityAttributes.ENTITY_GRAVITY_MODIFIER, GRAVITY_MODIFIER,
UEntityAttributes.EXTENDED_REACH_DISTANCE, GRAVITY_MODIFIER, UEntityAttributes.EXTENDED_REACH_DISTANCE, GRAVITY_MODIFIER,
UEntityAttributes.EXTENDED_ATTACK_DISTANCE, GRAVITY_MODIFIER, UEntityAttributes.EXTENDED_ATTACK_DISTANCE, GRAVITY_MODIFIER,
@ -157,18 +157,18 @@ public class BubbleSpell extends AbstractSpell implements TimedSpell,
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
super.toNBT(compound); super.toNBT(compound, lookup);
compound.putInt("struggles", struggles.get()); compound.putInt("struggles", struggles.get());
compound.putFloat("radius", radius.get()); compound.putFloat("radius", radius.get());
timer.toNBT(compound); timer.toNBT(compound, lookup);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
super.fromNBT(compound); super.fromNBT(compound, lookup);
struggles.set(compound.getInt("struggles")); struggles.set(compound.getInt("struggles"));
radius.set(compound.getFloat("radius")); radius.set(compound.getFloat("radius"));
timer.fromNBT(compound); timer.fromNBT(compound, lookup);
} }
} }

View file

@ -172,7 +172,7 @@ public class NecromancySpell extends AbstractAreaEffectSpell implements Projecti
if (master != null) { if (master != null) {
master.applyDamageEffects(master, e); master.applyDamageEffects(master, e);
} }
e.getWorld().sendEntityStatus(e, (byte)60); e.getWorld().sendEntityStatus(e, EntityStatuses.ADD_DEATH_PARTICLES);
e.discard(); e.discard();
}); });
}); });
@ -199,7 +199,7 @@ public class NecromancySpell extends AbstractAreaEffectSpell implements Projecti
for (int i = source.asWorld().random.nextInt(GEAR.length); i < GEAR.length; i++) { for (int i = source.asWorld().random.nextInt(GEAR.length); i < GEAR.length; i++) {
ItemStack pick = GEAR[i][(int)(powerScale * GEAR[i].length) % GEAR[i].length].getDefaultStack(); ItemStack pick = GEAR[i][(int)(powerScale * GEAR[i].length) % GEAR[i].length].getDefaultStack();
minion.equipStack(LivingEntity.getPreferredEquipmentSlot(pick), pick); minion.equipStack(minion.getPreferredEquipmentSlot(pick), pick);
if (source.asWorld().random.nextFloat() > powerScale) { if (source.asWorld().random.nextFloat() > powerScale) {
break; break;

View file

@ -30,6 +30,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -162,14 +163,14 @@ public class SiphoningSpell extends AbstractAreaEffectSpell {
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
super.toNBT(compound); super.toNBT(compound, lookup);
compound.putInt("upset", ticksUpset); compound.putInt("upset", ticksUpset);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
super.fromNBT(compound); super.fromNBT(compound, lookup);
ticksUpset = compound.getInt("upset"); ticksUpset = compound.getInt("upset");
if (ticksUpset > 0) { if (ticksUpset > 0) {
upset.set(true); upset.set(true);

View file

@ -19,6 +19,7 @@ import java.util.stream.Stream;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer; import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer;
import com.minelittlepony.unicopia.item.component.UDataComponentTypes;
import com.minelittlepony.unicopia.util.InventoryUtil; import com.minelittlepony.unicopia.util.InventoryUtil;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
@ -32,10 +33,8 @@ import net.minecraft.item.Item;
import net.minecraft.item.SpawnEggItem; import net.minecraft.item.SpawnEggItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodec;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -248,19 +247,16 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
} }
public static Optional<SpellTraits> getEmbeddedTraits(ItemStack stack) { public static Optional<SpellTraits> getEmbeddedTraits(ItemStack stack) {
if (!stack.hasNbt() || !stack.getNbt().contains("spell_traits", NbtElement.COMPOUND_TYPE)) { return Optional.ofNullable(stack.get(UDataComponentTypes.SPELL_TRAITS));
return Optional.empty();
}
return fromNbt(stack.getNbt().getCompound("spell_traits"));
} }
public ItemStack applyTo(ItemStack stack) { public ItemStack applyTo(ItemStack stack) {
stack = stack.copy(); stack = stack.copy();
if (isEmpty()) { if (isEmpty()) {
stack.removeSubNbt("spell_traits"); stack.remove(UDataComponentTypes.SPELL_TRAITS);
return stack; return stack;
} }
stack.getOrCreateNbt().put("spell_traits", toNbt()); stack.set(UDataComponentTypes.SPELL_TRAITS, this);
return stack; return stack;
} }

View file

@ -9,8 +9,8 @@ import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.command.CommandArgumentEnum; import com.minelittlepony.unicopia.command.CommandArgumentEnum;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import net.minecraft.command.argument.EnumArgumentType; import net.minecraft.command.argument.EnumArgumentType;
import net.minecraft.component.type.AttributeModifiersComponent;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtList;
import net.minecraft.text.*; import net.minecraft.text.*;
@ -92,7 +92,7 @@ public enum Trait implements CommandArgumentEnum<Trait> {
Text.empty(), Text.empty(),
Text.translatable("trait." + getId().getNamespace() + "." + getId().getPath() + ".description").formatted(Formatting.GRAY), Text.translatable("trait." + getId().getNamespace() + "." + getId().getPath() + ".description").formatted(Formatting.GRAY),
Text.empty(), Text.empty(),
Text.translatable("gui.unicopia.trait.corruption", ItemStack.MODIFIER_FORMAT.format(getGroup().getCorruption())).formatted(Formatting.ITALIC, corruptionColor) Text.translatable("gui.unicopia.trait.corruption", AttributeModifiersComponent.DECIMAL_FORMAT.format(getGroup().getCorruption())).formatted(Formatting.ITALIC, corruptionColor)
); );
MutableText tooltipText = getName().copy(); MutableText tooltipText = getName().copy();

View file

@ -32,6 +32,7 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; 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.world.World; import net.minecraft.world.World;
public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery> { public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery> {
@ -120,7 +121,7 @@ public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery>
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
NbtCompound disco = new NbtCompound(); NbtCompound disco = new NbtCompound();
items.forEach((key, val) -> { items.forEach((key, val) -> {
disco.put(key.toString(), val.toNbt()); disco.put(key.toString(), val.toNbt());
@ -137,7 +138,7 @@ public class TraitDiscovery implements NbtSerialisable, Copyable<TraitDiscovery>
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
clear(); clear();
NbtCompound disco = compound.getCompound("items"); NbtCompound disco = compound.getCompound("items");
disco.getKeys().forEach(key -> { disco.getKeys().forEach(key -> {

View file

@ -52,19 +52,19 @@ public class TraitLoader extends SinglePreparationResourceReloader<Multimap<Iden
profiler.push(path.toString()); profiler.push(path.toString());
try { try {
for (Resource resource : manager.getAllResources(path)) { for (Resource resource : manager.getAllResources(path)) {
profiler.push(resource.getResourcePackName()); profiler.push(resource.getPackId());
try (InputStreamReader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { try (InputStreamReader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) {
JsonObject data = JsonHelper.deserialize(Resources.GSON, reader, JsonObject.class); JsonObject data = JsonHelper.deserialize(Resources.GSON, reader, JsonObject.class);
TraitStream set = TraitStream.of(path, resource.getResourcePackName(), data); TraitStream set = TraitStream.of(path, resource.getPackId(), data);
if (set.replace()) { if (set.replace()) {
prepared.removeAll(path); prepared.removeAll(path);
} }
prepared.put(path, set); prepared.put(path, set);
} catch (JsonParseException e) { } catch (JsonParseException e) {
Unicopia.LOGGER.error("Error reading traits file " + resource.getResourcePackName() + ":" + path, e); Unicopia.LOGGER.error("Error reading traits file " + resource.getPackId() + ":" + path, e);
} finally { } finally {
profiler.pop(); profiler.pop();
} }

View file

@ -183,7 +183,7 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven
} else if (getFluid() != null) { } else if (getFluid() != null) {
nbt.put("fluid", getFluid().toNBT(new NbtCompound(), lookup)); nbt.put("fluid", getFluid().toNBT(new NbtCompound(), lookup));
} else if (getFakeFluid() != null) { } else if (getFakeFluid() != null) {
nbt.put("fakeFluid", getFakeFluid().toNBT(new NbtCompound())); nbt.put("fakeFluid", getFakeFluid().toNBT(new NbtCompound(), lookup));
} }
} }
} }

View file

@ -15,11 +15,13 @@ import net.minecraft.block.TransparentBlock;
import net.minecraft.block.Waterloggable; import net.minecraft.block.Waterloggable;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.FluidState; import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids; import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.state.StateManager; import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
@ -101,7 +103,8 @@ public class JarBlock extends TransparentBlock implements Waterloggable {
@Override @Override
public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
super.afterBreak(world, player, pos, state, blockEntity, tool); super.afterBreak(world, player, pos, state, blockEntity, tool);
if (!EnchantmentHelper.hasSilkTouch(tool) && !player.shouldCancelInteraction()) { // TODO: Enchantment tag
if (EnchantmentHelper.getLevel(world.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(Enchantments.SILK_TOUCH).get(), tool) == 0 && !player.shouldCancelInteraction()) {
if (asItem() instanceof WeatherJarItem jar) { if (asItem() instanceof WeatherJarItem jar) {
jar.releaseContents(world, pos); jar.releaseContents(world, pos);
} }

View file

@ -76,7 +76,7 @@ public class ShellsBlock extends Block implements Waterloggable {
} }
@Override @Override
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { public boolean canPathfindThrough(BlockState state, NavigationType type) {
return (type == NavigationType.WATER) == world.getFluidState(pos).isIn(FluidTags.WATER); return (type == NavigationType.WATER) == state.getFluidState().isIn(FluidTags.WATER);
} }
} }

View file

@ -16,7 +16,6 @@ import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.item.enchantment.AttributedEnchantment; import com.minelittlepony.unicopia.item.enchantment.AttributedEnchantment;
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
@ -24,7 +23,9 @@ import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.attribute.EntityAttributeModifier.Operation; import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
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.TooltipType;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.screen.ScreenTexts; import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@ -32,11 +33,12 @@ import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Pair; import net.minecraft.util.Pair;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.entry.RegistryEntry;
public class ModifierTooltipRenderer implements ItemTooltipCallback { public class ModifierTooltipRenderer implements ItemTooltipCallback {
@Override @Override
public void getTooltip(ItemStack stack, TooltipContext context, List<Text> lines) { public void getTooltip(ItemStack stack, Item.TooltipContext tooltipContext, TooltipType tooltipType, List<Text> lines) {
int flags = stack.hasNbt() && stack.getNbt().contains("HideFlags", 99) ? stack.getNbt().getInt("HideFlags") : 0; int flags = stack.hasNbt() && stack.getNbt().contains("HideFlags", 99) ? stack.getNbt().getInt("HideFlags") : 0;
@ -60,7 +62,7 @@ public class ModifierTooltipRenderer implements ItemTooltipCallback {
if (!newLines.isEmpty()) { if (!newLines.isEmpty()) {
Text find = Text.translatable("item.modifiers." + slot.getName()).formatted(Formatting.GRAY); Text find = Text.translatable("item.modifiers." + slot.getName()).formatted(Formatting.GRAY);
int insertPosition = getInsertPosition(stack, find, flags, lines, context.isAdvanced()); int insertPosition = getInsertPosition(stack, find, flags, lines, tooltipType.isAdvanced());
if (insertPosition == -1) { if (insertPosition == -1) {
lines.add(ScreenTexts.EMPTY); lines.add(ScreenTexts.EMPTY);
lines.add(find); lines.add(find);
@ -113,18 +115,18 @@ public class ModifierTooltipRenderer implements ItemTooltipCallback {
return lines.indexOf(category); return lines.indexOf(category);
} }
private void describeModifiers(EntityAttribute attribute, EntityAttributeModifier modifier, @Nullable PlayerEntity player, List<Text> lines) { private void describeModifiers(RegistryEntry<EntityAttribute> attribute, EntityAttributeModifier modifier, @Nullable PlayerEntity player, List<Text> lines) {
double value = modifier.getValue(); double value = modifier.value();
boolean baseAdjusted = false; boolean baseAdjusted = false;
if (player != null) { if (player != null) {
value += player.getAttributeBaseValue(attribute); value += player.getAttributeBaseValue(attribute);
baseAdjusted = true; baseAdjusted = true;
} }
Operation op = modifier.getOperation(); Operation op = modifier.operation();
double displayValue; double displayValue;
if (op != EntityAttributeModifier.Operation.MULTIPLY_BASE && op != EntityAttributeModifier.Operation.MULTIPLY_TOTAL) { if (op != EntityAttributeModifier.Operation.ADD_MULTIPLIED_BASE && op != EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL) {
displayValue = value; displayValue = value;
} else { } else {
displayValue = value * 100; displayValue = value * 100;

View file

@ -23,7 +23,7 @@ public record Structure(Bounds bounds, Schematic schematic) implements PageEleme
Immediate immediate = context.getVertexConsumers(); Immediate immediate = context.getVertexConsumers();
MinecraftClient client = MinecraftClient.getInstance(); MinecraftClient client = MinecraftClient.getInstance();
float tickDelta = client.player.age + client.getTickDelta(); float tickDelta = client.player.age + client.getRenderTickCounter().getTickDelta(false);
float age = tickDelta % 360F; float age = tickDelta % 360F;
matrices.push(); matrices.push();

View file

@ -40,7 +40,7 @@ class AmuletGear extends AmuletModel implements Gear {
@Override @Override
public <T extends Entity> Identifier getTexture(T entity, Context<T, ?> context) { public <T extends Entity> Identifier getTexture(T entity, Context<T, ?> context) {
return textures.computeIfAbsent(Registries.ITEM.getId(AmuletItem.get((LivingEntity)entity).stack().getItem()), id -> new Identifier(id.getNamespace(), "textures/models/armor/" + id.getPath() + ".png")); return textures.computeIfAbsent(Registries.ITEM.getId(AmuletItem.get((LivingEntity)entity).stack().getItem()), id -> id.withPath(p -> "textures/models/armor/" + p + ".png"));
} }
@Override @Override
@ -58,7 +58,7 @@ class AmuletGear extends AmuletModel implements Gear {
} }
@Override @Override
public void render(MatrixStack stack, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha, UUID interpolatorId) { public void render(MatrixStack stack, VertexConsumer consumer, int light, int overlay, int color, UUID interpolatorId) {
render(stack, consumer, light, overlay, red, green, blue, 1); render(stack, consumer, light, overlay, color);
} }
} }

View file

@ -5,7 +5,6 @@ import java.util.UUID;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.common.util.Color;
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer; import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer.BraceletModel; import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer.BraceletModel;
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
@ -19,10 +18,11 @@ import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.SkinTextures.Model; import net.minecraft.client.util.SkinTextures.Model;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.type.DyedColorComponent;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.DyeableItem;
import net.minecraft.util.Arm; import net.minecraft.util.Arm;
import net.minecraft.util.Colors;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
class BangleGear implements Gear { class BangleGear implements Gear {
@ -66,9 +66,11 @@ class BangleGear implements Gear {
@Override @Override
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getSkinTextures().model() == Model.SLIM; alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getSkinTextures().model() == Model.SLIM;
color = Colors.WHITE;
glowing = false;
FriendshipBraceletItem.getWornBangles((LivingEntity)entity, slot).findFirst().ifPresent(bracelet -> { FriendshipBraceletItem.getWornBangles((LivingEntity)entity, slot).findFirst().ifPresent(bracelet -> {
color = ((DyeableItem)bracelet.stack().getItem()).getColor(bracelet.stack()); color = DyedColorComponent.getColor(bracelet.stack(), Colors.WHITE);
glowing = ((GlowableItem)bracelet.stack().getItem()).isGlowing(bracelet.stack()); glowing = GlowableItem.isGlowing(bracelet.stack());
}); });
BraceletModel m = alex ? alexModel : steveModel; BraceletModel m = alex ? alexModel : steveModel;
@ -80,8 +82,8 @@ class BangleGear implements Gear {
} }
@Override @Override
public void render(MatrixStack stack, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha, UUID interpolatorId) { public void render(MatrixStack stack, VertexConsumer consumer, int light, int overlay, int color, UUID interpolatorId) {
BraceletModel m = alex ? alexModel : steveModel; BraceletModel m = alex ? alexModel : steveModel;
m.render(stack, consumer, glowing ? 0x0F00F0 : light, overlay, Color.r(color), Color.g(color), Color.b(color), 1); m.render(stack, consumer, glowing ? 0x0F00F0 : light, overlay, this.color);
} }
} }

View file

@ -23,6 +23,7 @@ import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Colors;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
@ -45,14 +46,14 @@ public class AmuletFeatureRenderer<E extends LivingEntity> implements AccessoryF
ItemStack stack = AmuletItem.get(entity).stack(); ItemStack stack = AmuletItem.get(entity).stack();
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
Identifier texture = textures.computeIfAbsent(Registries.ITEM.getId(stack.getItem()), id -> new Identifier(id.getNamespace(), "textures/models/armor/" + id.getPath() + ".png")); Identifier texture = textures.computeIfAbsent(Registries.ITEM.getId(stack.getItem()), id -> id.withPath(p -> "textures/models/armor/" + p + ".png"));
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(texture), false, false); VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(texture), false);
if (context.getModel() instanceof BipedEntityModel) { if (context.getModel() instanceof BipedEntityModel) {
model.setAngles(entity, context.getModel()); model.setAngles(entity, context.getModel());
} }
model.render(matrices, consumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1); model.render(matrices, consumer, lightUv, OverlayTexture.DEFAULT_UV, Colors.WHITE);
} }
} }
@ -79,8 +80,8 @@ public class AmuletFeatureRenderer<E extends LivingEntity> implements AccessoryF
} }
@Override @Override
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) { public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int i, int j, int color) {
amulet.render(matrices, vertexConsumer, i, j, f, g, h, k); amulet.render(matrices, vertexConsumer, i, j, color);
} }
} }
} }

View file

@ -1,6 +1,5 @@
package com.minelittlepony.unicopia.client.render; package com.minelittlepony.unicopia.client.render;
import com.minelittlepony.common.util.Color;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate; import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
@ -15,6 +14,7 @@ import net.minecraft.client.model.ModelPartData;
import net.minecraft.client.model.ModelTransform; import net.minecraft.client.model.ModelTransform;
import net.minecraft.client.model.TexturedModelData; import net.minecraft.client.model.TexturedModelData;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
@ -25,9 +25,9 @@ import net.minecraft.client.render.entity.model.EntityModelPartNames;
import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.SkinTextures; import net.minecraft.client.util.SkinTextures;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.type.DyedColorComponent;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.item.DyeableItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.*; import net.minecraft.util.*;
@ -58,7 +58,7 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
} }
private void renderBangleThirdPerson(ItemStack item, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch, Arm mainArm) { private void renderBangleThirdPerson(ItemStack item, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch, Arm mainArm) {
int j = ((DyeableItem)item.getItem()).getColor(item); int j = DyedColorComponent.getColor(item, Colors.WHITE);
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getSkinTextures().model() == SkinTextures.Model.SLIM; boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getSkinTextures().model() == SkinTextures.Model.SLIM;
@ -69,40 +69,36 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
ModelPart arm = isLeft ? context.getModel().leftArm : context.getModel().rightArm; ModelPart arm = isLeft ? context.getModel().leftArm : context.getModel().rightArm;
arm.visible = true; arm.visible = true;
VertexConsumer consumer = renderContext.getBuffer(context.getModel().getLayer(context.getTexture(entity))); VertexConsumer consumer = renderContext.getBuffer(context.getModel().getLayer(context.getTexture(entity)));
arm.render(stack, consumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1); arm.render(stack, consumer, lightUv, OverlayTexture.DEFAULT_UV, Colors.WHITE);
} }
boolean glowing = ((GlowableItem)item.getItem()).isGlowing(item); VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(TEXTURE), false);
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(TEXTURE), false, false);
model.setAngles(context.getModel()); model.setAngles(context.getModel());
model.setVisible(mainArm); model.setVisible(mainArm);
model.render(stack, consumer, glowing ? 0x0F00F0 : lightUv, OverlayTexture.DEFAULT_UV, Color.r(j), Color.g(j), Color.b(j), 1); model.render(stack, consumer, GlowableItem.isGlowing(item) ? LightmapTextureManager.MAX_LIGHT_COORDINATE : lightUv, OverlayTexture.DEFAULT_UV, j);
} }
@Override @Override
public void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, ModelPart armModel, Arm side) { public void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, E entity, ModelPart armModel, Arm side) {
FriendshipBraceletItem.getWornBangles(entity, side == entity.getMainArm() ? TrinketsDelegate.MAIN_GLOVE : TrinketsDelegate.SECONDARY_GLOVE).findFirst().ifPresent(item -> { FriendshipBraceletItem.getWornBangles(entity, side == entity.getMainArm() ? TrinketsDelegate.MAIN_GLOVE : TrinketsDelegate.SECONDARY_GLOVE).findFirst().ifPresent(item -> {
int j = ((DyeableItem)item.stack().getItem()).getColor(item.stack()); int j = DyedColorComponent.getColor(item.stack(), Colors.WHITE);
boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getSkinTextures().model() == SkinTextures.Model.SLIM; boolean alex = entity instanceof ClientPlayerEntity && ((ClientPlayerEntity)entity).getSkinTextures().model() == SkinTextures.Model.SLIM;
BraceletModel model = alex ? alexModel : steveModel; BraceletModel model = alex ? alexModel : steveModel;
boolean glowing = ((GlowableItem)item.stack().getItem()).isGlowing(item.stack());
if (MineLPDelegate.getInstance().getPlayerPonyRace((ClientPlayerEntity)entity).isEquine()) { if (MineLPDelegate.getInstance().getPlayerPonyRace((ClientPlayerEntity)entity).isEquine()) {
stack.translate(side == Arm.LEFT ? 0.06 : -0.06, 0.3, 0); stack.translate(side == Arm.LEFT ? 0.06 : -0.06, 0.3, 0);
} else { } else {
stack.translate(0, -0.1, 0); stack.translate(0, -0.1, 0);
} }
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(TEXTURE), false, false); VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(TEXTURE), false);
model.setAngles(context.getModel()); model.setAngles(context.getModel());
model.setVisible(side); model.setVisible(side);
model.render(stack, consumer, glowing ? 0x0F00F0 : lightUv, OverlayTexture.DEFAULT_UV, Color.r(j), Color.g(j), Color.b(j), 1); model.render(stack, consumer, GlowableItem.isGlowing(item.stack()) ? LightmapTextureManager.MAX_LIGHT_COORDINATE : lightUv, OverlayTexture.DEFAULT_UV, j);
}); });
} }
@ -144,9 +140,9 @@ public class BraceletFeatureRenderer<E extends LivingEntity> implements Accessor
} }
@Override @Override
public void render(MatrixStack matrixStack, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) { public void render(MatrixStack matrixStack, VertexConsumer vertexConsumer, int i, int j, int color) {
leftArm.render(matrixStack, vertexConsumer, i, j, f, g, h, k); leftArm.render(matrixStack, vertexConsumer, i, j, color);
rightArm.render(matrixStack, vertexConsumer, i, j, f, g, h, k); rightArm.render(matrixStack, vertexConsumer, i, j, color);
} }
} }

View file

@ -27,8 +27,8 @@ public class ViewportShader implements SynchronousResourceReloader, Identifiable
public static final ViewportShader INSTANCE = new ViewportShader(); public static final ViewportShader INSTANCE = new ViewportShader();
public static final Identifier CREEPER_SHADER = new Identifier("shaders/post/invert.json"); public static final Identifier CREEPER_SHADER = Identifier.ofVanilla("shaders/post/invert.json");
public static final Identifier DESATURATION_SHADER = new Identifier("shaders/post/desaturate.json"); public static final Identifier DESATURATION_SHADER = Identifier.ofVanilla("shaders/post/desaturate.json");
private final MinecraftClient client = MinecraftClient.getInstance(); private final MinecraftClient client = MinecraftClient.getInstance();
@ -112,8 +112,8 @@ public class ViewportShader implements SynchronousResourceReloader, Identifiable
} }
@Override @Override
public PostEffectPass addPass(String programName, Framebuffer source, Framebuffer dest) throws IOException { public PostEffectPass addPass(String programName, Framebuffer source, Framebuffer dest, boolean linear) throws IOException {
PostEffectPass pass = super.addPass(programName, source, dest); PostEffectPass pass = super.addPass(programName, source, dest, linear);
if (programs == null) { if (programs == null) {
programs = LinkedListMultimap.create(); programs = LinkedListMultimap.create();
} }

View file

@ -1,7 +1,5 @@
package com.minelittlepony.unicopia.compat.trinkets; package com.minelittlepony.unicopia.compat.trinkets;
import java.util.UUID;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.minelittlepony.unicopia.entity.ItemTracker; import com.minelittlepony.unicopia.entity.ItemTracker;
import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.Living;
@ -9,16 +7,17 @@ import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
import com.minelittlepony.unicopia.item.WearableItem; import com.minelittlepony.unicopia.item.WearableItem;
import dev.emi.trinkets.api.*; import dev.emi.trinkets.api.*;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.Equipment; import net.minecraft.item.Equipment;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Identifier;
import net.minecraft.world.event.GameEvent; import net.minecraft.world.event.GameEvent;
public class UnicopiaTrinket implements Trinket { public class UnicopiaTrinket implements Trinket {
@ -74,21 +73,22 @@ public class UnicopiaTrinket implements Trinket {
return slot.inventory().getStack(slot.index()).isEmpty(); return slot.inventory().getStack(slot.index()).isEmpty();
} }
@Override
public boolean canUnequip(ItemStack stack, SlotReference slot, LivingEntity entity) {
return !(EnchantmentHelper.hasBindingCurse(stack) && EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.test(entity));
}
@Override @Override
public void tick(ItemStack stack, SlotReference slot, LivingEntity entity) { public void tick(ItemStack stack, SlotReference slot, LivingEntity entity) {
item.inventoryTick(stack, entity.getWorld(), entity, slot.index(), false); item.inventoryTick(stack, entity.getWorld(), entity, slot.index(), false);
} }
@Override @Override
public Multimap<EntityAttribute, EntityAttributeModifier> getModifiers(ItemStack stack, SlotReference slot, LivingEntity entity, UUID uuid) { public Multimap<RegistryEntry<EntityAttribute>, EntityAttributeModifier> getModifiers(ItemStack stack, SlotReference slot, LivingEntity entity, Identifier slotIdentifier) {
Multimap<EntityAttribute, EntityAttributeModifier> modifiers = Trinket.super.getModifiers(stack, slot, entity, uuid); Multimap<RegistryEntry<EntityAttribute>, EntityAttributeModifier> modifiers = Trinket.super.getModifiers(stack, slot, entity, slotIdentifier);
if (item instanceof WearableItem wearable) { if (item instanceof WearableItem wearable) {
item.getAttributeModifiers(wearable.getSlotType(stack)); EquipmentSlot es = wearable.getSlotType(stack);
stack.get(DataComponentTypes.ATTRIBUTE_MODIFIERS).modifiers().forEach(entry -> {
if (entry.slot().matches(es)) {
modifiers.put(entry.attribute(), entry.modifier());
}
});
} }
return modifiers; return modifiers;
} }

View file

@ -11,16 +11,15 @@ import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.recipe.URecipes; import com.minelittlepony.unicopia.recipe.URecipes;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import net.minecraft.component.EnchantmentEffectComponentTypes;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.CraftingResultInventory; import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.Equipment; import net.minecraft.item.Equipment;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.recipe.RecipeEntry; import net.minecraft.recipe.RecipeEntry;
import net.minecraft.screen.PlayerScreenHandler; import net.minecraft.screen.PlayerScreenHandler;
@ -129,7 +128,7 @@ public class SpellbookScreenHandler extends ScreenHandler {
@Override @Override
public boolean canTakeItems(PlayerEntity playerEntity) { public boolean canTakeItems(PlayerEntity playerEntity) {
ItemStack stack = getStack(); ItemStack stack = getStack();
if (!stack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasBindingCurse(stack)) { if (!stack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasAnyEnchantmentsWith(stack, EnchantmentEffectComponentTypes.PREVENT_ARMOR_CHANGE)) {
return false; return false;
} }
return super.canTakeItems(playerEntity); return super.canTakeItems(playerEntity);
@ -323,7 +322,7 @@ public class SpellbookScreenHandler extends ScreenHandler {
Slot slot = getSlot(i); Slot slot = getSlot(i);
ItemStack current = slot.getStack(); ItemStack current = slot.getStack();
if (!current.isEmpty() && ItemStack.canCombine(stack, current)) { if (!current.isEmpty() && ItemStack.areItemsAndComponentsEqual(stack, current)) {
// abide by the slot's max item count when trying to insert stacks // abide by the slot's max item count when trying to insert stacks
int available = Math.min(Math.min(current.getMaxCount(), slot.getMaxItemCount(stack)) - current.getCount(), stack.getCount()); int available = Math.min(Math.min(current.getMaxCount(), slot.getMaxItemCount(stack)) - current.getCount(), stack.getCount());

View file

@ -5,20 +5,26 @@ import java.util.function.Consumer;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.network.datasync.Synchronizable; import com.minelittlepony.unicopia.network.datasync.Synchronizable;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.nbt.NbtCompound; import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NbtElement;
import net.minecraft.network.PacketByteBuf;
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.registry.RegistryWrapper.WrapperLookup; import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class SpellbookState extends Synchronizable<SpellbookState> implements NbtSerialisable { public class SpellbookState extends Synchronizable<SpellbookState> {
// TODO: SpellbookState needs a packet codec public static final Codec<SpellbookState> CODEC = RecordCodecBuilder.create(instance -> instance.group(
public static final PacketCodec<RegistryByteBuf, SpellbookState> PACKET_CODEC = null; Identifier.CODEC.optionalFieldOf("current_page").forGetter(i -> i.currentPageId),
Codec.unboundedMap(Identifier.CODEC, PageState.CODEC).fieldOf("states").forGetter(i -> i.states)
).apply(instance, SpellbookState::new));
public static final PacketCodec<RegistryByteBuf, SpellbookState> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.optional(Identifier.PACKET_CODEC), SpellbookState::getCurrentPageId,
PacketCodecs.map(HashMap::new, Identifier.PACKET_CODEC, PageState.PACKET_CODEC), p -> p.states,
SpellbookState::new
);
public static final Identifier CRAFTING_ID = Unicopia.id("crafting"); public static final Identifier CRAFTING_ID = Unicopia.id("crafting");
public static final Identifier PROFILE_ID = Unicopia.id("profile"); public static final Identifier PROFILE_ID = Unicopia.id("profile");
@ -30,6 +36,15 @@ public class SpellbookState extends Synchronizable<SpellbookState> implements Nb
private final Map<Identifier, PageState> states = new HashMap<>(); private final Map<Identifier, PageState> states = new HashMap<>();
public SpellbookState() {}
private SpellbookState(Optional<Identifier> currentPageId, Map<Identifier, PageState> states) {
this.currentPageId = currentPageId;
states.forEach((id, state) -> {
getState(id).offset = state.offset;
});
}
public boolean isDirty() { public boolean isDirty() {
boolean isDirty = dirty; boolean isDirty = dirty;
dirty = false; dirty = false;
@ -56,42 +71,21 @@ public class SpellbookState extends Synchronizable<SpellbookState> implements Nb
dirty = true; dirty = true;
} }
public void toPacket(PacketByteBuf buf) { public SpellbookState createCopy() {
buf.writeOptional(currentPageId, PacketByteBuf::writeIdentifier); SpellbookState copy = new SpellbookState();
buf.writeMap(states, PacketByteBuf::writeIdentifier, (b, v) -> v.toPacket(b)); copy.currentPageId = currentPageId;
} states.forEach((id, state) -> {
copy.getState(id).offset = state.offset;
public SpellbookState fromPacket(PacketByteBuf buf) {
currentPageId = buf.readOptional(PacketByteBuf::readIdentifier);
buf.readMap(PacketByteBuf::readIdentifier, b -> new PageState(page -> synchronize()).fromPacket(b)).forEach((id, state) -> {
getState(id).copyFrom(state);
}); });
return this; return copy;
} }
@Override public static class PageState extends Synchronizable<PageState> {
public void toNBT(NbtCompound compound, WrapperLookup lookup) { public static final Codec<PageState> CODEC = RecordCodecBuilder.create(instance -> instance.group(
currentPageId.ifPresent(id -> compound.putString("current_page", id.toString())); Codec.INT.fieldOf("offset").forGetter(PageState::getOffset)
NbtCompound states = new NbtCompound(); ).apply(instance, PageState::new));
compound.put("states", states); public static final PacketCodec<ByteBuf, PageState> PACKET_CODEC = PacketCodecs.INTEGER.xmap(PageState::new, PageState::getOffset);
this.states.forEach((id, page) -> {
states.put(id.toString(), page.toNBT(lookup));
});
}
@Override
public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
currentPageId = compound.contains("current_page", NbtElement.STRING_TYPE) ? Optional.ofNullable(Identifier.tryParse(compound.getString("current_page"))) : Optional.empty();
NbtCompound states = compound.getCompound("states");
states.getKeys().stream().forEach(key -> {
Identifier id = Identifier.tryParse(key);
if (id != null) {
getState(id).fromNBT(states.getCompound(key), lookup);
}
});
}
public static class PageState extends Synchronizable<PageState> implements NbtSerialisable {
private int offset; private int offset;
public PageState() {} public PageState() {}
@ -100,6 +94,10 @@ public class SpellbookState extends Synchronizable<SpellbookState> implements Nb
setSynchronizer(synchronizer); setSynchronizer(synchronizer);
} }
public PageState(int offset) {
this.offset = offset;
}
@Override @Override
public void copyFrom(PageState other) { public void copyFrom(PageState other) {
offset = other.offset; offset = other.offset;
@ -117,24 +115,5 @@ public class SpellbookState extends Synchronizable<SpellbookState> implements Nb
public void swap(int incr, int max) { public void swap(int incr, int max) {
setOffset(MathHelper.clamp(getOffset() + incr, 0, max - 1)); setOffset(MathHelper.clamp(getOffset() + incr, 0, max - 1));
} }
public void toPacket(PacketByteBuf buf) {
buf.writeInt(offset);
}
public PageState fromPacket(PacketByteBuf buf) {
offset = buf.readInt();
return this;
}
@Override
public void toNBT(NbtCompound compound, WrapperLookup lookup) {
compound.putInt("offset", offset);
}
@Override
public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
offset = compound.getInt("offset");
}
} }
} }

View file

@ -8,6 +8,7 @@ import com.minelittlepony.unicopia.datagen.providers.DietsProvider;
import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider; import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider;
import com.minelittlepony.unicopia.datagen.providers.UAdvancementsProvider; import com.minelittlepony.unicopia.datagen.providers.UAdvancementsProvider;
import com.minelittlepony.unicopia.datagen.providers.UModelProvider; import com.minelittlepony.unicopia.datagen.providers.UModelProvider;
import com.minelittlepony.unicopia.datagen.providers.UPaintingVariantProvider;
import com.minelittlepony.unicopia.datagen.providers.loot.UBlockAdditionsLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockAdditionsLootTableProvider;
import com.minelittlepony.unicopia.datagen.providers.loot.UBlockLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockLootTableProvider;
import com.minelittlepony.unicopia.datagen.providers.loot.UChestAdditionsLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UChestAdditionsLootTableProvider;
@ -61,7 +62,9 @@ public class Datagen implements DataGeneratorEntrypoint {
pack.addProvider(UEntityTypeTagProvider::new); pack.addProvider(UEntityTypeTagProvider::new);
pack.addProvider(UStatusEffectTagProvider::new); pack.addProvider(UStatusEffectTagProvider::new);
pack.addProvider(UDimensionTypeTagProvider::new); pack.addProvider(UDimensionTypeTagProvider::new);
pack.addProvider(UPaintingVariantTagProvider::new);
final var paintingVariantProvider = pack.addProvider(UPaintingVariantProvider::new);
pack.addProvider((output, registries) -> new UPaintingVariantTagProvider(output, registries, paintingVariantProvider));
pack.addProvider(UModelProvider::new); pack.addProvider(UModelProvider::new);
pack.addProvider(URecipeProvider::new); pack.addProvider(URecipeProvider::new);

View file

@ -17,8 +17,8 @@ import com.minelittlepony.unicopia.diet.affliction.StatusEffectAffliction;
import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.effect.UEffects;
import com.minelittlepony.unicopia.item.UFoodComponents; import com.minelittlepony.unicopia.item.UFoodComponents;
import net.minecraft.component.type.FoodComponents;
import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.item.FoodComponents;
public class DietProfileGenerator { public class DietProfileGenerator {

View file

@ -55,7 +55,7 @@ public class DietsProvider implements DataProvider {
} }
keyToGroupId.computeIfAbsent(key.id(), i -> new HashSet<>()).add(id); keyToGroupId.computeIfAbsent(key.id(), i -> new HashSet<>()).add(id);
}); });
diets.accept(id, () -> FoodGroup.CODEC.encode(attributes, JsonOps.INSTANCE, new JsonObject()).result().get()); diets.accept(id, () -> FoodGroup.EFFECTS_CODEC.encode(attributes, JsonOps.INSTANCE, new JsonObject()).result().get());
}); });
var profiles = dietsCollector.prime(); var profiles = dietsCollector.prime();
new DietProfileGenerator().generate((race, profile) -> { new DietProfileGenerator().generate((race, profile) -> {

View file

@ -34,7 +34,7 @@ public class SeasonsModelGenerator extends UBlockStateModelGenerator {
private static JsonObject createTextures(String season, JsonObject input) { private static JsonObject createTextures(String season, JsonObject input) {
JsonObject textures = new JsonObject(); JsonObject textures = new JsonObject();
input.entrySet().forEach(entry -> { input.entrySet().forEach(entry -> {
textures.addProperty(entry.getKey(), new Identifier(entry.getValue().getAsString()).withPath(path -> path.replace("/", "/seasons/" + season + "/")).toString()); textures.addProperty(entry.getKey(), Identifier.of(entry.getValue().getAsString()).withPath(path -> path.replace("/", "/seasons/" + season + "/")).toString());
}); });
return textures; return textures;
} }

View file

@ -1,7 +1,9 @@
package com.minelittlepony.unicopia.datagen.providers; package com.minelittlepony.unicopia.datagen.providers;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.UTags;
@ -35,18 +37,23 @@ import net.minecraft.predicate.NumberRange;
import net.minecraft.predicate.TagPredicate; import net.minecraft.predicate.TagPredicate;
import net.minecraft.predicate.entity.DamageSourcePredicate; import net.minecraft.predicate.entity.DamageSourcePredicate;
import net.minecraft.predicate.item.EnchantmentPredicate; import net.minecraft.predicate.item.EnchantmentPredicate;
import net.minecraft.predicate.item.EnchantmentsPredicate;
import net.minecraft.predicate.item.ItemPredicate; import net.minecraft.predicate.item.ItemPredicate;
import net.minecraft.predicate.item.ItemSubPredicateTypes;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.TagKey; import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class UAdvancementsProvider extends FabricAdvancementProvider { public class UAdvancementsProvider extends FabricAdvancementProvider {
public UAdvancementsProvider(FabricDataOutput output) { public UAdvancementsProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
super(output); super(output, registryLookup);
} }
@Override @Override
public void generateAdvancement(Consumer<AdvancementEntry> consumer) { public void generateAdvancement(WrapperLookup registryLookup, Consumer<AdvancementEntry> consumer) {
AdvancementDisplayBuilder.create(UItems.ALICORN_BADGE).criterion("crafting_table", hasItems(Items.CRAFTING_TABLE)).build(consumer, "root").children(root -> { AdvancementDisplayBuilder.create(UItems.ALICORN_BADGE).criterion("crafting_table", hasItems(Items.CRAFTING_TABLE)).build(consumer, "root").children(root -> {
createTribeRootAdvancement(consumer, root, Race.EARTH).children(consumer, this::generateEarthTribeAdvancementsTree); createTribeRootAdvancement(consumer, root, Race.EARTH).children(consumer, this::generateEarthTribeAdvancementsTree);
createTribeRootAdvancement(consumer, root, Race.BAT).children(consumer, this::generateBatTribeAdvancementsTree); createTribeRootAdvancement(consumer, root, Race.BAT).children(consumer, this::generateBatTribeAdvancementsTree);
@ -195,7 +202,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider {
AdvancementDisplayBuilder.create(Items.NETHERITE_SCRAP).showToast().announce() AdvancementDisplayBuilder.create(Items.NETHERITE_SCRAP).showToast().announce()
.criterion("enchant_with_consumption", enchant(UEnchantments.CONSUMPTION)) .criterion("enchant_with_consumption", enchant(UEnchantments.CONSUMPTION))
.rewards(AdvancementRewards.Builder.experience(120)) .rewards(AdvancementRewards.Builder.experience(120))
.parent(new Identifier("story/enchant_item")) .parent(Identifier.ofVanilla("story/enchant_item"))
.group("enchanting") .group("enchanting")
.build(consumer, "experimental") .build(consumer, "experimental")
.child(Items.NETHERITE_PICKAXE) .child(Items.NETHERITE_PICKAXE)
@ -207,7 +214,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider {
AdvancementDisplayBuilder.create(Items.GOLDEN_APPLE).showToast().announce() AdvancementDisplayBuilder.create(Items.GOLDEN_APPLE).showToast().announce()
.criterion("enchant_with_heart_bound", enchant(UEnchantments.HEART_BOUND)) .criterion("enchant_with_heart_bound", enchant(UEnchantments.HEART_BOUND))
.rewards(AdvancementRewards.Builder.experience(120)) .rewards(AdvancementRewards.Builder.experience(120))
.parent(new Identifier("story/enchant_item")) .parent(Identifier.ofVanilla("story/enchant_item"))
.group("enchanting") .group("enchanting")
.build(consumer, "hearts_stronger_than_horses") .build(consumer, "hearts_stronger_than_horses")
.child(Items.GOLDEN_PICKAXE) .child(Items.GOLDEN_PICKAXE)
@ -218,11 +225,11 @@ public class UAdvancementsProvider extends FabricAdvancementProvider {
.build(consumer, "soulmate"); .build(consumer, "soulmate");
} }
public static AdvancementCriterion<?> enchant(Enchantment enchantment) { public static AdvancementCriterion<?> enchant(RegistryEntry<Enchantment> enchantment) {
return Criteria.ENCHANTED_ITEM.create(new EnchantedItemCriterion.Conditions( return Criteria.ENCHANTED_ITEM.create(new EnchantedItemCriterion.Conditions(
Optional.empty(), Optional.empty(),
Optional.of(ItemPredicate.Builder.create() Optional.of(ItemPredicate.Builder.create()
.enchantment(new EnchantmentPredicate(enchantment, NumberRange.IntRange.ANY)) .subPredicate(ItemSubPredicateTypes.ENCHANTMENTS, EnchantmentsPredicate.enchantments(List.of(new EnchantmentPredicate(enchantment, NumberRange.IntRange.ANY))))
.build()), .build()),
NumberRange.IntRange.ANY NumberRange.IntRange.ANY
)); ));

View file

@ -57,8 +57,8 @@ import static net.minecraft.data.client.VariantSettings.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*; import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class UBlockStateModelGenerator extends BlockStateModelGenerator { public class UBlockStateModelGenerator extends BlockStateModelGenerator {
static final Identifier AIR_BLOCK_ID = new Identifier("block/air"); static final Identifier AIR_BLOCK_ID = Identifier.ofVanilla("block/air");
static final Identifier AIR_ITEM_ID = new Identifier("item/air"); static final Identifier AIR_ITEM_ID = Identifier.ofVanilla("item/air");
static UBlockStateModelGenerator create(BlockStateModelGenerator modelGenerator) { static UBlockStateModelGenerator create(BlockStateModelGenerator modelGenerator) {
return new UBlockStateModelGenerator(modelGenerator.blockStateCollector, modelGenerator.modelCollector, modelGenerator::excludeFromSimpleItemModelGeneration); return new UBlockStateModelGenerator(modelGenerator.blockStateCollector, modelGenerator.modelCollector, modelGenerator::excludeFromSimpleItemModelGeneration);
@ -166,9 +166,9 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator {
// bales // bales
registerAll((g, block) -> g.registerBale(Unicopia.id(block.getLeft().getPath().replace("bale", "block")), block.getLeft(), block.getRight()), registerAll((g, block) -> g.registerBale(Unicopia.id(block.getLeft().getPath().replace("bale", "block")), block.getLeft(), block.getRight()),
new Pair<>(new Identifier("hay_block"), "_top"), new Pair<>(Identifier.ofVanilla("hay_block"), "_top"),
new Pair<>(new Identifier("farmersdelight", "rice_bale"), "_top"), new Pair<>(Identifier.of("farmersdelight", "rice_bale"), "_top"),
new Pair<>(new Identifier("farmersdelight", "straw_bale"), "_end") new Pair<>(Identifier.of("farmersdelight", "straw_bale"), "_end")
); );
// shells // shells
registerAll(UBlockStateModelGenerator::registerShell, UBlocks.CLAM_SHELL, UBlocks.TURRET_SHELL, UBlocks.SCALLOP_SHELL); registerAll(UBlockStateModelGenerator::registerShell, UBlocks.CLAM_SHELL, UBlocks.TURRET_SHELL, UBlocks.SCALLOP_SHELL);

View file

@ -0,0 +1,60 @@
package com.minelittlepony.unicopia.datagen.providers;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.minelittlepony.unicopia.Unicopia;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider;
import net.minecraft.entity.decoration.painting.PaintingVariant;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
public class UPaintingVariantProvider extends FabricDynamicRegistryProvider {
private final List<RegistryKey<PaintingVariant>> keys = new ArrayList<>();
public UPaintingVariantProvider(FabricDataOutput output, CompletableFuture<WrapperLookup> registriesFuture) {
super(output, registriesFuture);
}
@Override
public String getName() {
return "Painting Variants";
}
public List<RegistryKey<PaintingVariant>> getKeys() {
return keys;
}
@Override
protected void configure(WrapperLookup registries, Entries entries) {
register(entries, "bloom", 2, 1);
register(entries, "chicken", 2, 1);
register(entries, "bells", 2, 1);
register(entries, "crystal", 3, 3);
register(entries, "harmony", 3, 3);
register(entries, "equality", 2, 4);
register(entries, "solar", 2, 4);
register(entries, "lunar", 2, 4);
register(entries, "platinum", 2, 4);
register(entries, "hurricane", 2, 4);
register(entries, "pudding", 2, 4);
register(entries, "terra", 2, 4);
register(entries, "equestria", 2, 4);
register(entries, "blossom", 2, 3);
register(entries, "shadow", 2, 3);
}
private void register(Entries entries, String name, int width, int height) {
RegistryKey<PaintingVariant> key = RegistryKey.of(RegistryKeys.PAINTING_VARIANT, Unicopia.id(name));
keys.add(key);
entries.add(key, new PaintingVariant(width, height, key.getValue()));
}
}

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia.datagen.providers.loot; package com.minelittlepony.unicopia.datagen.providers.loot;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function; import java.util.function.Function;
import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.UTags;
@ -31,6 +32,7 @@ import net.minecraft.predicate.NumberRange;
import net.minecraft.predicate.entity.LocationPredicate; import net.minecraft.predicate.entity.LocationPredicate;
import net.minecraft.predicate.item.EnchantmentPredicate; import net.minecraft.predicate.item.EnchantmentPredicate;
import net.minecraft.predicate.item.ItemPredicate; import net.minecraft.predicate.item.ItemPredicate;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.world.biome.BiomeKeys; import net.minecraft.world.biome.BiomeKeys;
@ -44,8 +46,8 @@ public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvid
LocationCheckLootCondition.builder(LocationPredicate.Builder.create().biome(BiomeKeys.OCEAN)) LocationCheckLootCondition.builder(LocationPredicate.Builder.create().biome(BiomeKeys.OCEAN))
.or(LocationCheckLootCondition.builder(LocationPredicate.Builder.create().biome(BiomeKeys.BEACH))); .or(LocationCheckLootCondition.builder(LocationPredicate.Builder.create().biome(BiomeKeys.BEACH)));
public UBlockAdditionsLootTableProvider(FabricDataOutput dataOutput) { public UBlockAdditionsLootTableProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
super(dataOutput); super(dataOutput, registryLookup);
} }
@Override @Override

View file

@ -7,11 +7,11 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.recipe.CloudShapingRecipe; import com.minelittlepony.unicopia.recipe.CloudShapingRecipe;
import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Either;
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags;
import net.minecraft.advancement.AdvancementCriterion; import net.minecraft.advancement.AdvancementCriterion;
import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.data.server.recipe.SingleItemRecipeJsonBuilder; import net.minecraft.data.server.recipe.StonecuttingRecipeJsonBuilder;
import net.minecraft.data.server.recipe.VanillaRecipeProvider; import net.minecraft.data.server.recipe.VanillaRecipeProvider;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
@ -42,8 +42,8 @@ public interface CraftingMaterialHelper {
} }
return Either.left( return Either.left(
Registries.ITEM.getOrEmpty(id) Registries.ITEM.getOrEmpty(id)
.or(() -> Registries.ITEM.getOrEmpty(new Identifier(Identifier.DEFAULT_NAMESPACE, id.getPath()))) .or(() -> Registries.ITEM.getOrEmpty(Identifier.ofVanilla(id.getPath())))
.or(() -> Registries.ITEM.getOrEmpty(new Identifier(Identifier.DEFAULT_NAMESPACE, id.getPath().replace(suffex, "")))) .or(() -> Registries.ITEM.getOrEmpty(Identifier.ofVanilla(id.getPath().replace(suffex, ""))))
.orElseThrow(() -> new NoSuchElementException("No item with id " + id)) .orElseThrow(() -> new NoSuchElementException("No item with id " + id))
); );
} }
@ -84,7 +84,7 @@ public interface CraftingMaterialHelper {
return "has_" + spell.getId() + "_gemstone"; return "has_" + spell.getId() + "_gemstone";
} }
static SingleItemRecipeJsonBuilder createCloudShaping(Ingredient input, RecipeCategory category, ItemConvertible output, int count) { static StonecuttingRecipeJsonBuilder createCloudShaping(Ingredient input, RecipeCategory category, ItemConvertible output, int count) {
return new SingleItemRecipeJsonBuilder(category, CloudShapingRecipe::new, input, output, count); return new StonecuttingRecipeJsonBuilder(category, CloudShapingRecipe::new, input, output, count);
} }
} }

View file

@ -7,6 +7,7 @@ import java.util.Map;
import org.spongepowered.include.com.google.common.base.Preconditions; import org.spongepowered.include.com.google.common.base.Preconditions;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.advancement.Advancement; import net.minecraft.advancement.Advancement;
@ -15,19 +16,21 @@ import net.minecraft.advancement.AdvancementRequirements;
import net.minecraft.advancement.AdvancementRewards; import net.minecraft.advancement.AdvancementRewards;
import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; import net.minecraft.advancement.criterion.RecipeUnlockedCriterion;
import net.minecraft.data.server.recipe.RecipeExporter; import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.Recipe; import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeSerializer; import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.RecipeType; import net.minecraft.recipe.RecipeType;
import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.recipe.input.CraftingRecipeInput;
import net.minecraft.recipe.input.RecipeInput;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.tag.TagKey; import net.minecraft.registry.tag.TagKey;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -43,7 +46,7 @@ public class CuttingBoardRecipeJsonBuilder {
private final List<Result> results = new ArrayList<>(); private final List<Result> results = new ArrayList<>();
private final List<Ingredient> ingredients = new ArrayList<>(); private final List<Ingredient> ingredients = new ArrayList<>();
private Identifier sound = new Identifier("minecraft:item.axe.strip"); private Identifier sound = Identifier.ofVanilla("item.axe.strip");
public static CuttingBoardRecipeJsonBuilder create(ItemConvertible output, TagKey<Item> tool) { public static CuttingBoardRecipeJsonBuilder create(ItemConvertible output, TagKey<Item> tool) {
return new CuttingBoardRecipeJsonBuilder(output, tool); return new CuttingBoardRecipeJsonBuilder(output, tool);
@ -90,7 +93,7 @@ public class CuttingBoardRecipeJsonBuilder {
exporter.accept(id, exporter.accept(id,
new CuttingBoardRecipe( new CuttingBoardRecipe(
ingredients, ingredients,
new Tool(new Identifier("farmersdelight:tool"), tool), new Tool(Identifier.of("farmersdelight:tool"), tool),
sound, sound,
results results
), ),
@ -103,7 +106,7 @@ public class CuttingBoardRecipeJsonBuilder {
} }
public void offerTo(RecipeExporter exporter, String recipePath) { public void offerTo(RecipeExporter exporter, String recipePath) {
Identifier recipeId = new Identifier(recipePath); Identifier recipeId = Identifier.of(recipePath);
if (recipeId.equals(Registries.ITEM.getId(output.asItem()))) { if (recipeId.equals(Registries.ITEM.getId(output.asItem()))) {
throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one"); throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one");
} }
@ -119,7 +122,7 @@ public class CuttingBoardRecipeJsonBuilder {
public record Result(Identifier item, int count) { public record Result(Identifier item, int count) {
public static final Codec<Result> CODEC = RecordCodecBuilder.create(i -> i.group( public static final Codec<Result> CODEC = RecordCodecBuilder.create(i -> i.group(
Identifier.CODEC.fieldOf("item").forGetter(Result::item), Identifier.CODEC.fieldOf("item").forGetter(Result::item),
Codecs.createStrictOptionalFieldCodec(Codecs.POSITIVE_INT, "count", 1).forGetter(Result::count) Codecs.POSITIVE_INT.optionalFieldOf("count", 1).forGetter(Result::count)
).apply(i, Result::new)); ).apply(i, Result::new));
} }
@ -128,8 +131,14 @@ public class CuttingBoardRecipeJsonBuilder {
Tool tool, Tool tool,
Identifier sound, Identifier sound,
List<Result> result List<Result> result
) implements Recipe<Inventory> { ) implements Recipe<CraftingRecipeInput> {
static final Identifier ID = new Identifier("farmersdelight", "cutting"); static final Identifier ID = Identifier.of("farmersdelight", "cutting");
static final MapCodec<CuttingBoardRecipe> CODEC = RecordCodecBuilder.mapCodec(i -> i.group(
Ingredient.DISALLOW_EMPTY_CODEC.listOf().fieldOf("ingredients").forGetter(CuttingBoardRecipe::ingredients),
Tool.CODEC.fieldOf("tool").forGetter(CuttingBoardRecipe::tool),
Identifier.CODEC.fieldOf("sound").forGetter(CuttingBoardRecipe::sound),
Result.CODEC.listOf().fieldOf("result").forGetter(CuttingBoardRecipe::result)
).apply(i, CuttingBoardRecipe::new));
static final RecipeType<CuttingBoardRecipe> TYPE = Registry.register(Registries.RECIPE_TYPE, ID, new RecipeType<>() { static final RecipeType<CuttingBoardRecipe> TYPE = Registry.register(Registries.RECIPE_TYPE, ID, new RecipeType<>() {
@Override @Override
public String toString() { public String toString() {
@ -138,38 +147,39 @@ public class CuttingBoardRecipeJsonBuilder {
}); });
static final RecipeSerializer<CuttingBoardRecipe> SERIALIZER = Registry.register(Registries.RECIPE_SERIALIZER, ID, new RecipeSerializer<>() { static final RecipeSerializer<CuttingBoardRecipe> SERIALIZER = Registry.register(Registries.RECIPE_SERIALIZER, ID, new RecipeSerializer<>() {
@Override @Override
public Codec<CuttingBoardRecipe> codec() { return CODEC; } public MapCodec<CuttingBoardRecipe> codec() { return CODEC; }
@Override @Override
public CuttingBoardRecipe read(PacketByteBuf buf) { return null; } public PacketCodec<RegistryByteBuf, CuttingBoardRecipe> packetCodec() { return null; }
@Override
public void write(PacketByteBuf buf, CuttingBoardRecipe recipe) { }
}); });
static final Codec<CuttingBoardRecipe> CODEC = RecordCodecBuilder.create(i -> i.group(
Ingredient.DISALLOW_EMPTY_CODEC.listOf().fieldOf("ingredients").forGetter(CuttingBoardRecipe::ingredients),
Tool.CODEC.fieldOf("tool").forGetter(CuttingBoardRecipe::tool),
Identifier.CODEC.fieldOf("sound").forGetter(CuttingBoardRecipe::sound),
Result.CODEC.listOf().fieldOf("result").forGetter(CuttingBoardRecipe::result)
).apply(i, CuttingBoardRecipe::new));
public static void bootstrap() {} public static void bootstrap() {}
@Override @Override
public boolean matches(Inventory inventory, World world) { return false; } public boolean matches(CraftingRecipeInput inventory, World world) { return false; }
@Override @Override
public ItemStack craft(Inventory inventory, DynamicRegistryManager registryManager) { return ItemStack.EMPTY; } public ItemStack craft(CraftingRecipeInput inventory, WrapperLookup registryManager) { return ItemStack.EMPTY; }
@Override @Override
public boolean fits(int width, int height) { return false; } public boolean fits(int width, int height) { return false; }
@Override @Override
public ItemStack getResult(DynamicRegistryManager registryManager) { return ItemStack.EMPTY; } public ItemStack getResult(WrapperLookup registryManager) { return ItemStack.EMPTY; }
@Override @Override
public RecipeSerializer<?> getSerializer() { return SERIALIZER; } public RecipeSerializer<?> getSerializer() { return SERIALIZER; }
@Override @Override
public RecipeType<?> getType() { return TYPE; } public RecipeType<?> getType() { return TYPE; }
static class CuttingInput implements RecipeInput {
@Override
public ItemStack getStackInSlot(int slot) {
return null;
}
@Override
public int getSize() {
return 0;
}
}
} }
} }

View file

@ -69,7 +69,7 @@ public class GrowingRecipeJsonBuilder {
} }
public void offerTo(RecipeExporter exporter, String recipePath) { public void offerTo(RecipeExporter exporter, String recipePath) {
Identifier recipeId = new Identifier(recipePath); Identifier recipeId = Identifier.of(recipePath);
Identifier id = Registries.BLOCK.getId(output.getBlock()); Identifier id = Registries.BLOCK.getId(output.getBlock());
if (recipeId.equals(id)) { if (recipeId.equals(id)) {
throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one"); throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one");

View file

@ -96,7 +96,7 @@ public class SpellcraftingRecipeJsonBuilder {
} }
public void offerTo(RecipeExporter exporter, String recipePath) { public void offerTo(RecipeExporter exporter, String recipePath) {
Identifier recipeId = new Identifier(recipePath); Identifier recipeId = Identifier.of(recipePath);
if (recipeId.equals(spell.getId())) { if (recipeId.equals(spell.getId())) {
throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one"); throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one");
} }

View file

@ -4,6 +4,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -28,8 +29,8 @@ import com.mojang.datafixers.util.Either;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.fabricmc.fabric.api.resource.conditions.v1.DefaultResourceConditions; import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions;
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags;
import net.minecraft.advancement.AdvancementCriterion; import net.minecraft.advancement.AdvancementCriterion;
import net.minecraft.advancement.criterion.Criteria; import net.minecraft.advancement.criterion.Criteria;
import net.minecraft.advancement.criterion.InventoryChangedCriterion; import net.minecraft.advancement.criterion.InventoryChangedCriterion;
@ -49,6 +50,7 @@ import net.minecraft.predicate.item.ItemPredicate;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.ItemTags; import net.minecraft.registry.tag.ItemTags;
import net.minecraft.registry.tag.TagKey; import net.minecraft.registry.tag.TagKey;
import net.minecraft.resource.featuretoggle.FeatureSet; import net.minecraft.resource.featuretoggle.FeatureSet;
@ -57,8 +59,8 @@ import net.minecraft.util.Identifier;
public class URecipeProvider extends FabricRecipeProvider { public class URecipeProvider extends FabricRecipeProvider {
private static final List<Item> WOOLS = List.of(Items.BLACK_WOOL, Items.BLUE_WOOL, Items.BROWN_WOOL, Items.CYAN_WOOL, Items.GRAY_WOOL, Items.GREEN_WOOL, Items.LIGHT_BLUE_WOOL, Items.LIGHT_GRAY_WOOL, Items.LIME_WOOL, Items.MAGENTA_WOOL, Items.ORANGE_WOOL, Items.PINK_WOOL, Items.PURPLE_WOOL, Items.RED_WOOL, Items.YELLOW_WOOL, Items.WHITE_WOOL); private static final List<Item> WOOLS = List.of(Items.BLACK_WOOL, Items.BLUE_WOOL, Items.BROWN_WOOL, Items.CYAN_WOOL, Items.GRAY_WOOL, Items.GREEN_WOOL, Items.LIGHT_BLUE_WOOL, Items.LIGHT_GRAY_WOOL, Items.LIME_WOOL, Items.MAGENTA_WOOL, Items.ORANGE_WOOL, Items.PINK_WOOL, Items.PURPLE_WOOL, Items.RED_WOOL, Items.YELLOW_WOOL, Items.WHITE_WOOL);
public URecipeProvider(FabricDataOutput output) { public URecipeProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output); super(output, registriesFuture);
} }
@Override @Override
@ -90,7 +92,7 @@ public class URecipeProvider extends FabricRecipeProvider {
.offerTo(exporter, convertBetween(UItems.SUNGLASSES, UItems.BROKEN_SUNGLASSES)); .offerTo(exporter, convertBetween(UItems.SUNGLASSES, UItems.BROKEN_SUNGLASSES));
// farmers delight // farmers delight
offerFarmersDelightCuttingRecipes(withConditions(exporter, DefaultResourceConditions.allModsLoaded("farmersdelight"))); offerFarmersDelightCuttingRecipes(withConditions(exporter, ResourceConditions.allModsLoaded("farmersdelight")));
} }
private void generateVanillaRecipeExtensions(RecipeExporter exporter) { private void generateVanillaRecipeExtensions(RecipeExporter exporter) {
@ -732,7 +734,7 @@ public class URecipeProvider extends FabricRecipeProvider {
CuttingBoardRecipeJsonBuilder.create(stripped, ItemTags.AXES) CuttingBoardRecipeJsonBuilder.create(stripped, ItemTags.AXES)
.input(unstripped).criterion(hasItem(unstripped), conditionsFromItem(unstripped)) .input(unstripped).criterion(hasItem(unstripped), conditionsFromItem(unstripped))
.sound(SoundEvents.ITEM_AXE_STRIP) .sound(SoundEvents.ITEM_AXE_STRIP)
.result(new Identifier("farmersdelight:tree_bark")) .result(Identifier.of("farmersdelight:tree_bark"))
.offerTo(exporter, convertBetween(stripped, unstripped)); .offerTo(exporter, convertBetween(stripped, unstripped));
}); });
} }

View file

@ -14,7 +14,7 @@ public interface SereneSeasonsTags {
TagKey<Item> SUMMER_CROPS = item("summer_crops"); TagKey<Item> SUMMER_CROPS = item("summer_crops");
private static TagKey<Item> item(String name) { private static TagKey<Item> item(String name) {
return TagKey.of(RegistryKeys.ITEM, new Identifier("sereneseasons", name)); return TagKey.of(RegistryKeys.ITEM, Identifier.of("sereneseasons", name));
} }
} }
@ -25,7 +25,7 @@ public interface SereneSeasonsTags {
TagKey<Block> SUMMER_CROPS = block("summer_crops"); TagKey<Block> SUMMER_CROPS = block("summer_crops");
private static TagKey<Block> block(String name) { private static TagKey<Block> block(String name) {
return TagKey.of(RegistryKeys.BLOCK, new Identifier("sereneseasons", name)); return TagKey.of(RegistryKeys.BLOCK, Identifier.of("sereneseasons", name));
} }
} }

View file

@ -12,11 +12,10 @@ import com.minelittlepony.unicopia.server.world.UTreeGen;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBlockTags; import net.fabricmc.fabric.api.tag.convention.v2.ConventionalBlockTags;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.RegistryWrapper.WrapperLookup; import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.BlockTags;
@ -101,7 +100,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider {
getOrCreateTagBuilder(UTags.Blocks.KICKS_UP_DUST).forceAddTag(BlockTags.SAND).add( getOrCreateTagBuilder(UTags.Blocks.KICKS_UP_DUST).forceAddTag(BlockTags.SAND).add(
Blocks.SUSPICIOUS_SAND, Blocks.SUSPICIOUS_SAND,
Blocks.GRAVEL, Blocks.SUSPICIOUS_GRAVEL Blocks.GRAVEL, Blocks.SUSPICIOUS_GRAVEL
).forceAddTag(TagKey.of(RegistryKeys.BLOCK, new Identifier("c", "concrete_powders"))); ).forceAddTag(ConventionalBlockTags.CONCRETES);
getOrCreateTagBuilder(UTags.Blocks.UNAFFECTED_BY_GROW_ABILITY).add(Blocks.GRASS_BLOCK); getOrCreateTagBuilder(UTags.Blocks.UNAFFECTED_BY_GROW_ABILITY).add(Blocks.GRASS_BLOCK);
addSeasonalCrops(); addSeasonalCrops();
@ -252,9 +251,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider {
} }
private void populateConventionalTags() { private void populateConventionalTags() {
getOrCreateTagBuilder(UConventionalTags.Blocks.CONCRETES).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_concrete"))).toArray(Block[]::new)); getOrCreateTagBuilder(UConventionalTags.Blocks.CONCRETE_POWDERS).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(Identifier.of(i.getName() + "_concrete_powder"))).toArray(Block[]::new));
getOrCreateTagBuilder(UConventionalTags.Blocks.CONCRETE_POWDERS).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_concrete_powder"))).toArray(Block[]::new));
getOrCreateTagBuilder(UConventionalTags.Blocks.GLAZED_TERRACOTTAS).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_glazed_terracotta"))).toArray(Block[]::new));
getOrCreateTagBuilder(UConventionalTags.Blocks.CORAL_BLOCKS).add(Blocks.TUBE_CORAL_BLOCK, Blocks.BRAIN_CORAL_BLOCK, Blocks.BUBBLE_CORAL_BLOCK, Blocks.FIRE_CORAL_BLOCK, Blocks.HORN_CORAL_BLOCK); getOrCreateTagBuilder(UConventionalTags.Blocks.CORAL_BLOCKS).add(Blocks.TUBE_CORAL_BLOCK, Blocks.BRAIN_CORAL_BLOCK, Blocks.BUBBLE_CORAL_BLOCK, Blocks.FIRE_CORAL_BLOCK, Blocks.HORN_CORAL_BLOCK);
getOrCreateTagBuilder(UConventionalTags.Blocks.CORAL_FANS).add(Blocks.TUBE_CORAL_FAN, Blocks.BRAIN_CORAL_FAN, Blocks.BUBBLE_CORAL_FAN, Blocks.FIRE_CORAL_FAN, Blocks.HORN_CORAL_FAN); getOrCreateTagBuilder(UConventionalTags.Blocks.CORAL_FANS).add(Blocks.TUBE_CORAL_FAN, Blocks.BRAIN_CORAL_FAN, Blocks.BUBBLE_CORAL_FAN, Blocks.FIRE_CORAL_FAN, Blocks.HORN_CORAL_FAN);
getOrCreateTagBuilder(UConventionalTags.Blocks.CORALS).add(Blocks.TUBE_CORAL, Blocks.BRAIN_CORAL, Blocks.BUBBLE_CORAL, Blocks.FIRE_CORAL, Blocks.HORN_CORAL); getOrCreateTagBuilder(UConventionalTags.Blocks.CORALS).add(Blocks.TUBE_CORAL, Blocks.BRAIN_CORAL, Blocks.BUBBLE_CORAL, Blocks.FIRE_CORAL, Blocks.HORN_CORAL);

View file

@ -18,18 +18,18 @@ public class UDimensionTypeTagProvider extends FabricTagProvider<DimensionType>
@Override @Override
protected void configure(WrapperLookup lookup) { protected void configure(WrapperLookup lookup) {
getOrCreateTagBuilder(UTags.DimensionTypes.HAS_NO_ATMOSPHERE) getOrCreateTagBuilder(UTags.DimensionTypes.HAS_NO_ATMOSPHERE)
.addOptional(new Identifier("ad_astra", "earth_orbit")) .addOptional(Identifier.of("ad_astra", "earth_orbit"))
.addOptional(new Identifier("ad_astra", "glacio_orbit")) .addOptional(Identifier.of("ad_astra", "glacio_orbit"))
.addOptional(new Identifier("ad_astra", "mars_orbit")) .addOptional(Identifier.of("ad_astra", "mars_orbit"))
.addOptional(new Identifier("ad_astra", "mercury_orbit")) .addOptional(Identifier.of("ad_astra", "mercury_orbit"))
.addOptional(new Identifier("ad_astra", "moon")).addOptional(new Identifier("adastra", "moon_orbit")) .addOptional(Identifier.of("ad_astra", "moon")).addOptional(Identifier.of("adastra", "moon_orbit"))
.addOptional(new Identifier("ad_astra", "venus_orbit")) .addOptional(Identifier.of("ad_astra", "venus_orbit"))
.addOptional(new Identifier("adastra", "earth_orbit")) .addOptional(Identifier.of("adastra", "earth_orbit"))
.addOptional(new Identifier("adastra", "glacio_orbit")) .addOptional(Identifier.of("adastra", "glacio_orbit"))
.addOptional(new Identifier("adastra", "mars_orbit")) .addOptional(Identifier.of("adastra", "mars_orbit"))
.addOptional(new Identifier("adastra", "mercury_orbit")) .addOptional(Identifier.of("adastra", "mercury_orbit"))
.addOptional(new Identifier("adastra", "moon")).addOptional(new Identifier("adastra", "moon_orbit")) .addOptional(Identifier.of("adastra", "moon")).addOptional(Identifier.of("adastra", "moon_orbit"))
.addOptional(new Identifier("adastra", "venus_orbit")); .addOptional(Identifier.of("adastra", "venus_orbit"));
} }
} }

View file

@ -19,7 +19,7 @@ import com.minelittlepony.unicopia.server.world.UTreeGen;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.data.family.BlockFamily; import net.minecraft.data.family.BlockFamily;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -67,7 +67,6 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
getOrCreateTagBuilder(ItemTags.CHEST_BOATS).add(UItems.PALM_CHEST_BOAT); getOrCreateTagBuilder(ItemTags.CHEST_BOATS).add(UItems.PALM_CHEST_BOAT);
getOrCreateTagBuilder(ItemTags.BOATS).add(UItems.PALM_BOAT); getOrCreateTagBuilder(ItemTags.BOATS).add(UItems.PALM_BOAT);
getOrCreateTagBuilder(ItemTags.MUSIC_DISCS).add(ItemFamilies.MUSIC_DISCS);
getOrCreateTagBuilder(ItemTags.CREEPER_DROP_MUSIC_DISCS).add(UItems.MUSIC_DISC_CRUSADE, UItems.MUSIC_DISC_FUNK, UItems.MUSIC_DISC_PET, UItems.MUSIC_DISC_POPULAR); getOrCreateTagBuilder(ItemTags.CREEPER_DROP_MUSIC_DISCS).add(UItems.MUSIC_DISC_CRUSADE, UItems.MUSIC_DISC_FUNK, UItems.MUSIC_DISC_PET, UItems.MUSIC_DISC_POPULAR);
getOrCreateTagBuilder(ItemTags.SIGNS).add(UBlocks.PALM_SIGN.asItem()); getOrCreateTagBuilder(ItemTags.SIGNS).add(UBlocks.PALM_SIGN.asItem());
@ -76,8 +75,6 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
getOrCreateTagBuilder(UTags.Items.HORSE_SHOES).add(ItemFamilies.HORSE_SHOES); getOrCreateTagBuilder(UTags.Items.HORSE_SHOES).add(ItemFamilies.HORSE_SHOES);
getOrCreateTagBuilder(UTags.Items.POLEARMS).add(ItemFamilies.POLEARMS); getOrCreateTagBuilder(UTags.Items.POLEARMS).add(ItemFamilies.POLEARMS);
getOrCreateTagBuilder(ItemTags.TOOLS).addTag(UTags.Items.HORSE_SHOES).addTag(UTags.Items.POLEARMS);
getOrCreateTagBuilder(UTags.Items.BASKETS).add(ItemFamilies.BASKETS); getOrCreateTagBuilder(UTags.Items.BASKETS).add(ItemFamilies.BASKETS);
getOrCreateTagBuilder(UTags.Items.BADGES).add(Race.REGISTRY.stream() getOrCreateTagBuilder(UTags.Items.BADGES).add(Race.REGISTRY.stream()
.map(race -> race.getId().withPath(p -> p + "_badge")) .map(race -> race.getId().withPath(p -> p + "_badge"))
@ -93,7 +90,7 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
// technical tags // technical tags
getOrCreateTagBuilder(ItemTags.VILLAGER_PLANTABLE_SEEDS).addTag(UTags.Items.APPLE_SEEDS); getOrCreateTagBuilder(ItemTags.VILLAGER_PLANTABLE_SEEDS).addTag(UTags.Items.APPLE_SEEDS);
getOrCreateTagBuilder(UTags.Items.CAN_CUT_PIE).forceAddTag(ConventionalItemTags.SHEARS).addOptionalTag(UConventionalTags.Items.TOOL_KNIVES); getOrCreateTagBuilder(UTags.Items.CAN_CUT_PIE).forceAddTag(ConventionalItemTags.SHEAR_TOOLS).addOptionalTag(UConventionalTags.Items.TOOL_KNIVES);
getOrCreateTagBuilder(UTags.Items.COOLS_OFF_KIRINS).add(Items.MELON_SLICE, UItems.JUICE).forceAddTag(ConventionalItemTags.WATER_BUCKETS); getOrCreateTagBuilder(UTags.Items.COOLS_OFF_KIRINS).add(Items.MELON_SLICE, UItems.JUICE).forceAddTag(ConventionalItemTags.WATER_BUCKETS);
getOrCreateTagBuilder(UTags.Items.FALLS_SLOWLY).add(Items.FEATHER, UItems.CLOUD_LUMP).forceAddTag(UTags.Items.MAGIC_FEATHERS); getOrCreateTagBuilder(UTags.Items.FALLS_SLOWLY).add(Items.FEATHER, UItems.CLOUD_LUMP).forceAddTag(UTags.Items.MAGIC_FEATHERS);
getOrCreateTagBuilder(UTags.Items.IS_DELIVERED_AGGRESSIVELY).forceAddTag(ItemTags.ANVIL); getOrCreateTagBuilder(UTags.Items.IS_DELIVERED_AGGRESSIVELY).forceAddTag(ItemTags.ANVIL);
@ -125,8 +122,8 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
Items.GOLDEN_PICKAXE, Items.GOLDEN_SHOVEL, Items.GOLDEN_AXE, Items.GOLDEN_SWORD, Items.GOLDEN_HOE, Items.GOLDEN_PICKAXE, Items.GOLDEN_SHOVEL, Items.GOLDEN_AXE, Items.GOLDEN_SWORD, Items.GOLDEN_HOE,
UItems.GOLDEN_HORSE_SHOE, UItems.GOLDEN_POLEARM, UItems.GOLDEN_FEATHER, UItems.GOLDEN_WING, UItems.GOLDEN_HORSE_SHOE, UItems.GOLDEN_POLEARM, UItems.GOLDEN_FEATHER, UItems.GOLDEN_WING,
UItems.GOLDEN_OAK_SEEDS UItems.GOLDEN_OAK_SEEDS
).forceAddTag(ConventionalItemTags.GOLD_INGOTS).forceAddTag(ConventionalItemTags.RAW_GOLD_ORES).forceAddTag(ConventionalItemTags.RAW_GOLD_BLOCKS) ).forceAddTag(ConventionalItemTags.GOLD_INGOTS).forceAddTag(ConventionalItemTags.GOLD_RAW_MATERIALS).forceAddTag(ConventionalItemTags.STORAGE_BLOCKS_RAW_GOLD)
.addOptionalTag(new Identifier("farmersdelight:golden_knife")); .addOptionalTag(Identifier.of("farmersdelight:golden_knife"));
getOrCreateTagBuilder(UTags.Items.LOOT_BUG_EPIC_DROPS).add( getOrCreateTagBuilder(UTags.Items.LOOT_BUG_EPIC_DROPS).add(
Items.DIAMOND_BLOCK, Items.DIAMOND_BLOCK,
Items.DIAMOND_HELMET, Items.DIAMOND_BOOTS, Items.DIAMOND_LEGGINGS, Items.DIAMOND_CHESTPLATE, Items.DIAMOND_HELMET, Items.DIAMOND_BOOTS, Items.DIAMOND_LEGGINGS, Items.DIAMOND_CHESTPLATE,
@ -316,10 +313,10 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
getOrCreateTagBuilder(UConventionalTags.Items.APPLES) getOrCreateTagBuilder(UConventionalTags.Items.APPLES)
.add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, UItems.ROTTEN_APPLE) .add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, UItems.ROTTEN_APPLE)
.forceAddTag(UTags.Items.FRESH_APPLES) .forceAddTag(UTags.Items.FRESH_APPLES)
.addOptionalTag(new Identifier("c", "pyrite_apples")) // no idea which mod add pyrite apples .addOptionalTag(Identifier.of("c", "pyrite_apples")) // no idea which mod add pyrite apples
; ;
getOrCreateTagBuilder(UConventionalTags.Items.BANANAS).add(UItems.BANANA); getOrCreateTagBuilder(UConventionalTags.Items.BANANAS).add(UItems.BANANA);
getOrCreateTagBuilder(UConventionalTags.Items.RAW_FISH).add(Items.COD, Items.SALMON, Items.PUFFERFISH, Items.TROPICAL_FISH).addOptionalTag(new Identifier("c", "mollusks")); getOrCreateTagBuilder(UConventionalTags.Items.RAW_FISH).add(Items.COD, Items.SALMON, Items.PUFFERFISH, Items.TROPICAL_FISH).addOptionalTag(Identifier.of("c", "mollusks"));
getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON, UItems.COOKED_TROPICAL_FISH, UItems.COOKED_PUFFERFISH, UItems.FRIED_AXOLOTL); getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON, UItems.COOKED_TROPICAL_FISH, UItems.COOKED_PUFFERFISH, UItems.FRIED_AXOLOTL);
getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_FISH).add(UItems.ROTTEN_COD, UItems.ROTTEN_TROPICAL_FISH, UItems.ROTTEN_SALMON, UItems.ROTTEN_PUFFERFISH); getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_FISH).add(UItems.ROTTEN_COD, UItems.ROTTEN_TROPICAL_FISH, UItems.ROTTEN_SALMON, UItems.ROTTEN_PUFFERFISH);
getOrCreateTagBuilder(ItemTags.FISHES).add( getOrCreateTagBuilder(ItemTags.FISHES).add(
@ -328,24 +325,24 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
); );
getOrCreateTagBuilder(UConventionalTags.Items.COOKED_MEAT) getOrCreateTagBuilder(UConventionalTags.Items.COOKED_MEAT)
.add(Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.COOKED_MUTTON, Items.COOKED_RABBIT, Items.COOKED_CHICKEN, Items.RABBIT_STEW) .add(Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.COOKED_MUTTON, Items.COOKED_RABBIT, Items.COOKED_CHICKEN, Items.RABBIT_STEW)
.addOptionalTag(new Identifier("c", "cooked_bacon")) .addOptionalTag(Identifier.of("c", "cooked_bacon"))
.addOptionalTag(new Identifier("c", "cooked_beef")) .addOptionalTag(Identifier.of("c", "cooked_beef"))
.addOptionalTag(new Identifier("c", "cooked_chicken")) .addOptionalTag(Identifier.of("c", "cooked_chicken"))
.addOptionalTag(new Identifier("c", "cooked_mutton")) .addOptionalTag(Identifier.of("c", "cooked_mutton"))
.addOptionalTag(new Identifier("c", "cooked_pork")) .addOptionalTag(Identifier.of("c", "cooked_pork"))
.addOptionalTag(new Identifier("c", "fried_chickens")) .addOptionalTag(Identifier.of("c", "fried_chickens"))
.addOptionalTag(new Identifier("c", "hamburgers")) .addOptionalTag(Identifier.of("c", "hamburgers"))
.addOptionalTag(new Identifier("c", "pork_and_beans")) .addOptionalTag(Identifier.of("c", "pork_and_beans"))
.addOptionalTag(new Identifier("c", "pork_jerkies")) .addOptionalTag(Identifier.of("c", "pork_jerkies"))
.addOptionalTag(new Identifier("c", "protien")); .addOptionalTag(Identifier.of("c", "protien"));
getOrCreateTagBuilder(UConventionalTags.Items.RAW_MEAT) getOrCreateTagBuilder(UConventionalTags.Items.RAW_MEAT)
.add(Items.PORKCHOP, Items.BEEF, Items.MUTTON, Items.RABBIT, Items.CHICKEN) .add(Items.PORKCHOP, Items.BEEF, Items.MUTTON, Items.RABBIT, Items.CHICKEN)
.addOptionalTag(new Identifier("c", "raw_bacon")) .addOptionalTag(Identifier.of("c", "raw_bacon"))
.addOptionalTag(new Identifier("c", "raw_beef")) .addOptionalTag(Identifier.of("c", "raw_beef"))
.addOptionalTag(new Identifier("c", "raw_chicken")) .addOptionalTag(Identifier.of("c", "raw_chicken"))
.addOptionalTag(new Identifier("c", "raw_mutton")) .addOptionalTag(Identifier.of("c", "raw_mutton"))
.addOptionalTag(new Identifier("c", "raw_pork")) .addOptionalTag(Identifier.of("c", "raw_pork"))
.addOptionalTag(new Identifier("c", "lemon_chickens")); .addOptionalTag(Identifier.of("c", "lemon_chickens"));
getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_MEAT).add(Items.ROTTEN_FLESH); getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_MEAT).add(Items.ROTTEN_FLESH);
getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_INSECT).add(Items.FERMENTED_SPIDER_EYE); getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_INSECT).add(Items.FERMENTED_SPIDER_EYE);
getOrCreateTagBuilder(UConventionalTags.Items.COOKED_INSECT).add(UItems.COOKED_FROG_LEGS); getOrCreateTagBuilder(UConventionalTags.Items.COOKED_INSECT).add(UItems.COOKED_FROG_LEGS);
@ -368,9 +365,9 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
getOrCreateTagBuilder(UConventionalTags.Items.NUTS).add(UItems.BOWL_OF_NUTS) getOrCreateTagBuilder(UConventionalTags.Items.NUTS).add(UItems.BOWL_OF_NUTS)
.addOptionalTag(UConventionalTags.Items.CROPS_PEANUTS) .addOptionalTag(UConventionalTags.Items.CROPS_PEANUTS)
.forceAddTag(UConventionalTags.Items.ACORNS) .forceAddTag(UConventionalTags.Items.ACORNS)
.addOptional(new Identifier("garnished", "nuts")) .addOptional(Identifier.of("garnished", "nuts"))
.addOptional(new Identifier("garnished", "nut_mix")) .addOptional(Identifier.of("garnished", "nut_mix"))
.addOptional(new Identifier("garnished", "neverable_delecacies")); .addOptional(Identifier.of("garnished", "neverable_delecacies"));
getOrCreateTagBuilder(UConventionalTags.Items.FRUITS) getOrCreateTagBuilder(UConventionalTags.Items.FRUITS)
.add(Items.MELON_SLICE, Items.SWEET_BERRIES, Items.GLOW_BERRIES, Items.CHORUS_FRUIT) .add(Items.MELON_SLICE, Items.SWEET_BERRIES, Items.GLOW_BERRIES, Items.CHORUS_FRUIT)
.add(UItems.JUICE, UItems.ZAP_APPLE, UItems.ZAP_BULB) .add(UItems.JUICE, UItems.ZAP_APPLE, UItems.ZAP_BULB)
@ -378,7 +375,7 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
.forceAddTag(UConventionalTags.Items.PINEAPPLES) .forceAddTag(UConventionalTags.Items.PINEAPPLES)
.forceAddTag(UConventionalTags.Items.APPLES) .forceAddTag(UConventionalTags.Items.APPLES)
.forceAddTag(UConventionalTags.Items.BANANAS) .forceAddTag(UConventionalTags.Items.BANANAS)
.addOptionalTag(new Identifier("garnished", "berries")); .addOptionalTag(Identifier.of("garnished", "berries"));
getOrCreateTagBuilder(UConventionalTags.Items.DESSERTS).add(Items.CAKE, UItems.APPLE_PIE_SLICE).forceAddTag(UTags.Items.PIES); getOrCreateTagBuilder(UConventionalTags.Items.DESSERTS).add(Items.CAKE, UItems.APPLE_PIE_SLICE).forceAddTag(UTags.Items.PIES);
getOrCreateTagBuilder(UConventionalTags.Items.CANDY).add(Items.SUGAR, UItems.ROCK_CANDY, UItems.CANDIED_APPLE); getOrCreateTagBuilder(UConventionalTags.Items.CANDY).add(Items.SUGAR, UItems.ROCK_CANDY, UItems.CANDIED_APPLE);
getOrCreateTagBuilder(UTags.Items.BAKED_GOODS).add( getOrCreateTagBuilder(UTags.Items.BAKED_GOODS).add(
@ -391,78 +388,78 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider {
private void exportFarmersDelightItems() { private void exportFarmersDelightItems() {
getOrCreateTagBuilder(UTags.Items.COOLS_OFF_KIRINS) getOrCreateTagBuilder(UTags.Items.COOLS_OFF_KIRINS)
.addOptional(new Identifier("farmersdelight", "melon_popsicle")) .addOptional(Identifier.of("farmersdelight", "melon_popsicle"))
.addOptional(new Identifier("farmersdelight", "melon_juice")); .addOptional(Identifier.of("farmersdelight", "melon_juice"));
getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight", "cabbage_roll_ingredients"))).add(UItems.OATS, UItems.ROCK, UItems.WHEAT_WORMS); getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, Identifier.of("farmersdelight", "cabbage_roll_ingredients"))).add(UItems.OATS, UItems.ROCK, UItems.WHEAT_WORMS);
getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight", "comfort_foods"))).add(UItems.OATMEAL, UItems.ROCK_STEW, UItems.MUFFIN); getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, Identifier.of("farmersdelight", "comfort_foods"))).add(UItems.OATMEAL, UItems.ROCK_STEW, UItems.MUFFIN);
getOrCreateTagBuilder(UConventionalTags.Items.RAW_FISH) getOrCreateTagBuilder(UConventionalTags.Items.RAW_FISH)
.addOptional(new Identifier("farmersdelight", "cod_roll")) .addOptional(Identifier.of("farmersdelight", "cod_roll"))
.addOptional(new Identifier("farmersdelight", "salmon_roll")) .addOptional(Identifier.of("farmersdelight", "salmon_roll"))
.addOptional(new Identifier("farmersdelight", "cod_slice")) .addOptional(Identifier.of("farmersdelight", "cod_slice"))
.addOptional(new Identifier("farmersdelight", "salmon_slice")); .addOptional(Identifier.of("farmersdelight", "salmon_slice"));
getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH) getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH)
.addOptional(new Identifier("farmersdelight", "fish_stew")) .addOptional(Identifier.of("farmersdelight", "fish_stew"))
.addOptional(new Identifier("farmersdelight", "baked_cod_stew")) .addOptional(Identifier.of("farmersdelight", "baked_cod_stew"))
.addOptional(new Identifier("farmersdelight", "grilled_salmon")); .addOptional(Identifier.of("farmersdelight", "grilled_salmon"));
getOrCreateTagBuilder(UConventionalTags.Items.RAW_MEAT) getOrCreateTagBuilder(UConventionalTags.Items.RAW_MEAT)
.addOptional(new Identifier("farmersdelight", "ham")); .addOptional(Identifier.of("farmersdelight", "ham"));
getOrCreateTagBuilder(UConventionalTags.Items.COOKED_MEAT) getOrCreateTagBuilder(UConventionalTags.Items.COOKED_MEAT)
.addOptional(new Identifier("farmersdelight", "chicken_soup")) .addOptional(Identifier.of("farmersdelight", "chicken_soup"))
.addOptional(new Identifier("farmersdelight", "bacon_and_eggs")) .addOptional(Identifier.of("farmersdelight", "bacon_and_eggs"))
.addOptional(new Identifier("farmersdelight", "pasta_with_meatballs")) .addOptional(Identifier.of("farmersdelight", "pasta_with_meatballs"))
.addOptional(new Identifier("farmersdelight", "beef_stew")) .addOptional(Identifier.of("farmersdelight", "beef_stew"))
.addOptional(new Identifier("farmersdelight", "bone_broth")) .addOptional(Identifier.of("farmersdelight", "bone_broth"))
.addOptional(new Identifier("farmersdelight", "mutton_wrap")) .addOptional(Identifier.of("farmersdelight", "mutton_wrap"))
.addOptional(new Identifier("farmersdelight", "bacon_sandwich")) .addOptional(Identifier.of("farmersdelight", "bacon_sandwich"))
.addOptional(new Identifier("farmersdelight", "hamburger")) .addOptional(Identifier.of("farmersdelight", "hamburger"))
.addOptional(new Identifier("farmersdelight", "chicken_sandwich")) .addOptional(Identifier.of("farmersdelight", "chicken_sandwich"))
.addOptional(new Identifier("farmersdelight", "barbecue_stick")) .addOptional(Identifier.of("farmersdelight", "barbecue_stick"))
.addOptional(new Identifier("farmersdelight", "smoked_ham")) .addOptional(Identifier.of("farmersdelight", "smoked_ham"))
.addOptional(new Identifier("farmersdelight", "honey_glazed_ham")) .addOptional(Identifier.of("farmersdelight", "honey_glazed_ham"))
.addOptional(new Identifier("farmersdelight", "honey_glazed_ham_block")) .addOptional(Identifier.of("farmersdelight", "honey_glazed_ham_block"))
.addOptional(new Identifier("farmersdelight", "roast_chicken")) .addOptional(Identifier.of("farmersdelight", "roast_chicken"))
.addOptional(new Identifier("farmersdelight", "roast_chicken_block")) .addOptional(Identifier.of("farmersdelight", "roast_chicken_block"))
.addOptional(new Identifier("farmersdelight", "steak_and_potatoes")) .addOptional(Identifier.of("farmersdelight", "steak_and_potatoes"))
.addOptional(new Identifier("farmersdelight", "roasted_mutton_chops")) .addOptional(Identifier.of("farmersdelight", "roasted_mutton_chops"))
.addOptional(new Identifier("farmersdelight", "pasta_with_mutton_chop")); .addOptional(Identifier.of("farmersdelight", "pasta_with_mutton_chop"));
getOrCreateTagBuilder(UConventionalTags.Items.FRUITS) getOrCreateTagBuilder(UConventionalTags.Items.FRUITS)
.addOptional(new Identifier("farmersdelight", "pumpkin_slice")) .addOptional(Identifier.of("farmersdelight", "pumpkin_slice"))
.addOptional(new Identifier("farmersdelight", "tomato")) .addOptional(Identifier.of("farmersdelight", "tomato"))
.addOptional(new Identifier("farmersdelight", "melon_juice")) .addOptional(Identifier.of("farmersdelight", "melon_juice"))
.addOptional(new Identifier("farmersdelight", "fruit_salad")); .addOptional(Identifier.of("farmersdelight", "fruit_salad"));
getOrCreateTagBuilder(UConventionalTags.Items.DESSERTS) getOrCreateTagBuilder(UConventionalTags.Items.DESSERTS)
.addOptional(new Identifier("farmersdelight", "sweet_berry_cheesecake")) .addOptional(Identifier.of("farmersdelight", "sweet_berry_cheesecake"))
.addOptional(new Identifier("farmersdelight", "sweet_berry_cheesecake_slice")) .addOptional(Identifier.of("farmersdelight", "sweet_berry_cheesecake_slice"))
.addOptional(new Identifier("farmersdelight", "chocolate_pie_slice")) .addOptional(Identifier.of("farmersdelight", "chocolate_pie_slice"))
.addOptional(new Identifier("farmersdelight", "cake_slice")) .addOptional(Identifier.of("farmersdelight", "cake_slice"))
.addOptional(new Identifier("farmersdelight", "apple_pie_slice")) .addOptional(Identifier.of("farmersdelight", "apple_pie_slice"))
.addOptional(new Identifier("farmersdelight", "glow_berry_custard")); .addOptional(Identifier.of("farmersdelight", "glow_berry_custard"));
getOrCreateTagBuilder(UConventionalTags.Items.COOKIES) getOrCreateTagBuilder(UConventionalTags.Items.COOKIES)
.addOptional(new Identifier("farmersdelight", "sweet_berry_cookie")) .addOptional(Identifier.of("farmersdelight", "sweet_berry_cookie"))
.addOptional(new Identifier("farmersdelight", "honey_cookie")); .addOptional(Identifier.of("farmersdelight", "honey_cookie"));
getOrCreateTagBuilder(UTags.Items.BAKED_GOODS) getOrCreateTagBuilder(UTags.Items.BAKED_GOODS)
.addOptional(new Identifier("farmersdelight", "wheat_dough")) .addOptional(Identifier.of("farmersdelight", "wheat_dough"))
.addOptional(new Identifier("farmersdelight", "raw_pasta")) .addOptional(Identifier.of("farmersdelight", "raw_pasta"))
.addOptional(new Identifier("farmersdelight", "pie_crust")) .addOptional(Identifier.of("farmersdelight", "pie_crust"))
.addOptional(new Identifier("farmersdelight", "egg_sandwich")); .addOptional(Identifier.of("farmersdelight", "egg_sandwich"));
getOrCreateTagBuilder(UTags.Items.HIGH_QUALITY_SEA_VEGETABLES) getOrCreateTagBuilder(UTags.Items.HIGH_QUALITY_SEA_VEGETABLES)
.addOptional(new Identifier("farmersdelight", "kelp_roll")); .addOptional(Identifier.of("farmersdelight", "kelp_roll"));
getOrCreateTagBuilder(UTags.Items.LOW_QUALITY_SEA_VEGETABLES) getOrCreateTagBuilder(UTags.Items.LOW_QUALITY_SEA_VEGETABLES)
.addOptional(new Identifier("farmersdelight", "kelp_roll_slice")); .addOptional(Identifier.of("farmersdelight", "kelp_roll_slice"));
getOrCreateTagBuilder(UTags.Items.FORAGE_FILLING) getOrCreateTagBuilder(UTags.Items.FORAGE_FILLING)
.addOptional(new Identifier("farmersdelight", "horse_feed")) .addOptional(Identifier.of("farmersdelight", "horse_feed"))
.addOptional(new Identifier("farmersdelight", "rice_bale")) .addOptional(Identifier.of("farmersdelight", "rice_bale"))
.addOptional(new Identifier("farmersdelight", "straw_bale")); .addOptional(Identifier.of("farmersdelight", "straw_bale"));
getOrCreateTagBuilder(UTags.Items.FORAGE_SAFE) getOrCreateTagBuilder(UTags.Items.FORAGE_SAFE)
.addOptional(new Identifier("farmersdelight", "sandy_shrub")) .addOptional(Identifier.of("farmersdelight", "sandy_shrub"))
.addOptional(new Identifier("farmersdelight", "wild_cabbages")) .addOptional(Identifier.of("farmersdelight", "wild_cabbages"))
.addOptional(new Identifier("farmersdelight", "wild_onions")) .addOptional(Identifier.of("farmersdelight", "wild_onions"))
.addOptional(new Identifier("farmersdelight", "wild_carrots")) .addOptional(Identifier.of("farmersdelight", "wild_carrots"))
.addOptional(new Identifier("farmersdelight", "wild_beetroots")) .addOptional(Identifier.of("farmersdelight", "wild_beetroots"))
.addOptional(new Identifier("farmersdelight", "wild_rice")); .addOptional(Identifier.of("farmersdelight", "wild_rice"));
getOrCreateTagBuilder(UTags.Items.FORAGE_RISKY) getOrCreateTagBuilder(UTags.Items.FORAGE_RISKY)
.addOptional(new Identifier("farmersdelight", "wild_tomatoes")) .addOptional(Identifier.of("farmersdelight", "wild_tomatoes"))
.addOptional(new Identifier("farmersdelight", "wild_potatoes")) .addOptional(Identifier.of("farmersdelight", "wild_potatoes"))
.addOptionalTag(new Identifier("c", "meads")); .addOptionalTag(Identifier.of("c", "meads"));
} }
} }

View file

@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.datagen.providers.tag;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import com.minelittlepony.unicopia.entity.mob.UEntities; import com.minelittlepony.unicopia.datagen.providers.UPaintingVariantProvider;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
@ -12,12 +12,16 @@ import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.tag.PaintingVariantTags; import net.minecraft.registry.tag.PaintingVariantTags;
public class UPaintingVariantTagProvider extends FabricTagProvider<PaintingVariant> { public class UPaintingVariantTagProvider extends FabricTagProvider<PaintingVariant> {
public UPaintingVariantTagProvider(FabricDataOutput output, CompletableFuture<WrapperLookup> registriesFuture) {
private final UPaintingVariantProvider provider;
public UPaintingVariantTagProvider(FabricDataOutput output, CompletableFuture<WrapperLookup> registriesFuture, UPaintingVariantProvider provider) {
super(output, RegistryKeys.PAINTING_VARIANT, registriesFuture); super(output, RegistryKeys.PAINTING_VARIANT, registriesFuture);
this.provider = provider;
} }
@Override @Override
protected void configure(WrapperLookup lookup) { protected void configure(WrapperLookup lookup) {
getOrCreateTagBuilder(PaintingVariantTags.PLACEABLE).add(UEntities.Paintings.REGISTRY.toArray(PaintingVariant[]::new)); getOrCreateTagBuilder(PaintingVariantTags.PLACEABLE).add(provider.getKeys());
} }
} }

View file

@ -17,6 +17,8 @@ public class UStatusEffectTagProvider extends FabricTagProvider<StatusEffect> {
@Override @Override
protected void configure(WrapperLookup lookup) { protected void configure(WrapperLookup lookup) {
getOrCreateTagBuilder(UTags.StatusEffects.PINEAPPLE_EFFECTS).add(StatusEffects.REGENERATION, StatusEffects.ABSORPTION, StatusEffects.LUCK, StatusEffects.HASTE); getOrCreateTagBuilder(UTags.StatusEffects.PINEAPPLE_EFFECTS).add(
StatusEffects.REGENERATION.value(), StatusEffects.ABSORPTION.value(), StatusEffects.LUCK.value(), StatusEffects.HASTE.value()
);
} }
} }

View file

@ -1,22 +1,17 @@
package com.minelittlepony.unicopia.diet; package com.minelittlepony.unicopia.diet;
import com.minelittlepony.unicopia.diet.affliction.Affliction; import com.minelittlepony.unicopia.diet.affliction.Affliction;
import com.minelittlepony.unicopia.diet.affliction.EmptyAffliction;
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.network.PacketByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
public record Ailment(Affliction effects) { public record Ailment(Affliction effects) {
public static final Ailment EMPTY = new Ailment(Affliction.EMPTY); public static final Ailment EMPTY = new Ailment(EmptyAffliction.INSTANCE);
public static final Codec<Ailment> CODEC = RecordCodecBuilder.create(instance -> instance.group( public static final Codec<Ailment> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Affliction.CODEC.fieldOf("effects").forGetter(Ailment::effects) Affliction.CODEC.fieldOf("effects").forGetter(Ailment::effects)
).apply(instance, Ailment::new)); ).apply(instance, Ailment::new));
public static final PacketCodec<RegistryByteBuf, Ailment> PACKET_CODEC = Affliction.PACKET_CODEC.xmap(Ailment::new, Ailment::effects);
public Ailment(PacketByteBuf buffer) {
this(Affliction.read(buffer));
}
public void toBuffer(PacketByteBuf buffer) {
Affliction.write(buffer, effects);
}
} }

View file

@ -16,11 +16,14 @@ 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.client.item.TooltipContext; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.FoodComponent;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -38,17 +41,17 @@ public record DietProfile(
Codec.FLOAT.fieldOf("default_multiplier").forGetter(DietProfile::defaultMultiplier), Codec.FLOAT.fieldOf("default_multiplier").forGetter(DietProfile::defaultMultiplier),
Codec.FLOAT.fieldOf("foraging_multiplier").forGetter(DietProfile::foragingMultiplier), Codec.FLOAT.fieldOf("foraging_multiplier").forGetter(DietProfile::foragingMultiplier),
Codec.list(Multiplier.CODEC).fieldOf("multipliers").forGetter(DietProfile::multipliers), Codec.list(Multiplier.CODEC).fieldOf("multipliers").forGetter(DietProfile::multipliers),
Codec.list(FoodGroupEffects.CODEC).fieldOf("effects").forGetter(DietProfile::effects), Codec.list(FoodGroupEffects.createCodec(FoodGroupKey.CODEC)).fieldOf("effects").forGetter(DietProfile::effects),
FoodGroupEffects.CODEC.optionalFieldOf("default_effect").forGetter(DietProfile::defaultEffect) FoodGroupEffects.createCodec(FoodGroupKey.CODEC).optionalFieldOf("default_effect").forGetter(DietProfile::defaultEffect)
).apply(instance, DietProfile::new)); ).apply(instance, DietProfile::new));
public static final PacketCodec<RegistryByteBuf, DietProfile> PACKET_CODEC = PacketCodec.tuple(
public DietProfile(PacketByteBuf buffer) { PacketCodecs.FLOAT, DietProfile::defaultMultiplier,
this(buffer.readFloat(), buffer.readFloat(), PacketCodecs.FLOAT, DietProfile::foragingMultiplier,
buffer.readList(Multiplier::new), Multiplier.PACKET_CODEC.collect(PacketCodecs.toList()), DietProfile::multipliers,
buffer.readList(b -> new FoodGroupEffects(b, FoodGroupKey.LOOKUP)), FoodGroupEffects.createPacketCodec(FoodGroupKey.PACKET_CODEC).collect(PacketCodecs.toList()), DietProfile::effects,
buffer.readOptional(b -> new FoodGroupEffects(b, FoodGroupKey.LOOKUP)) PacketCodecs.optional(FoodGroupEffects.createPacketCodec(FoodGroupKey.PACKET_CODEC)), DietProfile::defaultEffect,
DietProfile::new
); );
}
public void validate(Consumer<String> issues, Predicate<Identifier> foodGroupExists) { public void validate(Consumer<String> issues, Predicate<Identifier> foodGroupExists) {
multipliers.stream().flatMap(i -> i.tags().stream()).forEach(key -> { multipliers.stream().flatMap(i -> i.tags().stream()).forEach(key -> {
@ -68,14 +71,6 @@ public record DietProfile(
}); });
} }
public void toBuffer(PacketByteBuf buffer) {
buffer.writeFloat(defaultMultiplier);
buffer.writeFloat(foragingMultiplier);
buffer.writeCollection(multipliers, (b, t) -> t.toBuffer(b));
buffer.writeCollection(effects, (b, t) -> t.toBuffer(b));
buffer.writeOptional(defaultEffect, (b, t) -> t.toBuffer(b));
}
public Optional<Multiplier> findMultiplier(ItemStack stack) { public Optional<Multiplier> findMultiplier(ItemStack stack) {
return multipliers.stream().filter(m -> m.test(stack)).findFirst(); return multipliers.stream().filter(m -> m.test(stack)).findFirst();
} }
@ -90,7 +85,7 @@ public record DietProfile(
@Nullable @Nullable
public FoodComponent getAdjustedFoodComponent(ItemStack stack) { public FoodComponent getAdjustedFoodComponent(ItemStack stack) {
var food = stack.getItem().getFoodComponent(); var food = stack.get(DataComponentTypes.FOOD);
if (this == EMPTY) { if (this == EMPTY) {
return food; return food;
} }
@ -100,13 +95,17 @@ public record DietProfile(
return null; return null;
} }
float hunger = food.getHunger() * ratios.getFirst(); float hunger = food.nutrition() * ratios.getFirst();
int baseline = (int)hunger; int baseline = (int)hunger;
return FoodAttributes.copy(food) return new FoodComponent(
.hunger(Math.max(1, (hunger - baseline) >= 0.5F ? baseline + 1 : baseline)) Math.max(1, (hunger - baseline) >= 0.5F ? baseline + 1 : baseline),
.saturationModifier(food.getSaturationModifier() * ratios.getSecond()) food.saturation() * ratios.getSecond(),
.build(); food.canAlwaysEat(),
food.eatSeconds(),
food.usingConvertsTo(),
food.effects()
);
} }
public boolean isInedible(ItemStack stack) { public boolean isInedible(ItemStack stack) {
@ -126,8 +125,8 @@ public record DietProfile(
return Pair.of(hungerMultiplier, saturationMultiplier); return Pair.of(hungerMultiplier, saturationMultiplier);
} }
public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> tooltip, TooltipContext context) { public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> tooltip, TooltipType context) {
var food = stack.getItem().getFoodComponent(); var food = stack.get(DataComponentTypes.FOOD);
var ratios = getRatios(stack); var ratios = getRatios(stack);
if (food == null || isInedible(ratios)) { if (food == null || isInedible(ratios)) {
@ -142,8 +141,8 @@ public record DietProfile(
if (context.isAdvanced()) { if (context.isAdvanced()) {
var nonAdjustedFood = getNonAdjustedFoodComponent(stack, user).orElse(food); var nonAdjustedFood = getNonAdjustedFoodComponent(stack, user).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.getHunger(), nonAdjustedFood.getHunger(), (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.getSaturationModifier(), nonAdjustedFood.getSaturationModifier(), (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));
} else { } else {
tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.hunger", (int)(ratios.getFirst() * 100))).formatted(Formatting.DARK_GRAY)); tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.hunger", (int)(ratios.getFirst() * 100))).formatted(Formatting.DARK_GRAY));
tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.saturation", (int)(ratios.getSecond() * 100))).formatted(Formatting.DARK_GRAY)); tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.saturation", (int)(ratios.getSecond() * 100))).formatted(Formatting.DARK_GRAY));
@ -178,22 +177,18 @@ public record DietProfile(
Codec.FLOAT.fieldOf("hunger").forGetter(Multiplier::hunger), Codec.FLOAT.fieldOf("hunger").forGetter(Multiplier::hunger),
Codec.FLOAT.fieldOf("saturation").forGetter(Multiplier::saturation) Codec.FLOAT.fieldOf("saturation").forGetter(Multiplier::saturation)
).apply(instance, Multiplier::new)); ).apply(instance, Multiplier::new));
public static final PacketCodec<RegistryByteBuf, Multiplier> PACKET_CODEC = PacketCodec.tuple(
public Multiplier(PacketByteBuf buffer) { FoodGroupKey.PACKET_CODEC.collect(PacketCodecs.toCollection(HashSet::new)), Multiplier::tags,
this(buffer.readCollection(HashSet::new, p -> FoodGroupKey.LOOKUP.apply(p.readIdentifier())), buffer.readFloat(), buffer.readFloat()); PacketCodecs.FLOAT, Multiplier::hunger,
} PacketCodecs.FLOAT, Multiplier::saturation,
Multiplier::new
);
@Override @Override
public boolean test(ItemStack stack) { public boolean test(ItemStack stack) {
return tags.stream().anyMatch(tag -> tag.contains(stack)); return tags.stream().anyMatch(tag -> tag.contains(stack));
} }
public void toBuffer(PacketByteBuf buffer) {
buffer.writeCollection(tags, (p, t) -> p.writeIdentifier(t.id()));
buffer.writeFloat(hunger);
buffer.writeFloat(saturation);
}
public static final class Builder { public static final class Builder {
private Set<FoodGroupKey> tags = new HashSet<>(); private Set<FoodGroupKey> tags = new HashSet<>();
private float hunger = 1; private float hunger = 1;

View file

@ -3,10 +3,10 @@ package com.minelittlepony.unicopia.diet;
import java.util.List; import java.util.List;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import net.minecraft.client.item.TooltipContext;
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.text.Text;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.TypedActionResult;
@ -17,7 +17,7 @@ public interface DietView {
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, TooltipContext context); void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> tooltip, TooltipType context);
interface Holder { interface Holder {
default DietView getDiets(ItemStack stack) { default DietView getDiets(ItemStack stack) {

View file

@ -33,11 +33,11 @@ public class DietsLoader implements IdentifiableResourceReloadListener {
Profiler prepareProfiler, Profiler applyProfiler, Profiler prepareProfiler, Profiler applyProfiler,
Executor prepareExecutor, Executor applyExecutor) { Executor prepareExecutor, Executor applyExecutor) {
CompletableFuture<Map<Identifier, Effect>> foodGroupsFuture = CompletableFuture.supplyAsync(() -> { CompletableFuture<Map<Identifier, FoodGroup>> foodGroupsFuture = CompletableFuture.supplyAsync(() -> {
Map<Identifier, Effect> foodGroups = new HashMap<>(); Map<Identifier, FoodGroup> foodGroups = new HashMap<>();
for (var group : loadData(manager, prepareExecutor, "diet/food_groups").entrySet()) { for (var group : loadData(manager, prepareExecutor, "diet/food_groups").entrySet()) {
try { try {
FoodGroup.CODEC.parse(JsonOps.INSTANCE, group.getValue()) FoodGroup.EFFECTS_CODEC.parse(JsonOps.INSTANCE, group.getValue())
.resultOrPartial(error -> LOGGER.error("Could not load food group {}: {}", group.getKey(), error)) .resultOrPartial(error -> LOGGER.error("Could not load food group {}: {}", group.getKey(), error))
.ifPresent(value -> { .ifPresent(value -> {
foodGroups.put(group.getKey(), new FoodGroup(group.getKey(), value)); foodGroups.put(group.getKey(), new FoodGroup(group.getKey(), value));

View file

@ -4,10 +4,10 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
import net.minecraft.client.item.TooltipContext; import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.FoodComponent; import net.minecraft.component.type.FoodComponent;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.UseAction; import net.minecraft.util.UseAction;
@ -21,16 +21,16 @@ public interface Effect extends Predicate<ItemStack> {
Ailment ailment(); Ailment ailment();
default void appendTooltip(ItemStack stack, List<Text> tooltip, TooltipContext context) { default void appendTooltip(ItemStack stack, List<Text> tooltip, TooltipType context) {
if (!test(stack)) { if (!test(stack)) {
if (stack.isFood()) { if (stack.contains(DataComponentTypes.FOOD)) {
tooltip.add(Text.literal(" ").append(Text.translatable("food_group.unicopia.misc")).formatted(Formatting.GRAY)); tooltip.add(Text.literal(" ").append(Text.translatable("food_group.unicopia.misc")).formatted(Formatting.GRAY));
} else if (stack.getUseAction() == UseAction.DRINK) { } else if (stack.getUseAction() == UseAction.DRINK) {
tooltip.add(Text.literal(" ").append(Text.translatable("food_group.unicopia.drinks")).formatted(Formatting.GRAY)); tooltip.add(Text.literal(" ").append(Text.translatable("food_group.unicopia.drinks")).formatted(Formatting.GRAY));
} }
} }
if (context.isAdvanced() && stack.isFood()) { if (context.isAdvanced() && stack.contains(DataComponentTypes.FOOD)) {
if (!ailment().effects().isEmpty()) { if (!ailment().effects().isEmpty()) {
tooltip.add(Text.translatable("unicopia.diet.side_effects").formatted(Formatting.DARK_PURPLE)); tooltip.add(Text.translatable("unicopia.diet.side_effects").formatted(Formatting.DARK_PURPLE));
ailment().effects().appendTooltip(tooltip); ailment().effects().appendTooltip(tooltip);
@ -38,12 +38,6 @@ public interface Effect extends Predicate<ItemStack> {
} }
} }
default void toBuffer(PacketByteBuf buffer) {
buffer.writeCollection(tags(), (b, t) -> b.writeIdentifier(t.id()));
buffer.writeOptional(foodComponent(), FoodAttributes::write);
ailment().toBuffer(buffer);
}
@Override @Override
default boolean test(ItemStack stack) { default boolean test(ItemStack stack) {
return tags().stream().anyMatch(tag -> tag.contains(stack)); return tags().stream().anyMatch(tag -> tag.contains(stack));

View file

@ -7,6 +7,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.component.type.FoodComponent; import net.minecraft.component.type.FoodComponent;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.RegistryByteBuf;
final class FoodAttributes { final class FoodAttributes {
@ -21,12 +22,12 @@ final class FoodAttributes {
})); }));
@Deprecated @Deprecated
static FoodComponent read(RegistryByteBuf buffer) { static FoodComponent read(PacketByteBuf buffer) {
return FoodComponent.PACKET_CODEC.decode(buffer); return FoodComponent.PACKET_CODEC.decode((RegistryByteBuf)buffer);
} }
@Deprecated @Deprecated
static void write(RegistryByteBuf buffer, FoodComponent food) { static void write(PacketByteBuf buffer, FoodComponent food) {
FoodComponent.PACKET_CODEC.encode(buffer, food); FoodComponent.PACKET_CODEC.encode((RegistryByteBuf)buffer, food);
} }
} }

View file

@ -4,12 +4,11 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.component.type.FoodComponent;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -18,15 +17,12 @@ import net.minecraft.util.Util;
public record FoodGroup( public record FoodGroup(
Identifier id, Identifier id,
FoodGroupEffects attributes) implements Effect { FoodGroupEffects attributes) implements Effect {
public static final Codec<FoodGroupEffects> CODEC = RecordCodecBuilder.create(instance -> instance.group( public static final Codec<FoodGroupEffects> EFFECTS_CODEC = FoodGroupEffects.createCodec(FoodGroupKey.TAG_CODEC);
FoodGroupKey.TAG_CODEC.listOf().fieldOf("tags").forGetter(FoodGroupEffects::tags), public static final PacketCodec<RegistryByteBuf, FoodGroup> PACKET_CODEC = PacketCodec.tuple(
FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(FoodGroupEffects::foodComponent), Identifier.PACKET_CODEC, FoodGroup::id,
Ailment.CODEC.fieldOf("ailment").forGetter(FoodGroupEffects::ailment) FoodGroupEffects.createPacketCodec(FoodGroupKey.TAG_PACKET_CODEC), FoodGroup::attributes,
).apply(instance, FoodGroupEffects::new)); FoodGroup::new
);
public FoodGroup(PacketByteBuf buffer) {
this(buffer.readIdentifier(), new FoodGroupEffects(buffer, FoodGroupKey.TAG_ID_LOOKUP));
}
@Override @Override
public List<FoodGroupKey> tags() { public List<FoodGroupKey> tags() {
@ -43,14 +39,8 @@ public record FoodGroup(
return attributes.ailment(); return attributes.ailment();
} }
@Override @Override
public void appendTooltip(ItemStack stack, List<Text> tooltip, TooltipContext context) { public void appendTooltip(ItemStack stack, List<Text> tooltip, TooltipType context) {
tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("food_group", id()))).formatted(Formatting.GRAY)); tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("food_group", id()))).formatted(Formatting.GRAY));
Effect.super.appendTooltip(stack, tooltip, context); Effect.super.appendTooltip(stack, tooltip, context);
} }
@Override
public void toBuffer(PacketByteBuf buffer) {
buffer.writeIdentifier(id());
Effect.super.toBuffer(buffer);
}
} }

View file

@ -3,17 +3,19 @@ package com.minelittlepony.unicopia.diet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import com.minelittlepony.unicopia.diet.affliction.Affliction; import com.minelittlepony.unicopia.diet.affliction.Affliction;
import com.minelittlepony.unicopia.item.UFoodComponents; import com.minelittlepony.unicopia.item.UFoodComponents;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.netty.buffer.ByteBuf;
import net.minecraft.component.type.FoodComponent; import net.minecraft.component.type.FoodComponent;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf; import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.TagKey; import net.minecraft.registry.tag.TagKey;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@ -26,18 +28,24 @@ public record FoodGroupEffects(
Optional<FoodComponent> foodComponent, Optional<FoodComponent> foodComponent,
Ailment ailment Ailment ailment
) implements Effect { ) implements Effect {
public static final Codec<FoodGroupEffects> CODEC = RecordCodecBuilder.create(instance -> instance.group( public static Codec<FoodGroupEffects> createCodec(Codec<FoodGroupKey> keyCodec) {
FoodGroupKey.CODEC.listOf().fieldOf("tags").forGetter(FoodGroupEffects::tags), return RecordCodecBuilder.create(instance -> instance.group(
keyCodec.listOf().fieldOf("tags").forGetter(FoodGroupEffects::tags),
FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(FoodGroupEffects::foodComponent), FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(FoodGroupEffects::foodComponent),
Ailment.CODEC.fieldOf("ailment").forGetter(FoodGroupEffects::ailment) Ailment.CODEC.fieldOf("ailment").forGetter(FoodGroupEffects::ailment)
).apply(instance, FoodGroupEffects::new)); ).apply(instance, FoodGroupEffects::new));
}
public FoodGroupEffects(PacketByteBuf buffer, Function<Identifier, FoodGroupKey> lookup) { public static final PacketCodec<RegistryByteBuf, FoodGroupEffects> createPacketCodec(PacketCodec<ByteBuf, FoodGroupKey> keyCodec) {
this(buffer.readList(b -> lookup.apply(b.readIdentifier())), buffer.readOptional(FoodAttributes::read), new Ailment(buffer)); return PacketCodec.tuple(
keyCodec.collect(PacketCodecs.toList()), FoodGroupEffects::tags,
PacketCodecs.optional(FoodComponent.PACKET_CODEC), FoodGroupEffects::foodComponent,
Ailment.PACKET_CODEC, FoodGroupEffects::ailment,
FoodGroupEffects::new
);
} }
@Override @Override
public void appendTooltip(ItemStack stack, List<Text> tooltip, TooltipContext context) { public void appendTooltip(ItemStack stack, List<Text> tooltip, TooltipType context) {
tags.forEach(tag -> { tags.forEach(tag -> {
if (tag.contains(stack)) { if (tag.contains(stack)) {
tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("tag", tag.id()))).formatted(Formatting.GRAY)); tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("tag", tag.id()))).formatted(Formatting.GRAY));
@ -49,7 +57,7 @@ public record FoodGroupEffects(
public static final class Builder { public static final class Builder {
private final List<FoodGroupKey> tags = new ArrayList<>(); private final List<FoodGroupKey> tags = new ArrayList<>();
private Optional<FoodComponent> foodComponent = Optional.empty(); private Optional<FoodComponent> foodComponent = Optional.empty();
private Ailment ailment = new Ailment(Affliction.EMPTY); private Ailment ailment = Ailment.EMPTY;
public Builder tag(Identifier tag) { public Builder tag(Identifier tag) {
return tag(TagKey.of(RegistryKeys.ITEM, tag)); return tag(TagKey.of(RegistryKeys.ITEM, tag));

View file

@ -6,8 +6,10 @@ import com.minelittlepony.unicopia.Debug;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.TagKey; import net.minecraft.registry.tag.TagKey;
@ -71,9 +73,13 @@ public interface FoodGroupKey {
}; };
}); });
Function<Identifier, FoodGroupKey> TAG_ID_LOOKUP = id -> TAG_LOOKUP.apply(TagKey.of(RegistryKeys.ITEM, id)); Function<Identifier, FoodGroupKey> TAG_ID_LOOKUP = id -> TAG_LOOKUP.apply(TagKey.of(RegistryKeys.ITEM, id));
Codec<FoodGroupKey> CODEC = Identifier.CODEC.xmap(LOOKUP, FoodGroupKey::id); Codec<FoodGroupKey> CODEC = Identifier.CODEC.xmap(LOOKUP, FoodGroupKey::id);
Codec<FoodGroupKey> TAG_CODEC = TagKey.unprefixedCodec(RegistryKeys.ITEM).xmap(TAG_LOOKUP, k -> TagKey.of(RegistryKeys.ITEM, k.id())); Codec<FoodGroupKey> TAG_CODEC = TagKey.unprefixedCodec(RegistryKeys.ITEM).xmap(TAG_LOOKUP, k -> TagKey.of(RegistryKeys.ITEM, k.id()));
PacketCodec<ByteBuf, FoodGroupKey> PACKET_CODEC = Identifier.PACKET_CODEC.xmap(LOOKUP, FoodGroupKey::id);
PacketCodec<ByteBuf, FoodGroupKey> TAG_PACKET_CODEC = Identifier.PACKET_CODEC.xmap(id -> TAG_LOOKUP.apply(TagKey.of(RegistryKeys.ITEM, id)), FoodGroupKey::id);
Identifier id(); Identifier id();
boolean contains(ItemStack stack); boolean contains(ItemStack stack);

View file

@ -1,23 +1,25 @@
package com.minelittlepony.unicopia.diet; package com.minelittlepony.unicopia.diet;
import java.util.ArrayList; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable; 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.item.ItemDuck;
import net.minecraft.client.item.TooltipContext; 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.network.PacketByteBuf; import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
@ -27,11 +29,28 @@ import net.minecraft.world.World;
public class PonyDiets implements DietView { public class PonyDiets implements DietView {
private final Map<Race, DietProfile> diets; private final Map<Race, DietProfile> diets;
private final Map<Identifier, Effect> effects; private final Map<Identifier, FoodGroup> effects;
private static PonyDiets INSTANCE = new PonyDiets(Map.of(), Map.of()); private static PonyDiets INSTANCE = new PonyDiets(Map.of(), Map.of());
public static final PacketCodec<RegistryByteBuf, PonyDiets> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.map(HashMap::new, PacketCodecs.registryValue(Race.REGISTRY_KEY), DietProfile.PACKET_CODEC), diets -> diets.diets,
FoodGroup.PACKET_CODEC.collect(PacketCodecUtils.toMap(FoodGroup::id)), diets -> diets.effects,
PonyDiets::new
);
/*public static final PacketCodec<RegistryByteBuf, PonyDiets> PACKET_CODEC = PacketCodec.ofStatic((buffer, diets) -> {
buffer.writeMap(diets.diets, (b, r) -> b.writeRegistryKey(Race.REGISTRY.getKey(r).get()), (b, e) -> e.toBuffer(b));
buffer.writeCollection(diets.effects.values(), (b, e) -> e.toBuffer(b));
}, buffer -> {
return new PonyDiets(
buffer.readMap(b -> Race.REGISTRY.get(b.readRegistryKey(Race.REGISTRY_KEY)), DietProfile::new),
FoodGroup.PACKET_CODEC.collect(PacketCodecUtils.toMap(FoodGroup::id)).decode(buffer)
);
});*/
public static PonyDiets getInstance() { public static PonyDiets getInstance() {
return INSTANCE; return INSTANCE;
} }
@ -44,29 +63,17 @@ public class PonyDiets implements DietView {
INSTANCE = diets; INSTANCE = diets;
} }
PonyDiets(Map<Race, DietProfile> diets, Map<Identifier, Effect> effects) { PonyDiets(Map<Race, DietProfile> diets, Map<Identifier, FoodGroup> effects) {
this.diets = diets; this.diets = diets;
this.effects = effects; this.effects = effects;
} }
public PonyDiets(PacketByteBuf buffer) {
this(
buffer.readMap(b -> b.readRegistryValue(Race.REGISTRY), DietProfile::new),
buffer.readCollection(ArrayList::new, FoodGroup::new).stream().collect(Collectors.toMap(FoodGroup::id, Function.identity()))
);
}
public void toBuffer(PacketByteBuf buffer) {
buffer.writeMap(diets, (b, r) -> b.writeRegistryValue(Race.REGISTRY, r), (b, e) -> e.toBuffer(b));
buffer.writeCollection(effects.values(), (b, e) -> e.toBuffer(b));
}
private DietProfile getDiet(Pony pony) { private 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) { Effect getEffects(ItemStack stack) {
return effects.values().stream().filter(effect -> effect.test(stack)).findFirst().orElse(Effect.EMPTY); return effects.values().stream().filter(effect -> effect.test(stack)).findFirst().map(Effect.class::cast).orElse(Effect.EMPTY);
} }
private Effect getEffects(ItemStack stack, Pony pony) { private Effect getEffects(ItemStack stack, Pony pony) {
@ -88,10 +95,10 @@ public class PonyDiets implements DietView {
} }
@Override @Override
public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> tooltip, TooltipContext context) { public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List<Text> tooltip, TooltipType context) {
if (initEdibility(stack, user)) { if (initEdibility(stack, user)) {
if (!((ItemDuck)stack.getItem()).getOriginalFoodComponent().isEmpty() || stack.getItem().getFoodComponent() != null) { if (!((ItemDuck)stack.getItem()).getOriginalFoodComponent().isEmpty() || stack.contains(DataComponentTypes.FOOD)) {
Pony pony = Pony.of(user); Pony pony = Pony.of(user);
tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE)); tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE));
@ -107,14 +114,14 @@ public class PonyDiets implements DietView {
return Pony.of(user).filter(pony -> { return Pony.of(user).filter(pony -> {
DietProfile diet = getDiet(pony); DietProfile diet = getDiet(pony);
if (!stack.isFood() && pony.getObservedSpecies().hasIronGut()) { if (!stack.contains(DataComponentTypes.FOOD) && pony.getObservedSpecies().hasIronGut()) {
diet.findEffect(stack) diet.findEffect(stack)
.flatMap(Effect::foodComponent) .flatMap(Effect::foodComponent)
.or(() -> getEffects(stack).foodComponent()) .or(() -> getEffects(stack).foodComponent())
.ifPresent(item::setFoodComponent); .ifPresent(item::setFoodComponent);
} }
if (stack.isFood()) { if (stack.contains(DataComponentTypes.FOOD)) {
item.setFoodComponent(diet.getAdjustedFoodComponent(stack)); item.setFoodComponent(diet.getAdjustedFoodComponent(stack));
} }

View file

@ -7,38 +7,28 @@ import com.mojang.serialization.Codec;
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.network.PacketByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.dynamic.Codecs;
public interface Affliction { public interface Affliction {
Affliction EMPTY = new Affliction() { Codec<Affliction> SINGLE_CODEC = AfflictionType.CODEC.dispatch("type", affliction -> affliction.getType(), type -> type.codec());
@Override Codec<Affliction> CODEC = Codec.xor(SINGLE_CODEC, Codec.list(SINGLE_CODEC).xmap(
public void afflict(PlayerEntity player, ItemStack stack) { }
@Override
public AfflictionType<?> getType() {
return AfflictionType.EMPTY;
}
@Override
public void toBuffer(PacketByteBuf buffer) { }
};
Codec<Affliction> CODEC = Codecs.xor(AfflictionType.CODEC, Codec.list(AfflictionType.CODEC).xmap(
afflictions -> { afflictions -> {
afflictions = afflictions.stream().filter(f -> !f.isEmpty()).toList(); afflictions = afflictions.stream().filter(f -> !f.isEmpty()).toList();
return switch (afflictions.size()) { return switch (afflictions.size()) {
case 0 -> EMPTY; case 0 -> EmptyAffliction.INSTANCE;
case 1 -> afflictions.get(0); case 1 -> afflictions.get(0);
default -> new CompoundAffliction(afflictions); default -> new CompoundAffliction(afflictions);
}; };
}, },
affliction -> ((CompoundAffliction)affliction).afflictions affliction -> ((CompoundAffliction)affliction).afflictions()
)).xmap( )).xmap(
either -> either.left().or(either::right).get(), either -> either.left().or(either::right).get(),
affliction -> affliction instanceof CompoundAffliction ? Either.right(affliction) : Either.left(affliction) affliction -> affliction instanceof CompoundAffliction ? Either.right(affliction) : Either.left(affliction)
); );
PacketCodec<RegistryByteBuf, Affliction> PACKET_CODEC = AfflictionType.PACKET_CODEC.dispatch(Affliction::getType, AfflictionType::packetCodec);
void afflict(PlayerEntity player, ItemStack stack); void afflict(PlayerEntity player, ItemStack stack);
@ -55,15 +45,4 @@ public interface Affliction {
} }
AfflictionType<?> getType(); AfflictionType<?> getType();
void toBuffer(PacketByteBuf buffer);
static void write(PacketByteBuf buffer, Affliction affliction) {
buffer.writeIdentifier(affliction.getType().id());
affliction.toBuffer(buffer);
}
static Affliction read(PacketByteBuf buffer) {
return AfflictionType.REGISTRY.get(buffer.readIdentifier()).reader().apply(buffer);
}
} }

View file

@ -3,45 +3,30 @@ package com.minelittlepony.unicopia.diet.affliction;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.util.RegistryUtils; import com.minelittlepony.unicopia.util.RegistryUtils;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult; import com.mojang.serialization.MapCodec;
import com.mojang.serialization.JsonOps;
import net.minecraft.network.PacketByteBuf.PacketReader; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.util.dynamic.Codecs;
public record AfflictionType<T extends Affliction>(Codec<T> codec, Identifier id, PacketReader<T> reader) { public record AfflictionType<T extends Affliction>(Identifier id, MapCodec<T> codec, PacketCodec<? super RegistryByteBuf, T> packetCodec) {
public static final String DEFAULT_ID = "unicopia:apply_status_effect"; public static final String DEFAULT_ID = "unicopia:apply_status_effect";
public static final Registry<AfflictionType<?>> REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("affliction_type"), DEFAULT_ID); public static final Registry<AfflictionType<?>> REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("affliction_type"), DEFAULT_ID);
@SuppressWarnings("unchecked") public static final Codec<AfflictionType<?>> CODEC = REGISTRY.getCodec();
public static final Codec<Affliction> CODEC = Codecs.JSON_ELEMENT.<Affliction>flatXmap(json -> { public static final PacketCodec<RegistryByteBuf, AfflictionType<?>> PACKET_CODEC = PacketCodecs.registryValue(REGISTRY.getKey());
if (!json.isJsonObject()) {
return DataResult.error(() -> "Not a JSON object");
}
return Identifier.validate(JsonHelper.getString(JsonHelper.asObject(json, "affliction"), "type", AfflictionType.DEFAULT_ID))
.flatMap(type -> AfflictionType.REGISTRY.get(type).codec().parse(JsonOps.INSTANCE, json));
}, thing -> {
AfflictionType<?> type = thing.getType();
return ((Codec<Affliction>)type.codec()).encodeStart(JsonOps.INSTANCE, thing).map(json -> {
if (json.isJsonObject()) {
json.getAsJsonObject().addProperty("type", type.id().toString());
}
return json;
});
});
public static final AfflictionType<Affliction> EMPTY = register("empty", Codec.unit(Affliction.EMPTY), buffer -> Affliction.EMPTY); public static final AfflictionType<EmptyAffliction> EMPTY = register("empty", EmptyAffliction.CODEC, EmptyAffliction.PACKET_CODEC);
public static final AfflictionType<Affliction> MANY = register("many", CompoundAffliction.CODEC, CompoundAffliction::new); public static final AfflictionType<CompoundAffliction> MANY = register("many", CompoundAffliction.CODEC, CompoundAffliction.PACKET_CODEC);
public static final AfflictionType<StatusEffectAffliction> APPLY_STATUS_EFFECT = register("apply_status_effect", StatusEffectAffliction.CODEC, StatusEffectAffliction::new); public static final AfflictionType<StatusEffectAffliction> APPLY_STATUS_EFFECT = register("apply_status_effect", StatusEffectAffliction.CODEC, StatusEffectAffliction.PACKET_CODEC);
public static final AfflictionType<LoseHungerAffliction> LOSE_HUNGER = register("lose_hunger", LoseHungerAffliction.CODEC, LoseHungerAffliction::new); public static final AfflictionType<LoseHungerAffliction> LOSE_HUNGER = register("lose_hunger", LoseHungerAffliction.CODEC, LoseHungerAffliction.PACKET_CODEC);
public static final AfflictionType<HealingAffliction> HEALING = register("healing", HealingAffliction.CODEC, HealingAffliction::new); public static final AfflictionType<HealingAffliction> HEALING = register("healing", HealingAffliction.CODEC, HealingAffliction.PACKET_CODEC);
public static final AfflictionType<ClearLoveSicknessAffliction> CURE_LOVE_SICKNESS = register("cure_love_sickness", ClearLoveSicknessAffliction.CODEC, buffer -> ClearLoveSicknessAffliction.INSTANCE); public static final AfflictionType<ClearLoveSicknessAffliction> CURE_LOVE_SICKNESS = register("cure_love_sickness", ClearLoveSicknessAffliction.CODEC, ClearLoveSicknessAffliction.PACKET_CODEC);
static <T extends Affliction> AfflictionType<T> register(String name, Codec<T> codec, PacketReader<T> reader) { static <T extends Affliction> AfflictionType<T> register(String name, MapCodec<T> codec, PacketCodec<? super RegistryByteBuf, T> packetCodec) {
return Registry.register(REGISTRY, Unicopia.id(name), new AfflictionType<>(codec, Unicopia.id(name), reader)); return Registry.register(REGISTRY, Unicopia.id(name), new AfflictionType<>(Unicopia.id(name), codec, packetCodec));
} }
public String getTranslationKey() { public String getTranslationKey() {

View file

@ -1,15 +1,22 @@
package com.minelittlepony.unicopia.diet.affliction; package com.minelittlepony.unicopia.diet.affliction;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.effect.UEffects;
import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec;
import io.netty.buffer.ByteBuf;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.FoodComponent;
import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.effect.StatusEffects;
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.network.PacketByteBuf; import net.minecraft.network.codec.PacketCodec;
public final class ClearLoveSicknessAffliction implements Affliction { public final class ClearLoveSicknessAffliction implements Affliction {
public static final ClearLoveSicknessAffliction INSTANCE = new ClearLoveSicknessAffliction(); public static final ClearLoveSicknessAffliction INSTANCE = new ClearLoveSicknessAffliction();
public static final Codec<ClearLoveSicknessAffliction> CODEC = Codec.unit(INSTANCE); public static final MapCodec<ClearLoveSicknessAffliction> CODEC = MapCodec.unit(INSTANCE);
public static final PacketCodec<ByteBuf, ClearLoveSicknessAffliction> PACKET_CODEC = PacketCodec.unit(INSTANCE);
@Override @Override
public AfflictionType<?> getType() { public AfflictionType<?> getType() {
@ -18,7 +25,9 @@ public final class ClearLoveSicknessAffliction implements Affliction {
@Override @Override
public void afflict(PlayerEntity player, ItemStack stack) { public void afflict(PlayerEntity player, ItemStack stack) {
player.heal(stack.isFood() ? stack.getItem().getFoodComponent().getHunger() : 1); @Nullable
FoodComponent food = stack.get(DataComponentTypes.FOOD);
player.heal(food == null ? 1 : food.nutrition());
if (player.getWorld().isClient) { if (player.getWorld().isClient) {
return; return;
} }
@ -26,8 +35,4 @@ public final class ClearLoveSicknessAffliction implements Affliction {
player.removeStatusEffect(UEffects.FOOD_POISONING); player.removeStatusEffect(UEffects.FOOD_POISONING);
player.removeStatusEffect(StatusEffects.WEAKNESS); player.removeStatusEffect(StatusEffects.WEAKNESS);
} }
@Override
public void toBuffer(PacketByteBuf buffer) {
}
} }

View file

@ -2,31 +2,25 @@ package com.minelittlepony.unicopia.diet.affliction;
import java.util.List; import java.util.List;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
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.network.PacketByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class CompoundAffliction implements Affliction { public record CompoundAffliction (List<Affliction> afflictions) implements Affliction {
public final List<Affliction> afflictions; public static final MapCodec<CompoundAffliction> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
Affliction.CODEC.listOf().fieldOf("afflictions").forGetter(CompoundAffliction::afflictions)
public CompoundAffliction(List<Affliction> afflictions) { ).apply(instance, CompoundAffliction::new));
this.afflictions = afflictions; public static final PacketCodec<RegistryByteBuf, CompoundAffliction> PACKET_CODEC = null;
}
public static CompoundAffliction of(Affliction...afflictions) { public static CompoundAffliction of(Affliction...afflictions) {
return new CompoundAffliction(List.of(afflictions)); return new CompoundAffliction(List.of(afflictions));
} }
public CompoundAffliction(PacketByteBuf buffer) {
this(buffer.readList(Affliction::read));
}
@Override
public void toBuffer(PacketByteBuf buffer) {
buffer.writeCollection(afflictions, Affliction::write);
}
@Override @Override
public AfflictionType<?> getType() { public AfflictionType<?> getType() {
return AfflictionType.MANY; return AfflictionType.MANY;
@ -49,7 +43,6 @@ public class CompoundAffliction implements Affliction {
}); });
} }
@Override @Override
public void afflict(PlayerEntity player, ItemStack stack) { public void afflict(PlayerEntity player, ItemStack stack) {
afflictions.forEach(i -> i.afflict(player, stack)); afflictions.forEach(i -> i.afflict(player, stack));

View file

@ -0,0 +1,23 @@
package com.minelittlepony.unicopia.diet.affliction;
import com.mojang.serialization.MapCodec;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.network.codec.PacketCodec;
public record EmptyAffliction() implements Affliction {
public static final EmptyAffliction INSTANCE = new EmptyAffliction();
public static final MapCodec<EmptyAffliction> CODEC = MapCodec.unit(INSTANCE);
public static final PacketCodec<ByteBuf, EmptyAffliction> PACKET_CODEC = PacketCodec.unit(INSTANCE);
@Override
public void afflict(PlayerEntity player, ItemStack stack) {
}
@Override
public AfflictionType<?> getType() {
return AfflictionType.EMPTY;
}
}

View file

@ -1,26 +1,21 @@
package com.minelittlepony.unicopia.diet.affliction; package com.minelittlepony.unicopia.diet.affliction;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.netty.buffer.ByteBuf;
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.network.PacketByteBuf; import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public record HealingAffliction(float health) implements Affliction { public record HealingAffliction(float health) implements Affliction {
public static final Codec<HealingAffliction> CODEC = RecordCodecBuilder.create(instance -> instance.group( public static final MapCodec<HealingAffliction> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
Codec.FLOAT.fieldOf("health").forGetter(HealingAffliction::health) Codec.FLOAT.fieldOf("health").forGetter(HealingAffliction::health)
).apply(instance, HealingAffliction::new)); ).apply(instance, HealingAffliction::new));
public static final PacketCodec<ByteBuf, HealingAffliction> PACKET_CODEC = PacketCodecs.FLOAT.xmap(HealingAffliction::new, HealingAffliction::health);
public HealingAffliction(PacketByteBuf buffer) {
this(buffer.readFloat());
}
@Override
public void toBuffer(PacketByteBuf buffer) {
buffer.writeFloat(health);
}
@Override @Override
public AfflictionType<?> getType() { public AfflictionType<?> getType() {

View file

@ -1,26 +1,21 @@
package com.minelittlepony.unicopia.diet.affliction; package com.minelittlepony.unicopia.diet.affliction;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.netty.buffer.ByteBuf;
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.network.PacketByteBuf; import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public record LoseHungerAffliction(float multiplier) implements Affliction { public record LoseHungerAffliction(float multiplier) implements Affliction {
public static final Codec<LoseHungerAffliction> CODEC = RecordCodecBuilder.create(instance -> instance.group( public static final MapCodec<LoseHungerAffliction> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
Codec.FLOAT.fieldOf("multiplier").forGetter(LoseHungerAffliction::multiplier) Codec.FLOAT.fieldOf("multiplier").forGetter(LoseHungerAffliction::multiplier)
).apply(instance, LoseHungerAffliction::new)); ).apply(instance, LoseHungerAffliction::new));
public static final PacketCodec<ByteBuf, LoseHungerAffliction> PACKET_CODEC = PacketCodecs.FLOAT.xmap(LoseHungerAffliction::new, LoseHungerAffliction::multiplier);
public LoseHungerAffliction(PacketByteBuf buffer) {
this(buffer.readFloat());
}
@Override
public void toBuffer(PacketByteBuf buffer) {
buffer.writeFloat(multiplier);
}
@Override @Override
public AfflictionType<?> getType() { public AfflictionType<?> getType() {

View file

@ -1,38 +1,38 @@
package com.minelittlepony.unicopia.diet.affliction; package com.minelittlepony.unicopia.diet.affliction;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Either;
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.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.dynamic.Codecs; import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
public record Range(int min, int max) { public record Range(int min, int max) {
public static final Codec<Range> CODEC = Codecs.xor( private static final Interner<Range> INTERNER = Interners.newWeakInterner();
public static final Codec<Range> CODEC = Codec.xor(
Codec.INT.xmap(value -> Range.of(value, -1), range -> range.min()), Codec.INT.xmap(value -> Range.of(value, -1), range -> range.min()),
RecordCodecBuilder.<Range>create(instance -> instance.group( RecordCodecBuilder.<Range>create(instance -> instance.group(
Codec.INT.fieldOf("min").forGetter(Range::min), Codec.INT.fieldOf("min").forGetter(Range::min),
Codec.INT.fieldOf("max").forGetter(Range::max) Codec.INT.fieldOf("max").forGetter(Range::max)
).apply(instance, Range::of)) ).apply(instance, Range::of))
).xmap(either -> either.left().or(either::right).get(), l -> Either.right(l)); ).xmap(either -> either.left().or(either::right).get(), l -> Either.right(l));
public static final PacketCodec<PacketByteBuf, Range> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.INTEGER, Range::min,
PacketCodecs.INTEGER, Range::max,
Range::of
);
public static Range of(int min, int max) { public static Range of(int min, int max) {
return new Range(min, max); return INTERNER.intern(new Range(min, max));
} }
public static Range of(int exact) { public static Range of(int exact) {
return of(exact, exact); return of(exact, exact);
} }
public static Range of(PacketByteBuf buffer) {
return of(buffer.readInt(), buffer.readInt());
}
public void toBuffer(PacketByteBuf buffer) {
buffer.writeInt(min);
buffer.writeInt(max);
}
public int getClamped(int currentTicks, int multiplier) { public int getClamped(int currentTicks, int multiplier) {
return clamp((min * multiplier) + currentTicks, multiplier); return clamp((min * multiplier) + currentTicks, multiplier);
} }

View file

@ -1,40 +1,39 @@
package com.minelittlepony.unicopia.diet.affliction; package com.minelittlepony.unicopia.diet.affliction;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffectInstance;
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.network.PacketByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.text.MutableText; import net.minecraft.text.MutableText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.StringHelper; import net.minecraft.util.StringHelper;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public record StatusEffectAffliction(StatusEffect effect, Range seconds, Range amplifier, int chance) implements Affliction { public record StatusEffectAffliction(RegistryEntry<StatusEffect> effect, Range seconds, Range amplifier, int chance) implements Affliction {
public static final Codec<StatusEffectAffliction> CODEC = RecordCodecBuilder.create(instance -> instance.group( public static final MapCodec<StatusEffectAffliction> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
Registries.STATUS_EFFECT.getCodec().fieldOf("effect").forGetter(StatusEffectAffliction::effect), Registries.STATUS_EFFECT.getEntryCodec().fieldOf("effect").forGetter(StatusEffectAffliction::effect),
Range.CODEC.fieldOf("seconds").forGetter(StatusEffectAffliction::seconds), Range.CODEC.fieldOf("seconds").forGetter(StatusEffectAffliction::seconds),
Range.CODEC.optionalFieldOf("amplifier", Range.of(0, -1)).forGetter(StatusEffectAffliction::amplifier), Range.CODEC.optionalFieldOf("amplifier", Range.of(0, -1)).forGetter(StatusEffectAffliction::amplifier),
Codec.INT.optionalFieldOf("chance", 0).forGetter(StatusEffectAffliction::chance) Codec.INT.optionalFieldOf("chance", 0).forGetter(StatusEffectAffliction::chance)
).apply(instance, StatusEffectAffliction::new)); ).apply(instance, StatusEffectAffliction::new));
public static final PacketCodec<RegistryByteBuf, StatusEffectAffliction> PACKET_CODEC = PacketCodec.tuple(
public StatusEffectAffliction(PacketByteBuf buffer) { PacketCodecs.registryEntry(RegistryKeys.STATUS_EFFECT), StatusEffectAffliction::effect,
this(Registries.STATUS_EFFECT.get(buffer.readIdentifier()), Range.of(buffer), Range.of(buffer), buffer.readInt()); Range.PACKET_CODEC, StatusEffectAffliction::seconds,
} Range.PACKET_CODEC, StatusEffectAffliction::amplifier,
PacketCodecs.INTEGER, StatusEffectAffliction::chance,
@Override StatusEffectAffliction::new
public void toBuffer(PacketByteBuf buffer) { );
buffer.writeIdentifier(Registries.STATUS_EFFECT.getId(effect));
seconds.toBuffer(buffer);
amplifier.toBuffer(buffer);
buffer.writeInt(chance);
}
@Override @Override
public AfflictionType<?> getType() { public AfflictionType<?> getType() {
@ -43,27 +42,26 @@ public record StatusEffectAffliction(StatusEffect effect, Range seconds, Range a
@Override @Override
public void afflict(PlayerEntity player, ItemStack stack) { public void afflict(PlayerEntity player, ItemStack stack) {
if (player.getWorld().isClient) { if (player.getWorld().isClient || (chance > 0 && player.getWorld().random.nextInt(chance) > 0)) {
return;
}
if (chance > 0 && player.getWorld().random.nextInt(chance) > 0) {
return; return;
} }
float health = player.getHealth(); float health = player.getHealth();
float oldMaxHealth = player.getMaxHealth();
StatusEffectInstance current = player.getStatusEffect(effect); StatusEffectInstance current = player.getStatusEffect(effect);
player.addStatusEffect(new StatusEffectInstance(effect, player.addStatusEffect(new StatusEffectInstance(effect,
seconds.getClamped(current == null ? 0 : current.getDuration(), 20), seconds.getClamped(current == null ? 0 : current.getDuration(), 20),
amplifier.getClamped(current == null ? 0 : current.getAmplifier(), 1) amplifier.getClamped(current == null ? 0 : current.getAmplifier(), 1)
)); ));
// keep original health // keep original health
if (effect.getAttributeModifiers().containsKey(EntityAttributes.GENERIC_MAX_HEALTH)) { if (player.getMaxHealth() != oldMaxHealth) {
player.setHealth(MathHelper.clamp(health, 0, player.getMaxHealth())); player.setHealth(MathHelper.clamp(health, 0, player.getMaxHealth()));
} }
} }
@Override @Override
public Text getName() { public Text getName() {
MutableText text = effect.getName().copy(); MutableText text = effect.value().getName().copy();
if (amplifier.min() > 0) { if (amplifier.min() > 0) {
text = Text.translatable("potion.withAmplifier", text, Text.translatable("potion.potency." + (amplifier.min()))); text = Text.translatable("potion.withAmplifier", text, Text.translatable("potion.potency." + (amplifier.min())));

View file

@ -1,21 +1,21 @@
package com.minelittlepony.unicopia.entity; package com.minelittlepony.unicopia.entity;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import it.unimi.dsi.fastutil.floats.Float2ObjectFunction; import it.unimi.dsi.fastutil.floats.Float2ObjectFunction;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public interface AttributeContainer { public interface AttributeContainer {
@Nullable @Nullable
EntityAttributeInstance getAttributeInstance(EntityAttribute attribute); EntityAttributeInstance getAttributeInstance(RegistryEntry<EntityAttribute> attribute);
default void updateAttributeModifier(UUID id, EntityAttribute attribute, float desiredValue, Float2ObjectFunction<EntityAttributeModifier> modifierSupplier, boolean permanent) { default void updateAttributeModifier(Identifier id, RegistryEntry<EntityAttribute> attribute, float desiredValue, Float2ObjectFunction<EntityAttributeModifier> modifierSupplier, boolean permanent) {
@Nullable @Nullable
EntityAttributeInstance instance = getAttributeInstance(attribute); EntityAttributeInstance instance = getAttributeInstance(attribute);
if (instance == null) { if (instance == null) {
@ -25,7 +25,7 @@ public interface AttributeContainer {
@Nullable @Nullable
EntityAttributeModifier modifier = instance.getModifier(id); EntityAttributeModifier modifier = instance.getModifier(id);
if (!MathHelper.approximatelyEquals(desiredValue, modifier == null ? 0 : modifier.getValue())) { if (!MathHelper.approximatelyEquals(desiredValue, modifier == null ? 0 : modifier.value())) {
instance.removeModifier(id); instance.removeModifier(id);
if (desiredValue != 0) { if (desiredValue != 0) {
@ -38,13 +38,13 @@ public interface AttributeContainer {
} }
} }
default void applyAttributeModifiers(Map<EntityAttribute, EntityAttributeModifier> modifiers, boolean permanent, boolean apply) { default void applyAttributeModifiers(Map<RegistryEntry<EntityAttribute>, EntityAttributeModifier> modifiers, boolean permanent, boolean apply) {
modifiers.forEach((attribute, modifier) -> { modifiers.forEach((attribute, modifier) -> {
applyAttributeModifier(attribute, modifier, permanent, apply); applyAttributeModifier(attribute, modifier, permanent, apply);
}); });
} }
default void applyAttributeModifier(EntityAttribute attribute, EntityAttributeModifier modifier, boolean permanent, boolean apply) { default void applyAttributeModifier(RegistryEntry<EntityAttribute> attribute, EntityAttributeModifier modifier, boolean permanent, boolean apply) {
@Nullable @Nullable
EntityAttributeInstance instance = getAttributeInstance(attribute); EntityAttributeInstance instance = getAttributeInstance(attribute);
if (instance == null) { if (instance == null) {
@ -52,7 +52,7 @@ public interface AttributeContainer {
} }
@Nullable @Nullable
boolean present = instance.hasModifier(modifier); boolean present = instance.hasModifier(modifier.id());
if (present != apply) { if (present != apply) {
if (apply) { if (apply) {
@ -62,7 +62,7 @@ public interface AttributeContainer {
instance.addTemporaryModifier(modifier); instance.addTemporaryModifier(modifier);
} }
} else { } else {
instance.removeModifier(modifier.getId()); instance.removeModifier(modifier.id());
} }
} }
} }

View file

@ -34,6 +34,7 @@ import net.minecraft.entity.passive.*;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutable<LivingEntity> { public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutable<LivingEntity> {
@ -299,23 +300,23 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
super.toNBT(compound); super.toNBT(compound, lookup);
compound.put("master", getMasterReference().toNBT()); compound.put("master", getMasterReference().toNBT(lookup));
physics.toNBT(compound); physics.toNBT(compound, lookup);
compound.putBoolean("discorded", isDiscorded()); compound.putBoolean("discorded", isDiscorded());
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
super.fromNBT(compound); super.fromNBT(compound, lookup);
if (compound.contains("master", NbtElement.COMPOUND_TYPE)) { if (compound.contains("master", NbtElement.COMPOUND_TYPE)) {
owner.fromNBT(compound.getCompound("master")); getMasterReference().fromNBT(compound.getCompound("master"), lookup);
if (owner.isSet()) { if (getMasterReference().isSet()) {
targets.ifPresent(this::initMinionAi); targets.ifPresent(this::initMinionAi);
} }
} }
physics.fromNBT(compound); physics.fromNBT(compound, lookup);
setDiscorded(compound.getBoolean("discorded")); setDiscorded(compound.getBoolean("discorded"));
} }

View file

@ -17,36 +17,41 @@ import com.minelittlepony.unicopia.util.Tickable;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtString; import net.minecraft.nbt.NbtString;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.entry.RegistryEntry;
public class Enchantments implements NbtSerialisable, Tickable { public class Enchantments implements NbtSerialisable, Tickable {
private final Living<?> entity; private final Living<?> entity;
private final Set<Enchantment> equippedEnchantments = new HashSet<>(); private final Set<RegistryEntry<Enchantment>> equippedEnchantments = new HashSet<>();
private final Map<Enchantment, SimpleEnchantment.Data> data = new HashMap<>(); private final Map<RegistryEntry<Enchantment>, SimpleEnchantment.Data> data = new HashMap<>();
Enchantments(Living<?> entity) { Enchantments(Living<?> entity) {
this.entity = entity; this.entity = entity;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends SimpleEnchantment.Data> Optional<T> getOrEmpty(Enchantment enchantment) { public <T extends SimpleEnchantment.Data> Optional<T> getOrEmpty(RegistryEntry<Enchantment> enchantment) {
return Optional.ofNullable((T)data.get(enchantment)); return Optional.ofNullable((T)data.get(enchantment));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends SimpleEnchantment.Data> T computeIfAbsent(Enchantment enchantment, Supplier<T> factory) { public <T extends SimpleEnchantment.Data> T computeIfAbsent(RegistryEntry<Enchantment> enchantment, Supplier<T> factory) {
return (T)data.computeIfAbsent(enchantment, e -> factory.get()); return (T)data.computeIfAbsent(enchantment, e -> factory.get());
} }
@Nullable @Nullable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends SimpleEnchantment.Data> T remove(Enchantment enchantment) { public <T extends SimpleEnchantment.Data> T remove(RegistryEntry<Enchantment> enchantment) {
return (T)data.remove(enchantment); return (T)data.remove(enchantment);
} }
@ -60,37 +65,38 @@ public class Enchantments implements NbtSerialisable, Tickable {
if (active != equippedEnchantments.contains(ench)) { if (active != equippedEnchantments.contains(ench)) {
if (active) { if (active) {
equippedEnchantments.add(ench); equippedEnchantments.add(ench);
ench.onEquipped(entity); ench.value().onEquipped(entity);
} else { } else {
equippedEnchantments.remove(ench); equippedEnchantments.remove(ench);
ench.onUnequipped(entity); ench.value().onUnequipped(entity);
} }
} }
if (active) { if (active) {
ench.onUserTick(entity, level); ench.value().onUserTick(entity, level);
} }
}); });
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
NbtList list = new NbtList(); NbtList list = new NbtList();
equippedEnchantments.forEach(enchant -> { equippedEnchantments.forEach(enchant -> {
Identifier id = Registries.ENCHANTMENT.getId(enchant); enchant.getKey().ifPresent(key -> {
if (id != null) { list.add(NbtString.of(key.getValue().toString()));
list.add(NbtString.of(id.toString())); });
}
}); });
compound.put("enchants", list); compound.put("enchants", list);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
equippedEnchantments.clear(); equippedEnchantments.clear();
if (compound.contains("enchants")) { if (compound.contains("enchants")) {
compound.getList("enchants", 8).forEach(tag -> { compound.getList("enchants", NbtElement.STRING_TYPE).forEach(tag -> {
Registries.ENCHANTMENT.getOrEmpty(new Identifier(tag.asString())).ifPresent(equippedEnchantments::add); lookup.getWrapperOrThrow(RegistryKeys.ENCHANTMENT)
.getOptional(RegistryKey.of(RegistryKeys.ENCHANTMENT, Identifier.of(tag.asString())))
.ifPresent(equippedEnchantments::add);
}); });
} }
} }

View file

@ -14,6 +14,7 @@ import net.minecraft.entity.EntityPose;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.BlockTags;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -130,12 +131,12 @@ public class EntityPhysics<T extends Entity> implements Physics, Copyable<Entity
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
compound.putFloat("gravity", getBaseGravityModifier()); compound.putFloat("gravity", getBaseGravityModifier());
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
setBaseGravityModifier(compound.getFloat("gravity")); setBaseGravityModifier(compound.getFloat("gravity"));
} }

View file

@ -23,6 +23,7 @@ import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
@ -154,13 +155,13 @@ public class ItemImpl implements Equine<ItemEntity> {
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
compound.putString("owner_race", getSpecies().getId().toString()); compound.putString("owner_race", getSpecies().getId().toString());
physics.toNBT(compound); physics.toNBT(compound);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
if (compound.contains("owner_race", NbtElement.STRING_TYPE)) { if (compound.contains("owner_race", NbtElement.STRING_TYPE)) {
setSpecies(Race.fromName(compound.getString("owner_race"), Race.HUMAN)); setSpecies(Race.fromName(compound.getString("owner_race"), Race.HUMAN));
} }
@ -209,7 +210,8 @@ public class ItemImpl implements Equine<ItemEntity> {
boolean isClingy(ItemStack stack); boolean isClingy(ItemStack stack);
default ParticleEffect getParticleEffect(IItemEntity entity) { default ParticleEffect getParticleEffect(IItemEntity entity) {
return ParticleTypes.AMBIENT_ENTITY_EFFECT; // TODO: was AMBIENT_ENTITY_EFFECT
return ParticleTypes.EFFECT;
} }
default float getFollowDistance(IItemEntity entity) { default float getFollowDistance(IItemEntity entity) {

View file

@ -16,6 +16,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
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;
public class ItemTracker implements NbtSerialisable, Copyable<ItemTracker>, Tickable, TrinketsDelegate.Inventory { public class ItemTracker implements NbtSerialisable, Copyable<ItemTracker>, Tickable, TrinketsDelegate.Inventory {
public static final long TICKS = 1; public static final long TICKS = 1;
@ -115,14 +116,14 @@ public class ItemTracker implements NbtSerialisable, Copyable<ItemTracker>, Tick
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
items.forEach((charm, count) -> { items.forEach((charm, count) -> {
compound.putLong(Registries.ITEM.getId(charm.asItem()).toString(), count); compound.putLong(Registries.ITEM.getId(charm.asItem()).toString(), count);
}); });
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
items.clear(); items.clear();
compound.getKeys().stream().map(Identifier::tryParse) compound.getKeys().stream().map(Identifier::tryParse)
.filter(Objects::nonNull) .filter(Objects::nonNull)

View file

@ -42,7 +42,6 @@ import com.minelittlepony.unicopia.util.*;
import net.fabricmc.fabric.api.util.TriState; import net.fabricmc.fabric.api.util.TriState;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.*; import net.minecraft.entity.*;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
@ -59,6 +58,9 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket; import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.DamageTypeTags; import net.minecraft.registry.tag.DamageTypeTags;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.BlockSoundGroup;
@ -252,7 +254,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
} }
@Override @Override
public final @Nullable EntityAttributeInstance getAttributeInstance(EntityAttribute attribute) { public final @Nullable EntityAttributeInstance getAttributeInstance(RegistryEntry<EntityAttribute> attribute) {
return asEntity().getAttributeInstance(attribute); return asEntity().getAttributeInstance(attribute);
} }
@ -373,8 +375,8 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
if (magical.isIn(UTags.DamageTypes.BREAKS_SUNGLASSES)) { if (magical.isIn(UTags.DamageTypes.BREAKS_SUNGLASSES)) {
ItemStack glasses = GlassesItem.getForEntity(entity).stack(); ItemStack glasses = GlassesItem.getForEntity(entity).stack();
if (glasses.isOf(UItems.SUNGLASSES)) { if (glasses.isOf(UItems.SUNGLASSES)) {
ItemStack broken = UItems.BROKEN_SUNGLASSES.getDefaultStack(); // TODO: BreaksIntoItemComponent
broken.setNbt(glasses.getNbt()); ItemStack broken = glasses.withItem(UItems.BROKEN_SUNGLASSES);
TrinketsDelegate.getInstance(entity).setEquippedStack(entity, TrinketsDelegate.FACE, broken); TrinketsDelegate.getInstance(entity).setEquippedStack(entity, TrinketsDelegate.FACE, broken);
playSound(USounds.ITEM_SUNGLASSES_SHATTER, 1, 1); playSound(USounds.ITEM_SUNGLASSES_SHATTER, 1, 1);
} }
@ -450,34 +452,35 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
@Override @Override
public float getCloudWalkingStrength() { public float getCloudWalkingStrength() {
Enchantment featherFalling = net.minecraft.enchantment.Enchantments.FEATHER_FALLING; return asWorld().getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(net.minecraft.enchantment.Enchantments.FEATHER_FALLING).map(featherFalling -> {
int maxLevel = featherFalling.getMaxLevel(); int maxLevel = featherFalling.value().getMaxLevel();
int level = EnchantmentHelper.getEquipmentLevel(featherFalling, entity); int level = EnchantmentHelper.getEquipmentLevel(featherFalling, entity);
return MathHelper.clamp(level / (float)maxLevel, 0, 1); return MathHelper.clamp(level / (float)maxLevel, 0, 1);
}).orElse(0F);
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
enchants.toNBT(compound); enchants.toNBT(compound);
spells.getSlots().toNBT(compound); spells.getSlots().toNBT(compound, lookup);
getCarrierId().ifPresent(id -> compound.putUuid("carrier", id)); getCarrierId().ifPresent(id -> compound.putUuid("carrier", id));
toSyncronisedNbt(compound); toSyncronisedNbt(compound, lookup);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
enchants.fromNBT(compound); enchants.fromNBT(compound);
spells.getSlots().fromNBT(compound); spells.getSlots().fromNBT(compound, lookup);
setCarrier(compound.containsUuid("carrier") ? compound.getUuid("carrier") : null); setCarrier(compound.containsUuid("carrier") ? compound.getUuid("carrier") : null);
fromSynchronizedNbt(compound); fromSynchronizedNbt(compound, lookup);
} }
public void toSyncronisedNbt(NbtCompound compound) { public void toSyncronisedNbt(NbtCompound compound, WrapperLookup lookup) {
compound.put("armour", armour.toNBT()); compound.put("armour", armour.toNBT(lookup));
} }
public void fromSynchronizedNbt(NbtCompound compound) { public void fromSynchronizedNbt(NbtCompound compound, WrapperLookup lookup) {
armour.fromNBT(compound.getCompound("armour")); armour.fromNBT(compound.getCompound("armour"), lookup);
} }
public void updateVelocity() { public void updateVelocity() {

View file

@ -2,10 +2,11 @@ package com.minelittlepony.unicopia.entity.effect;
import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.InteractionManager;
import net.minecraft.component.type.AttributeModifiersComponent;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.ItemStack; import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.StringHelper; import net.minecraft.util.StringHelper;
@ -23,7 +24,7 @@ public interface EffectUtils {
return getAmplifier(entity, UEffects.BROKEN_WINGS) > 1; return getAmplifier(entity, UEffects.BROKEN_WINGS) > 1;
} }
static int getAmplifier(LivingEntity entity, StatusEffect effect) { static int getAmplifier(LivingEntity entity, RegistryEntry<StatusEffect> effect) {
return entity.hasStatusEffect(effect) ? entity.getStatusEffect(effect).getAmplifier() + 1 : 0; return entity.hasStatusEffect(effect) ? entity.getStatusEffect(effect).getAmplifier() + 1 : 0;
} }
@ -35,7 +36,7 @@ public interface EffectUtils {
return entity.hasStatusEffect(UEffects.FORTIFICATION); return entity.hasStatusEffect(UEffects.FORTIFICATION);
} }
static boolean applyStatusEffect(LivingEntity entity, StatusEffect effect, boolean apply) { static boolean applyStatusEffect(LivingEntity entity, RegistryEntry<StatusEffect> effect, boolean apply) {
if (entity.getWorld().isClient) { if (entity.getWorld().isClient) {
return false; return false;
} }
@ -62,14 +63,14 @@ public interface EffectUtils {
static Text formatModifierChange(String modifierName, float change, boolean isDetrimental) { static Text formatModifierChange(String modifierName, float change, boolean isDetrimental) {
return Text.literal(" ").append(Text.translatable("attribute.modifier." + (change > 0 ? "plus" : "take") + ".0", return Text.literal(" ").append(Text.translatable("attribute.modifier." + (change > 0 ? "plus" : "take") + ".0",
ItemStack.MODIFIER_FORMAT.format(Math.abs(change)), AttributeModifiersComponent.DECIMAL_FORMAT.format(Math.abs(change)),
Text.translatable(modifierName) Text.translatable(modifierName)
).formatted((isDetrimental ? change : -change) < 0 ? Formatting.DARK_GREEN : Formatting.RED)); ).formatted((isDetrimental ? change : -change) < 0 ? Formatting.DARK_GREEN : Formatting.RED));
} }
static Text formatModifierChange(Text modifierName, float change, boolean isDetrimental) { static Text formatModifierChange(Text modifierName, float change, boolean isDetrimental) {
return Text.literal(" ").append(Text.translatable("attribute.modifier." + (change > 0 ? "plus" : "take") + ".0", return Text.literal(" ").append(Text.translatable("attribute.modifier." + (change > 0 ? "plus" : "take") + ".0",
ItemStack.MODIFIER_FORMAT.format(Math.abs(change)), AttributeModifiersComponent.DECIMAL_FORMAT.format(Math.abs(change)),
modifierName modifierName
).formatted((isDetrimental ? change : -change) < 0 ? Formatting.DARK_GREEN : Formatting.RED)); ).formatted((isDetrimental ? change : -change) < 0 ? Formatting.DARK_GREEN : Formatting.RED));
} }

View file

@ -5,30 +5,31 @@ import com.minelittlepony.unicopia.Unicopia;
import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory; import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
public interface UEffects { public interface UEffects {
StatusEffect FOOD_POISONING = register("food_poisoning", new FoodPoisoningStatusEffect(3484199)); RegistryEntry<StatusEffect> FOOD_POISONING = register("food_poisoning", new FoodPoisoningStatusEffect(3484199));
StatusEffect SUN_BLINDNESS = register("sun_blindness", new SunBlindnessStatusEffect(0x886F0F)); RegistryEntry<StatusEffect> SUN_BLINDNESS = register("sun_blindness", new SunBlindnessStatusEffect(0x886F0F));
/** /**
* Status effect emitted by players with a high level of corruption. * Status effect emitted by players with a high level of corruption.
* When affecting an entity, will give them a random chance to reproduce or duplicate themselves when they die. * When affecting an entity, will give them a random chance to reproduce or duplicate themselves when they die.
*/ */
StatusEffect CORRUPT_INFLUENCE = register("corrupt_influence", new CorruptInfluenceStatusEffect(0x00FF00)); RegistryEntry<StatusEffect> CORRUPT_INFLUENCE = register("corrupt_influence", new CorruptInfluenceStatusEffect(0x00FF00));
StatusEffect PARALYSIS = register("paralysis", new SimpleStatusEffect(StatusEffectCategory.HARMFUL, 0, false)); RegistryEntry<StatusEffect> PARALYSIS = register("paralysis", new SimpleStatusEffect(StatusEffectCategory.HARMFUL, 0, false));
StatusEffect FORTIFICATION = register("fortification", new SimpleStatusEffect(StatusEffectCategory.BENEFICIAL, 0x000077, false)); RegistryEntry<StatusEffect> FORTIFICATION = register("fortification", new SimpleStatusEffect(StatusEffectCategory.BENEFICIAL, 0x000077, false));
StatusEffect BROKEN_WINGS = register("broken_wings", new SimpleStatusEffect(StatusEffectCategory.BENEFICIAL, 0xEEAA00, false)); RegistryEntry<StatusEffect> BROKEN_WINGS = register("broken_wings", new SimpleStatusEffect(StatusEffectCategory.BENEFICIAL, 0xEEAA00, false));
/** /**
* Side-effect of wearing the alicorn amulet. * Side-effect of wearing the alicorn amulet.
* Causes the player to lose grip on whatever item they're holding. * Causes the player to lose grip on whatever item they're holding.
*/ */
StatusEffect BUTTER_FINGERS = register("butter_fingers", new ButterfingersStatusEffect(0x888800)); RegistryEntry<StatusEffect> BUTTER_FINGERS = register("butter_fingers", new ButterfingersStatusEffect(0x888800));
StatusEffect SEAPONYS_GRACE = register("seaponys_grace", new SimpleStatusEffect(StatusEffectCategory.BENEFICIAL, 0x0000EE, false)); RegistryEntry<StatusEffect> SEAPONYS_GRACE = register("seaponys_grace", new SimpleStatusEffect(StatusEffectCategory.BENEFICIAL, 0x0000EE, false));
StatusEffect SEAPONYS_IRE = register("seaponys_ire", new SimpleStatusEffect(StatusEffectCategory.HARMFUL, 0xEE00EE, false)); RegistryEntry<StatusEffect> SEAPONYS_IRE = register("seaponys_ire", new SimpleStatusEffect(StatusEffectCategory.HARMFUL, 0xEE00EE, false));
private static StatusEffect register(String name, StatusEffect effect) { private static RegistryEntry<StatusEffect> register(String name, StatusEffect effect) {
return Registry.register(Registries.STATUS_EFFECT, Unicopia.id(name), effect); return Registry.registerReference(Registries.STATUS_EFFECT, Unicopia.id(name), effect);
} }
static void bootstrap() {} static void bootstrap() {}

View file

@ -1,13 +1,9 @@
package com.minelittlepony.unicopia.entity.mob; package com.minelittlepony.unicopia.entity.mob;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
@ -15,9 +11,9 @@ import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.item.ButterflyItem; import com.minelittlepony.unicopia.item.ButterflyItem;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.ItemEntity; import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.SpawnReason; import net.minecraft.entity.SpawnReason;
@ -27,16 +23,20 @@ import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.data.DataTracker.Builder;
import net.minecraft.entity.mob.AmbientEntity; import net.minecraft.entity.mob.AmbientEntity;
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.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.ItemTags; import net.minecraft.registry.tag.ItemTags;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -73,6 +73,7 @@ public class ButterflyEntity extends AmbientEntity {
} }
public static boolean canSpawn(EntityType<? extends ButterflyEntity> type, WorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { public static boolean canSpawn(EntityType<? extends ButterflyEntity> type, WorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) {
// TODO: Uncomment this
return true;//world.getBlockState(pos.down()).isIn(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON); return true;//world.getBlockState(pos.down()).isIn(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON);
} }
@ -104,10 +105,10 @@ public class ButterflyEntity extends AmbientEntity {
} }
@Override @Override
protected void initDataTracker() { protected void initDataTracker(Builder builder) {
super.initDataTracker(); super.initDataTracker(builder);
getDataTracker().startTracking(VARIANT, Variant.BUTTERFLY.ordinal()); builder.add(VARIANT, Variant.BUTTERFLY.ordinal());
getDataTracker().startTracking(RESTING, false); builder.add(RESTING, false);
} }
@Override @Override
@ -330,11 +331,6 @@ public class ButterflyEntity extends AmbientEntity {
return reason != SpawnReason.NATURAL || (getY() >= world.getSeaLevel() && world.getLightLevel(getBlockPos()) > 3); return reason != SpawnReason.NATURAL || (getY() >= world.getSeaLevel() && world.getLightLevel(getBlockPos()) > 3);
} }
@Override
public float getEyeHeight(EntityPose pose) {
return getHeight() / 2;
}
@Override @Override
public ItemEntity dropStack(ItemStack stack, float yOffset) { public ItemEntity dropStack(ItemStack stack, float yOffset) {
return super.dropStack(ButterflyItem.setVariant(stack, getVariant()), yOffset); return super.dropStack(ButterflyItem.setVariant(stack, getVariant()), yOffset);
@ -345,8 +341,12 @@ public class ButterflyEntity extends AmbientEntity {
super.writeCustomDataToNbt(nbt); super.writeCustomDataToNbt(nbt);
nbt.putInt("ticksResting", ticksResting); nbt.putInt("ticksResting", ticksResting);
nbt.putInt("breedingCooldown", breedingCooldown); nbt.putInt("breedingCooldown", breedingCooldown);
NbtSerialisable.BLOCK_POS.writeOptional("hoveringPosition", nbt, hoveringPosition); hoveringPosition.ifPresent(pos -> {
NbtSerialisable.BLOCK_POS.writeOptional("flowerPosition", nbt, flowerPosition); nbt.put("hoveringPosition", NbtSerialisable.encode(BlockPos.CODEC, pos));
});
flowerPosition.ifPresent(pos -> {
nbt.put("flowerPosition", NbtSerialisable.encode(BlockPos.CODEC, pos));
});
NbtCompound visited = new NbtCompound(); NbtCompound visited = new NbtCompound();
this.visited.forEach((pos, time) -> { this.visited.forEach((pos, time) -> {
visited.putLong(String.valueOf(pos.asLong()), time); visited.putLong(String.valueOf(pos.asLong()), time);
@ -359,8 +359,8 @@ public class ButterflyEntity extends AmbientEntity {
super.readCustomDataFromNbt(nbt); super.readCustomDataFromNbt(nbt);
ticksResting = nbt.getInt("ticksResting"); ticksResting = nbt.getInt("ticksResting");
breedingCooldown = nbt.getInt("breedingCooldown"); breedingCooldown = nbt.getInt("breedingCooldown");
hoveringPosition = NbtSerialisable.BLOCK_POS.readOptional("hoveringPosition", nbt); hoveringPosition = NbtSerialisable.decode(BlockPos.CODEC, nbt.get("hoveringPosition"));
flowerPosition = NbtSerialisable.BLOCK_POS.readOptional("flowerPosition", nbt); flowerPosition = NbtSerialisable.decode(BlockPos.CODEC, nbt.get("flowerPosition"));
NbtCompound visited = nbt.getCompound("visited"); NbtCompound visited = nbt.getCompound("visited");
this.visited.clear(); this.visited.clear();
visited.getKeys().forEach(key -> { visited.getKeys().forEach(key -> {
@ -370,7 +370,7 @@ public class ButterflyEntity extends AmbientEntity {
}); });
} }
public enum Variant { public enum Variant implements StringIdentifiable {
BUTTERFLY, BUTTERFLY,
YELLOW, YELLOW,
LIME, LIME,
@ -388,9 +388,12 @@ public class ButterflyEntity extends AmbientEntity {
BRIMSTONE; BRIMSTONE;
public static final Variant[] VALUES = Variant.values(); public static final Variant[] VALUES = Variant.values();
private static final Map<String, Variant> REGISTRY = Arrays.stream(VALUES).collect(Collectors.toMap(a -> a.name().toLowerCase(Locale.ROOT), Function.identity()));
private final Identifier skin = Unicopia.id("textures/entity/butterfly/" + name().toLowerCase(Locale.ROOT) + ".png"); public static final EnumCodec<Variant> CODEC = StringIdentifiable.createCodec(Variant::values);
public static final PacketCodec<ByteBuf, Variant> PACKET_CODEC = PacketCodecs.indexed(i -> VALUES[i], Variant::ordinal);
private final String name = name().toLowerCase(Locale.ROOT);
private final Identifier skin = Unicopia.id("textures/entity/butterfly/" + name + ".png");
public Identifier getSkin() { public Identifier getSkin() {
return skin; return skin;
@ -405,7 +408,12 @@ public class ButterflyEntity extends AmbientEntity {
} }
public static Variant byName(String name) { public static Variant byName(String name) {
return REGISTRY.getOrDefault(name == null ? "" : name, BUTTERFLY); return CODEC.byId(name, BUTTERFLY);
}
@Override
public String asString() {
return name;
} }
} }
} }

View file

@ -12,11 +12,12 @@ import com.minelittlepony.unicopia.container.SpellbookScreenHandler;
import com.minelittlepony.unicopia.container.SpellbookState; import com.minelittlepony.unicopia.container.SpellbookState;
import com.minelittlepony.unicopia.entity.MagicImmune; import com.minelittlepony.unicopia.entity.MagicImmune;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.item.component.UDataComponentTypes;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgSpellbookStateChanged; import com.minelittlepony.unicopia.network.MsgSpellbookStateChanged;
import com.minelittlepony.unicopia.server.world.Altar; import com.minelittlepony.unicopia.server.world.Altar;
import com.minelittlepony.unicopia.util.MeteorlogicalUtil; import com.minelittlepony.unicopia.util.MeteorlogicalUtil;
import com.minelittlepony.unicopia.util.NbtSerialisable;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.fabricmc.fabric.api.util.TriState; import net.fabricmc.fabric.api.util.TriState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@ -27,12 +28,12 @@ import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.data.DataTracker.Builder;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.screen.*; import net.minecraft.screen.*;
@ -62,7 +63,7 @@ public class SpellbookEntity extends MobEntity implements MagicImmune {
private int activeTicks = TICKS_TO_SLEEP; private int activeTicks = TICKS_TO_SLEEP;
private boolean prevDaytime; private boolean prevDaytime;
private final SpellbookState state = new SpellbookState(); private SpellbookState state = new SpellbookState();
private Optional<Altar> altar = Optional.empty(); private Optional<Altar> altar = Optional.empty();
@ -91,20 +92,25 @@ public class SpellbookEntity extends MobEntity implements MagicImmune {
} }
@Override @Override
protected void initDataTracker() { protected void initDataTracker(Builder builder) {
super.initDataTracker(); super.initDataTracker(builder);
dataTracker.startTracking(LOCKED, (byte)1); builder.add(LOCKED, (byte)1);
dataTracker.startTracking(ALTERED, false); builder.add(ALTERED, false);
} }
public SpellbookState getSpellbookState() { public SpellbookState getSpellbookState() {
return state; return state;
} }
public void setSpellbookState(SpellbookState state) {
state.copySyncronizer(this.state);
this.state = state;
}
@Override @Override
public ItemStack getPickBlockStack() { public ItemStack getPickBlockStack() {
ItemStack stack = UItems.SPELLBOOK.getDefaultStack(); ItemStack stack = UItems.SPELLBOOK.getDefaultStack();
stack.getOrCreateNbt().put("spellbookState", state.toNBT()); stack.set(UDataComponentTypes.SPELLBOOK_STATE, state.createCopy());
return stack; return stack;
} }
@ -345,7 +351,7 @@ public class SpellbookEntity extends MobEntity implements MagicImmune {
if (isOpen()) { if (isOpen()) {
keepAwake(); keepAwake();
player.openHandledScreen(new ExtendedScreenHandlerFactory() { player.openHandledScreen(new ExtendedScreenHandlerFactory<SpellbookState>() {
@Override @Override
public Text getDisplayName() { public Text getDisplayName() {
return SpellbookEntity.this.getDisplayName(); return SpellbookEntity.this.getDisplayName();
@ -357,8 +363,8 @@ public class SpellbookEntity extends MobEntity implements MagicImmune {
} }
@Override @Override
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) { public SpellbookState getScreenOpeningData(ServerPlayerEntity player) {
state.toPacket(buf); return state;
} }
}); });
player.playSound(USounds.Vanilla.ITEM_BOOK_PAGE_TURN, 2, 1); player.playSound(USounds.Vanilla.ITEM_BOOK_PAGE_TURN, 2, 1);
@ -385,8 +391,8 @@ public class SpellbookEntity extends MobEntity implements MagicImmune {
activeTicks = compound.getInt("activeTicks"); activeTicks = compound.getInt("activeTicks");
setAltered(compound.getBoolean("altered")); setAltered(compound.getBoolean("altered"));
setForcedState(compound.contains("locked") ? TriState.of(compound.getBoolean("locked")) : TriState.DEFAULT); setForcedState(compound.contains("locked") ? TriState.of(compound.getBoolean("locked")) : TriState.DEFAULT);
state.fromNBT(compound.getCompound("spellbookState")); state.fromNBT(compound.getCompound("spellbookState"), getWorld().getRegistryManager());
altar = Altar.SERIALIZER.readOptional("altar", compound); altar = NbtSerialisable.decode(Altar.CODEC, compound.get("altar"));
} }
@Override @Override
@ -395,12 +401,14 @@ public class SpellbookEntity extends MobEntity implements MagicImmune {
compound.putInt("activeTicks", activeTicks); compound.putInt("activeTicks", activeTicks);
compound.putBoolean("prevDaytime", prevDaytime); compound.putBoolean("prevDaytime", prevDaytime);
compound.putBoolean("altered", isAltered()); compound.putBoolean("altered", isAltered());
compound.put("spellbookState", state.toNBT()); compound.put("spellbookState", state.toNBT(getWorld().getRegistryManager()));
getForcedState().map(t -> { getForcedState().map(t -> {
compound.putBoolean("locked", t); compound.putBoolean("locked", t);
return null; return null;
}); });
Altar.SERIALIZER.writeOptional("altar", compound, altar); altar.ifPresent(altar -> {
compound.put("altar", NbtSerialisable.encode(Altar.CODEC, altar));
});
} }
@Override @Override

View file

@ -26,6 +26,7 @@ import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
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.loot.LootTable;
import net.minecraft.loot.context.LootContextParameterSet; import net.minecraft.loot.context.LootContextParameterSet;
import net.minecraft.loot.context.LootContextParameters; import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.loot.context.LootContextTypes; import net.minecraft.loot.context.LootContextTypes;
@ -33,11 +34,12 @@ import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -73,11 +75,11 @@ public class StormCloudEntity extends Entity implements MagicImmune {
} }
@Override @Override
protected void initDataTracker() { protected void initDataTracker(DataTracker.Builder builder) {
dataTracker.startTracking(STORM_TICKS, 0); builder.add(STORM_TICKS, 0);
dataTracker.startTracking(CLEAR_TICKS, 0); builder.add(CLEAR_TICKS, 0);
dataTracker.startTracking(TARGET_SIZE, 1F); builder.add(TARGET_SIZE, 1F);
dataTracker.startTracking(DISSIPATING, false); builder.add(DISSIPATING, false);
} }
public boolean isStormy() { public boolean isStormy() {
@ -295,17 +297,17 @@ public class StormCloudEntity extends Entity implements MagicImmune {
if (random.nextInt(35) == 0 || (source.isOf(DamageTypes.PLAYER_ATTACK) && EquineContext.of(source.getAttacker()).collidesWithClouds())) { if (random.nextInt(35) == 0 || (source.isOf(DamageTypes.PLAYER_ATTACK) && EquineContext.of(source.getAttacker()).collidesWithClouds())) {
if (getSize(1) < 2) { if (getSize(1) < 2) {
if (!getWorld().isClient() && getWorld().getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { if (!getWorld().isClient() && getWorld().getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) {
Identifier identifier = getType().getLootTableId(); RegistryKey<LootTable> table = getType().getLootTableId();
LootContextParameterSet.Builder builder = new LootContextParameterSet.Builder((ServerWorld)this.getWorld()) LootContextParameterSet.Builder builder = new LootContextParameterSet.Builder((ServerWorld)this.getWorld())
.add(LootContextParameters.THIS_ENTITY, this) .add(LootContextParameters.THIS_ENTITY, this)
.add(LootContextParameters.ORIGIN, this.getPos()) .add(LootContextParameters.ORIGIN, this.getPos())
.add(LootContextParameters.DAMAGE_SOURCE, source) .add(LootContextParameters.DAMAGE_SOURCE, source)
.addOptional(LootContextParameters.KILLER_ENTITY, source.getAttacker()) .addOptional(LootContextParameters.ATTACKING_ENTITY, source.getAttacker())
.addOptional(LootContextParameters.DIRECT_KILLER_ENTITY, source.getSource()); .addOptional(LootContextParameters.DIRECT_ATTACKING_ENTITY, source.getSource());
if (source.getAttacker() instanceof PlayerEntity player) { if (source.getAttacker() instanceof PlayerEntity player) {
builder = builder.add(LootContextParameters.LAST_DAMAGE_PLAYER, player).luck(player.getLuck()); builder = builder.add(LootContextParameters.LAST_DAMAGE_PLAYER, player).luck(player.getLuck());
} }
getWorld().getServer().getLootManager().getLootTable(identifier) getWorld().getRegistryManager().get(RegistryKeys.LOOT_TABLE).get(table)
.generateLoot(builder.build(LootContextTypes.ENTITY), 0L, this::dropStack); .generateLoot(builder.build(LootContextTypes.ENTITY), 0L, this::dropStack);
} }
kill(); kill();

View file

@ -1,7 +1,5 @@
package com.minelittlepony.unicopia.entity.mob; package com.minelittlepony.unicopia.entity.mob;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
@ -13,14 +11,11 @@ import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity;
import net.fabricmc.fabric.api.biome.v1.BiomeModifications; import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityType;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup; import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.SpawnRestriction.Location; import net.minecraft.entity.SpawnLocationTypes;
import net.minecraft.entity.decoration.painting.PaintingVariant;
import net.minecraft.entity.mob.FlyingEntity; import net.minecraft.entity.mob.FlyingEntity;
import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.registry.*; import net.minecraft.registry.*;
@ -28,91 +23,92 @@ import net.minecraft.registry.tag.BiomeTags;
import net.minecraft.world.Heightmap.Type; import net.minecraft.world.Heightmap.Type;
public interface UEntities { public interface UEntities {
EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.createMob().spawnGroup(SpawnGroup.AMBIENT).entityFactory(ButterflyEntity::new) EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityType.Builder.createMob(ButterflyEntity::new, SpawnGroup.AMBIENT, builder -> builder
.spawnRestriction(Location.NO_RESTRICTIONS, Type.MOTION_BLOCKING_NO_LEAVES, ButterflyEntity::canSpawn) .spawnRestriction(SpawnLocationTypes.UNRESTRICTED, Type.MOTION_BLOCKING_NO_LEAVES, ButterflyEntity::canSpawn)
.defaultAttributes(ButterflyEntity::createButterflyAttributes))
.spawnableFarFromPlayer() .spawnableFarFromPlayer()
.dimensions(EntityDimensions.fixed(0.25F, 0.25F))); .dimensions(0.25F, 0.25F)
EntityType<MagicProjectileEntity> THROWN_ITEM = register("thrown_item", FabricEntityTypeBuilder.<MagicProjectileEntity>create(SpawnGroup.MISC, MagicProjectileEntity::new) .eyeHeight(0.125F));
.trackRangeBlocks(100) EntityType<MagicProjectileEntity> THROWN_ITEM = register("thrown_item", EntityType.Builder.<MagicProjectileEntity>create(MagicProjectileEntity::new, SpawnGroup.MISC)
.maxTrackingRange(100)
.disableSummon() .disableSummon()
.trackedUpdateRate(2) .trackingTickInterval(2)
.dimensions(EntityDimensions.fixed(0.25F, 0.25F))); .dimensions(0.25F, 0.25F));
EntityType<PhysicsBodyProjectileEntity> MUFFIN = register("muffin", FabricEntityTypeBuilder.<PhysicsBodyProjectileEntity>create(SpawnGroup.MISC, (type, world) -> new PhysicsBodyProjectileEntity(type, world, UItems.MUFFIN.getDefaultStack())) EntityType<PhysicsBodyProjectileEntity> MUFFIN = register("muffin", EntityType.Builder.<PhysicsBodyProjectileEntity>create((type, world) -> new PhysicsBodyProjectileEntity(type, world, UItems.MUFFIN.getDefaultStack()), SpawnGroup.MISC)
.trackRangeBlocks(100) .maxTrackingRange(100)
.disableSummon() .disableSummon()
.trackedUpdateRate(2) .trackingTickInterval(2)
.dimensions(EntityDimensions.fixed(0.25F, 0.25F))); .dimensions(0.25F, 0.25F));
EntityType<MagicBeamEntity> MAGIC_BEAM = register("magic_beam", FabricEntityTypeBuilder.<MagicBeamEntity>create(SpawnGroup.MISC, MagicBeamEntity::new) EntityType<MagicBeamEntity> MAGIC_BEAM = register("magic_beam", EntityType.Builder.<MagicBeamEntity>create(MagicBeamEntity::new, SpawnGroup.MISC)
.trackRangeBlocks(100) .maxTrackingRange(100)
.disableSummon() .disableSummon()
.trackedUpdateRate(2) .trackingTickInterval(2)
.dimensions(EntityDimensions.fixed(0.25F, 0.25F))); .alwaysUpdateVelocity(true)
EntityType<FloatingArtefactEntity> FLOATING_ARTEFACT = register("floating_artefact", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FloatingArtefactEntity::new) .dimensions(0.25F, 0.25F));
.trackRangeBlocks(200) EntityType<FloatingArtefactEntity> FLOATING_ARTEFACT = register("floating_artefact", EntityType.Builder.create(FloatingArtefactEntity::new, SpawnGroup.MISC)
.maxTrackingRange(200)
.disableSummon() .disableSummon()
.dimensions(EntityDimensions.fixed(1, 1))); .dimensions(1, 1));
EntityType<CastSpellEntity> CAST_SPELL = register("cast_spell", FabricEntityTypeBuilder.<CastSpellEntity>create(SpawnGroup.MISC, CastSpellEntity::new) EntityType<CastSpellEntity> CAST_SPELL = register("cast_spell", EntityType.Builder.<CastSpellEntity>create(CastSpellEntity::new, SpawnGroup.MISC)
.trackRangeBlocks(200) .maxTrackingRange(200)
.disableSummon() .disableSummon()
.dimensions(EntityDimensions.changing(4, 4))); .dimensions(4, 4));
EntityType<FairyEntity> TWITTERMITE = register("twittermite", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FairyEntity::new) EntityType<FairyEntity> TWITTERMITE = register("twittermite", FabricEntityType.Builder.createMob(FairyEntity::new, SpawnGroup.MISC, builder -> builder
.trackRangeBlocks(200) .defaultAttributes(FairyEntity::createMobAttributes))
.dimensions(EntityDimensions.fixed(0.1F, 0.1F))); .maxTrackingRange(200)
EntityType<FriendlyCreeperEntity> FRIENDLY_CREEPER = register("friendly_creeper", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FriendlyCreeperEntity::new) .dimensions(0.1F, 0.1F));
.trackRangeChunks(8) EntityType<FriendlyCreeperEntity> FRIENDLY_CREEPER = register("friendly_creeper", FabricEntityType.Builder.createMob(FriendlyCreeperEntity::new, SpawnGroup.MISC, builder -> builder
.defaultAttributes(FriendlyCreeperEntity::createCreeperAttributes))
.maxTrackingRange(8)
.disableSummon() .disableSummon()
.dimensions(EntityDimensions.fixed(0.6f, 1.7f))); .dimensions(0.6f, 1.7f));
EntityType<SpellbookEntity> SPELLBOOK = register("spellbook", FabricEntityTypeBuilder.create(SpawnGroup.MISC, SpellbookEntity::new) EntityType<SpellbookEntity> SPELLBOOK = register("spellbook", FabricEntityType.Builder.createMob(SpellbookEntity::new, SpawnGroup.MISC, builder -> builder
.trackRangeBlocks(200) .defaultAttributes(SpellbookEntity::createMobAttributes))
.dimensions(EntityDimensions.fixed(0.9F, 0.5F))); .maxTrackingRange(200)
EntityType<SombraEntity> SOMBRA = register("sombra", FabricEntityTypeBuilder.<SombraEntity>create(SpawnGroup.MONSTER, SombraEntity::new) .dimensions(0.9F, 0.5F));
.trackRangeBlocks(200) EntityType<SombraEntity> SOMBRA = register("sombra", FabricEntityType.Builder.<SombraEntity>createMob(SombraEntity::new, SpawnGroup.MONSTER, builder -> builder
.dimensions(EntityDimensions.changing(2F, 4F))); .defaultAttributes(SombraEntity::createMobAttributes))
EntityType<CrystalShardsEntity> CRYSTAL_SHARDS = register("crystal_shards", FabricEntityTypeBuilder.create(SpawnGroup.MISC, CrystalShardsEntity::new) .maxTrackingRange(200)
.trackRangeBlocks(100) .dimensions(2F, 4F));
.dimensions(EntityDimensions.changing(1F, 1F))); EntityType<CrystalShardsEntity> CRYSTAL_SHARDS = register("crystal_shards", EntityType.Builder.create(CrystalShardsEntity::new, SpawnGroup.MISC)
EntityType<StormCloudEntity> STORM_CLOUD = register("storm_cloud", FabricEntityTypeBuilder.create(SpawnGroup.MISC, StormCloudEntity::new) .maxTrackingRange(100)
.trackRangeBlocks(200) .dimensions(1F, 1F));
.dimensions(EntityDimensions.changing(20F, 20F))); EntityType<StormCloudEntity> STORM_CLOUD = register("storm_cloud", EntityType.Builder.create(StormCloudEntity::new, SpawnGroup.MISC)
EntityType<AirBalloonEntity> AIR_BALLOON = register("air_balloon", FabricEntityTypeBuilder.create(SpawnGroup.MISC, AirBalloonEntity::new) .maxTrackingRange(200)
.trackRangeBlocks(1000) .dimensions(20F, 20F));
.dimensions(EntityDimensions.changing(2.5F, 0.1F))); EntityType<AirBalloonEntity> AIR_BALLOON = register("air_balloon", FabricEntityType.Builder.createMob(AirBalloonEntity::new, SpawnGroup.MISC, builder -> builder
EntityType<LootBugEntity> LOOT_BUG = register("loot_bug", FabricEntityTypeBuilder.create(SpawnGroup.MONSTER, LootBugEntity::new) .defaultAttributes(FlyingEntity::createMobAttributes))
.trackRangeChunks(8) .maxTrackingRange(1000)
.dimensions(EntityDimensions.fixed(0.8F, 0.6F))); .dimensions(2.5F, 0.1F));
EntityType<TentacleEntity> TENTACLE = register("ignominious_vine", FabricEntityTypeBuilder.<TentacleEntity>create(SpawnGroup.MISC, TentacleEntity::new) EntityType<LootBugEntity> LOOT_BUG = register("loot_bug", FabricEntityType.Builder.createMob(LootBugEntity::new, SpawnGroup.MONSTER, builder -> builder
.trackRangeChunks(8) .defaultAttributes(LootBugEntity::createSilverfishAttributes))
.dimensions(EntityDimensions.fixed(0.8F, 0.8F))); .maxTrackingRange(8)
EntityType<IgnominiousBulbEntity> IGNOMINIOUS_BULB = register("ignominious_bulb", FabricEntityTypeBuilder.<IgnominiousBulbEntity>create(SpawnGroup.MISC, IgnominiousBulbEntity::new) .dimensions(0.8F, 0.6F));
.trackRangeChunks(8) EntityType<TentacleEntity> TENTACLE = register("ignominious_vine", EntityType.Builder.<TentacleEntity>create(TentacleEntity::new, SpawnGroup.MISC)
.dimensions(EntityDimensions.fixed(3, 2))); .maxTrackingRange(8)
EntityType<SpecterEntity> SPECTER = register("specter", FabricEntityTypeBuilder.createMob().spawnGroup(SpawnGroup.MONSTER).entityFactory(SpecterEntity::new) .dimensions(0.8F, 0.8F));
.spawnRestriction(Location.ON_GROUND, Type.MOTION_BLOCKING_NO_LEAVES, HostileEntity::canSpawnInDark) EntityType<IgnominiousBulbEntity> IGNOMINIOUS_BULB = register("ignominious_bulb", FabricEntityType.Builder.<IgnominiousBulbEntity>createMob(IgnominiousBulbEntity::new, SpawnGroup.MISC, builder -> builder
.fireImmune() .defaultAttributes(IgnominiousBulbEntity::createMobAttributes))
.maxTrackingRange(8)
.dimensions(3, 2));
EntityType<SpecterEntity> SPECTER = register("specter", FabricEntityType.Builder.createMob(SpecterEntity::new, SpawnGroup.MONSTER, builder -> builder
.spawnRestriction(SpawnLocationTypes.ON_GROUND, Type.MOTION_BLOCKING_NO_LEAVES, HostileEntity::canSpawnInDark)
.defaultAttributes(SpecterEntity::createAttributes))
.makeFireImmune()
.spawnableFarFromPlayer() .spawnableFarFromPlayer()
.dimensions(EntityDimensions.fixed(1, 2))); .dimensions(1, 2));
EntityType<MimicEntity> MIMIC = register("mimic", FabricEntityTypeBuilder.create(SpawnGroup.MONSTER, MimicEntity::new) EntityType<MimicEntity> MIMIC = register("mimic", FabricEntityType.Builder.createMob(MimicEntity::new, SpawnGroup.MONSTER, builder -> builder
.fireImmune() .defaultAttributes(MimicEntity::createMobAttributes))
.makeFireImmune()
.disableSummon() .disableSummon()
.dimensions(EntityDimensions.changing(0.875F, 0.875F))); .dimensions(0.875F, 0.875F));
static <T extends Entity> EntityType<T> register(String name, FabricEntityTypeBuilder<T> builder) { static <T extends Entity> EntityType<T> register(String name, EntityType.Builder<T> builder) {
EntityType<T> type = builder.build(); EntityType<T> type = builder.build();
return Registry.register(Registries.ENTITY_TYPE, Unicopia.id(name), type); return Registry.register(Registries.ENTITY_TYPE, Unicopia.id(name), type);
} }
static void bootstrap() { static void bootstrap() {
FabricDefaultAttributeRegistry.register(BUTTERFLY, ButterflyEntity.createButterflyAttributes());
FabricDefaultAttributeRegistry.register(SPELLBOOK, SpellbookEntity.createMobAttributes());
FabricDefaultAttributeRegistry.register(TWITTERMITE, FairyEntity.createMobAttributes());
FabricDefaultAttributeRegistry.register(AIR_BALLOON, FlyingEntity.createMobAttributes());
FabricDefaultAttributeRegistry.register(SOMBRA, SombraEntity.createMobAttributes());
FabricDefaultAttributeRegistry.register(FRIENDLY_CREEPER, FriendlyCreeperEntity.createCreeperAttributes());
FabricDefaultAttributeRegistry.register(LOOT_BUG, LootBugEntity.createSilverfishAttributes());
FabricDefaultAttributeRegistry.register(IGNOMINIOUS_BULB, IgnominiousBulbEntity.createMobAttributes());
FabricDefaultAttributeRegistry.register(SPECTER, SpecterEntity.createAttributes());
FabricDefaultAttributeRegistry.register(MIMIC, MimicEntity.createMobAttributes());
if (!Unicopia.getConfig().disableButterflySpawning.get()) { if (!Unicopia.getConfig().disableButterflySpawning.get()) {
final Predicate<BiomeSelectionContext> butterflySpawnable = BiomeSelectors.foundInOverworld() final Predicate<BiomeSelectionContext> butterflySpawnable = BiomeSelectors.foundInOverworld()
.and(ctx -> ctx.getBiome().hasPrecipitation() && ctx.getBiome().getTemperature() > 0.15F); .and(ctx -> ctx.getBiome().hasPrecipitation() && ctx.getBiome().getTemperature() > 0.15F);
@ -133,39 +129,5 @@ public interface UEntities {
UTradeOffers.bootstrap(); UTradeOffers.bootstrap();
EntityBehaviour.bootstrap(); EntityBehaviour.bootstrap();
UEntityAttributes.bootstrap(); UEntityAttributes.bootstrap();
Paintings.bootstrap();
}
interface Paintings {
Set<PaintingVariant> REGISTRY = new HashSet<>();
private static void register(String id, int width, int height) {
REGISTRY.add(Registry.register(
Registries.PAINTING_VARIANT,
RegistryKey.of(RegistryKeys.PAINTING_VARIANT, Unicopia.id(id)),
new PaintingVariant(16 * width, 16 * height)
));
}
static void bootstrap() {
register("bloom", 2, 1);
register("chicken", 2, 1);
register("bells", 2, 1);
register("crystal", 3, 3);
register("harmony", 3, 3);
register("equality", 2, 4);
register("solar", 2, 4);
register("lunar", 2, 4);
register("platinum", 2, 4);
register("hurricane", 2, 4);
register("pudding", 2, 4);
register("terra", 2, 4);
register("equestria", 2, 4);
register("blossom", 2, 3);
register("shadow", 2, 3);
}
} }
} }

View file

@ -3,25 +3,26 @@ package com.minelittlepony.unicopia.entity.mob;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.jamieswhiteshirt.reachentityattributes.ReachEntityAttributes;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import net.minecraft.entity.attribute.ClampedEntityAttribute; import net.minecraft.entity.attribute.ClampedEntityAttribute;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
public interface UEntityAttributes { public interface UEntityAttributes {
List<EntityAttribute> REGISTRY = new ArrayList<>(); List<EntityAttribute> REGISTRY = new ArrayList<>();
EntityAttribute EXTENDED_REACH_DISTANCE = ReachEntityAttributes.REACH; RegistryEntry<EntityAttribute> EXTENDED_REACH_DISTANCE = EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE;
EntityAttribute EXTENDED_ATTACK_DISTANCE = ReachEntityAttributes.ATTACK_RANGE; RegistryEntry<EntityAttribute> EXTENDED_ATTACK_DISTANCE = EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE;
EntityAttribute EXTRA_MINING_SPEED = register("earth.mining_speed", new ClampedEntityAttribute("player.miningSpeed", 1, 0, 5).setTracked(true)); RegistryEntry<EntityAttribute> EXTRA_MINING_SPEED = register("earth.mining_speed", new ClampedEntityAttribute("player.miningSpeed", 1, 0, 5).setTracked(true));
EntityAttribute ENTITY_GRAVITY_MODIFIER = register("player.gravity", (new EntityAttribute("player.gravityModifier", 1) {}).setTracked(true)); RegistryEntry<EntityAttribute> ENTITY_GRAVITY_MODIFIER = register("player.gravity", (new EntityAttribute("player.gravityModifier", 1) {}).setTracked(true));
private static EntityAttribute register(String name, EntityAttribute attribute) { private static RegistryEntry<EntityAttribute> register(String name, EntityAttribute attribute) {
REGISTRY.add(attribute); REGISTRY.add(attribute);
return Registry.register(Registries.ATTRIBUTE, Unicopia.id(name), attribute); return Registry.registerReference(Registries.ATTRIBUTE, Unicopia.id(name), attribute);
} }
static void bootstrap() {} static void bootstrap() {}

View file

@ -17,6 +17,7 @@ import net.minecraft.block.Blocks;
import net.minecraft.block.SideShapeType; import net.minecraft.block.SideShapeType;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.BlockTags;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
@ -161,7 +162,7 @@ public class Acrobatics implements Tickable, NbtSerialisable {
public void startHanging(BlockPos pos) { public void startHanging(BlockPos pos) {
boolean inverted = pony.getPhysics().isGravityNegative(); boolean inverted = pony.getPhysics().isGravityNegative();
hangingPos.set(Optional.of(pos)); hangingPos.set(Optional.of(pos));
entity.teleport(pos.getX() + 0.5, pos.getY() - (inverted ? 0 : 1), pos.getZ() + 0.5); entity.setPosition(pos.getX() + 0.5, pos.getY() - (inverted ? 0 : 1), pos.getZ() + 0.5);
entity.setVelocity(Vec3d.ZERO); entity.setVelocity(Vec3d.ZERO);
entity.setSneaking(false); entity.setSneaking(false);
entity.stopFallFlying(); entity.stopFallFlying();
@ -196,14 +197,14 @@ public class Acrobatics implements Tickable, NbtSerialisable {
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
compound.putInt("ticksHanging", ticksHanging); compound.putInt("ticksHanging", ticksHanging);
BLOCK_POS.writeOptional("hangingPosition", compound, getHangingPosition()); BLOCK_POS.writeOptional("hangingPosition", compound, getHangingPosition(), lookup);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
ticksHanging = compound.getInt("ticksHanging"); ticksHanging = compound.getInt("ticksHanging");
hangingPos.set(NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound)); hangingPos.set(NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound, lookup));
} }
} }

View file

@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.util.Copyable;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import com.minelittlepony.unicopia.util.Tickable; import com.minelittlepony.unicopia.util.Tickable;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyable<ManaContainer> { class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyable<ManaContainer> {
@ -44,13 +45,13 @@ class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyabl
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
bars.forEach((key, bar) -> compound.put(key, bar.toNBT())); bars.forEach((key, bar) -> compound.put(key, bar.toNBT(lookup)));
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
bars.forEach((key, bar) -> bar.fromNBT(compound.getCompound(key))); bars.forEach((key, bar) -> bar.fromNBT(compound.getCompound(key), lookup));
} }
@Override @Override
@ -227,13 +228,13 @@ class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyabl
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
compound.putFloat("shadow", trailingValue); compound.putFloat("shadow", trailingValue);
compound.putFloat("value", get()); compound.putFloat("value", get());
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
trailingValue = compound.getFloat("shadow"); trailingValue = compound.getFloat("shadow");
load(compound.getFloat("value")); load(compound.getFloat("value"));
} }

View file

@ -1,10 +1,10 @@
package com.minelittlepony.unicopia.entity.player; package com.minelittlepony.unicopia.entity.player;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
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.entity.effect.EffectUtils; import com.minelittlepony.unicopia.entity.effect.EffectUtils;
import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.effect.UEffects;
@ -12,58 +12,59 @@ import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import com.minelittlepony.unicopia.util.Tickable; import com.minelittlepony.unicopia.util.Tickable;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributeModifier.Operation; import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;
public class PlayerAttributes implements Tickable { public class PlayerAttributes implements Tickable {
private final static List<ToggleableAttribute> ATTRIBUTES = List.of( private final static List<ToggleableAttribute> ATTRIBUTES = List.of(
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("777a5505-521e-480b-b9d5-6ea54f259564"), "Earth Pony Strength", 0.6, Operation.MULTIPLY_TOTAL), new EntityAttributeModifier(Unicopia.id("earth_pony_strength"), 0.6, Operation.ADD_MULTIPLIED_TOTAL),
List.of(EntityAttributes.GENERIC_ATTACK_DAMAGE, EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE), List.of(EntityAttributes.GENERIC_ATTACK_DAMAGE, EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE),
pony -> pony.getCompositeRace().canUseEarth() pony -> pony.getCompositeRace().canUseEarth()
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("79e269a8-03e8-b9d5-5853-e25fdcf6706d"), "Earth Pony Knockback Resistance", 6, Operation.ADDITION), new EntityAttributeModifier(Unicopia.id("earth_pony_knockback_resistance"), 6, Operation.ADD_VALUE),
List.of(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE), List.of(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE),
pony -> pony.getCompositeRace().canUseEarth() && pony.asEntity().isSneaking() pony -> pony.getCompositeRace().canUseEarth() && pony.asEntity().isSneaking()
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("9fc9e269-152e-0b48-9bd5-564a546e59f2"), "Earth Pony Mining Speed", 0.5, Operation.MULTIPLY_TOTAL), new EntityAttributeModifier(Unicopia.id("earth_pony_mining_speed"), 0.5, Operation.ADD_MULTIPLIED_TOTAL),
List.of(UEntityAttributes.EXTRA_MINING_SPEED), List.of(UEntityAttributes.EXTRA_MINING_SPEED),
pony -> pony.getCompositeRace().canUseEarth() pony -> pony.getCompositeRace().canUseEarth()
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("9e2699fc-3b8d-4f71-9d2d-fb92ee19b4f7"), "Pegasus Speed", 0.2, Operation.MULTIPLY_TOTAL), new EntityAttributeModifier(Unicopia.id("pegasus_speed"), 0.2, Operation.ADD_MULTIPLIED_TOTAL),
List.of(EntityAttributes.GENERIC_MOVEMENT_SPEED, EntityAttributes.GENERIC_ATTACK_SPEED), List.of(EntityAttributes.GENERIC_MOVEMENT_SPEED, EntityAttributes.GENERIC_ATTACK_SPEED),
pony -> pony.getCompositeRace().canFly() && !pony.getCompositeRace().includes(Race.HIPPOGRIFF) pony -> pony.getCompositeRace().canFly() && !pony.getCompositeRace().includes(Race.HIPPOGRIFF)
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("707b50a8-03e8-40f4-8553-ecf67025fd6d"), "Pegasus Reach", 1.5, Operation.ADDITION), new EntityAttributeModifier(Unicopia.id("pegasus_reach"), 1.5, Operation.ADD_VALUE),
List.of(UEntityAttributes.EXTENDED_REACH_DISTANCE), List.of(UEntityAttributes.EXTENDED_REACH_DISTANCE),
pony -> pony.getCompositeRace().canFly() && !pony.getCompositeRace().includes(Race.HIPPOGRIFF) pony -> pony.getCompositeRace().canFly() && !pony.getCompositeRace().includes(Race.HIPPOGRIFF)
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("9e2699fc-3b8d-4f71-92dd-bef19b92e4f7"), "Hippogriff Speed", 0.1, Operation.MULTIPLY_TOTAL), new EntityAttributeModifier(Unicopia.id("hippogriff_speed"), 0.1, Operation.ADD_MULTIPLIED_TOTAL),
List.of(EntityAttributes.GENERIC_MOVEMENT_SPEED, EntityAttributes.GENERIC_ATTACK_SPEED), List.of(EntityAttributes.GENERIC_MOVEMENT_SPEED, EntityAttributes.GENERIC_ATTACK_SPEED),
pony -> pony.getCompositeRace().includes(Race.HIPPOGRIFF) pony -> pony.getCompositeRace().includes(Race.HIPPOGRIFF)
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("707b50a8-03e8-40f4-5853-fc7e0f625d6d"), "Hippogriff Reach", 1.3, Operation.ADDITION), new EntityAttributeModifier(Unicopia.id("hippogriff_reach"), 1.3, Operation.ADD_VALUE),
List.of(UEntityAttributes.EXTENDED_REACH_DISTANCE), List.of(UEntityAttributes.EXTENDED_REACH_DISTANCE),
pony -> pony.getCompositeRace().includes(Race.HIPPOGRIFF) pony -> pony.getCompositeRace().includes(Race.HIPPOGRIFF)
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("79e269a8-03e8-b9d5-5853-e25fdcf6706e"), "Kirin Knockback Vulnerability", -2, Operation.ADDITION), new EntityAttributeModifier(Unicopia.id("kirin_knockback_vulneravility"), -2, Operation.ADD_VALUE),
List.of(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE), List.of(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE),
pony -> pony.getCompositeRace().includes(Race.KIRIN) pony -> pony.getCompositeRace().includes(Race.KIRIN)
), ),
new ToggleableAttribute( new ToggleableAttribute(
new EntityAttributeModifier(UUID.fromString("4991fde9-c685-4930-bbd2-d7a228728bfe"), "Kirin Rage Speed", 0.7, Operation.MULTIPLY_TOTAL), new EntityAttributeModifier(Unicopia.id("kirin_rage"), 0.7, Operation.ADD_MULTIPLIED_TOTAL),
List.of(EntityAttributes.GENERIC_MOVEMENT_SPEED, List.of(EntityAttributes.GENERIC_MOVEMENT_SPEED,
EntityAttributes.GENERIC_ATTACK_SPEED, EntityAttributes.GENERIC_ATTACK_SPEED,
EntityAttributes.GENERIC_ATTACK_DAMAGE, EntityAttributes.GENERIC_ATTACK_DAMAGE,
@ -74,10 +75,10 @@ public class PlayerAttributes implements Tickable {
) )
); );
public static final UUID HEALTH_SWAPPING_MODIFIER_ID = UUID.fromString("7b93803e-4b25-11ed-951e-00155d43e0a2"); public static final Identifier HEALTH_SWAPPING_MODIFIER_ID = Unicopia.id("health_swap");
public static EntityAttributeModifier healthChange(float addition) { public static EntityAttributeModifier healthChange(float addition) {
return new EntityAttributeModifier(HEALTH_SWAPPING_MODIFIER_ID, "Health Swap", addition, Operation.ADDITION); return new EntityAttributeModifier(HEALTH_SWAPPING_MODIFIER_ID, addition, Operation.ADD_VALUE);
} }
private final Pony pony; private final Pony pony;
@ -92,20 +93,10 @@ public class PlayerAttributes implements Tickable {
EffectUtils.applyStatusEffect(pony.asEntity(), UEffects.FORTIFICATION, pony.getCompositeRace().canUseEarth() && pony.asEntity().isSneaking()); EffectUtils.applyStatusEffect(pony.asEntity(), UEffects.FORTIFICATION, pony.getCompositeRace().canUseEarth() && pony.asEntity().isSneaking());
} }
record ToggleableAttribute(EntityAttributeModifier modifier, List<EntityAttribute> attributes, Predicate<Pony> test) { record ToggleableAttribute(EntityAttributeModifier modifier, List<RegistryEntry<EntityAttribute>> attributes, Predicate<Pony> test) {
public void update(Pony pony) { public void update(Pony pony) {
boolean enable = test.test(pony); boolean enable = test.test(pony);
attributes.forEach(attribute -> { attributes.forEach(attribute -> pony.applyAttributeModifier(attribute, modifier, true, enable));
EntityAttributeInstance instance = pony.asEntity().getAttributeInstance(attribute);
if (enable) {
if (!instance.hasModifier(modifier)) {
instance.addPersistentModifier(modifier);
}
} else {
instance.removeModifier(modifier.getId());
}
});
} }
} }
} }

View file

@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.util.NbtSerialisable;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtList;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.TypedActionResult;
@ -71,7 +72,7 @@ public class PlayerCharmTracker implements NbtSerialisable, Copyable<PlayerCharm
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
NbtList equippedSpells = new NbtList(); NbtList equippedSpells = new NbtList();
for (CustomisedSpellType<?> spell : handSpells) { for (CustomisedSpellType<?> spell : handSpells) {
equippedSpells.add(spell.toNbt(new NbtCompound())); equippedSpells.add(spell.toNbt(new NbtCompound()));
@ -80,7 +81,7 @@ public class PlayerCharmTracker implements NbtSerialisable, Copyable<PlayerCharm
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
if (compound.contains("handSpells", NbtElement.LIST_TYPE)) { if (compound.contains("handSpells", NbtElement.LIST_TYPE)) {
NbtList list = compound.getList("handSpells", NbtElement.COMPOUND_TYPE); NbtList list = compound.getList("handSpells", NbtElement.COMPOUND_TYPE);
for (int i = 0; i < handSpells.length && i < list.size(); i++) { for (int i = 0; i < handSpells.length && i < list.size(); i++) {

View file

@ -47,6 +47,9 @@ import net.minecraft.nbt.NbtCompound;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.util.math.*; import net.minecraft.util.math.*;
@ -521,7 +524,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
ChargeableItem.consumeEnergy(stack.stack(), energyConsumed); ChargeableItem.consumeEnergy(stack.stack(), energyConsumed);
if (entity.getWorld().random.nextInt(damageInterval) == 0) { if (entity.getWorld().random.nextInt(damageInterval) == 0) {
stack.stack().damage(minDamage + entity.getWorld().random.nextInt(50), (LivingEntity)entity, stack.breakStatusSender()); stack.stack().damage(minDamage + entity.getWorld().random.nextInt(50), (ServerWorld)entity.getWorld(), (ServerPlayerEntity)entity, stack.breakStatusSender());
} }
if (!lastFlightType.canFly()) { if (!lastFlightType.canFly()) {
@ -871,8 +874,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
super.toNBT(compound); super.toNBT(compound, lookup);
compound.putBoolean("isFlying", isFlyingSurvival); compound.putBoolean("isFlying", isFlyingSurvival);
compound.putBoolean("isCancelled", isCancelled); compound.putBoolean("isCancelled", isCancelled);
compound.putBoolean("isFlyingEither", isFlyingEither); compound.putBoolean("isFlyingEither", isFlyingEither);
@ -882,8 +885,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
super.fromNBT(compound); super.fromNBT(compound, lookup);
isFlyingSurvival = compound.getBoolean("isFlying"); isFlyingSurvival = compound.getBoolean("isFlying");
isCancelled = compound.getBoolean("isCancelled"); isCancelled = compound.getBoolean("isCancelled");
isFlyingEither = compound.getBoolean("isFlyingEither"); isFlyingEither = compound.getBoolean("isFlyingEither");

View file

@ -42,6 +42,8 @@ import com.google.common.collect.Streams;
import com.minelittlepony.common.util.animation.Interpolator; import com.minelittlepony.common.util.animation.Interpolator;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.PotionContentsComponent;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments; import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.*; import net.minecraft.entity.*;
@ -55,8 +57,8 @@ import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.potion.PotionUtil; import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.potion.Potions; import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.DamageTypeTags; import net.minecraft.registry.tag.DamageTypeTags;
import net.minecraft.registry.tag.FluidTags; import net.minecraft.registry.tag.FluidTags;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
@ -650,13 +652,13 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
return false; return false;
} }
public int getImplicitEnchantmentLevel(Enchantment enchantment, int initial) { public int getImplicitEnchantmentLevel(RegistryEntry<Enchantment> enchantment, int initial) {
if ((enchantment == Enchantments.AQUA_AFFINITY if ((enchantment == Enchantments.AQUA_AFFINITY
|| enchantment == Enchantments.DEPTH_STRIDER || enchantment == Enchantments.DEPTH_STRIDER
|| enchantment == Enchantments.LUCK_OF_THE_SEA || enchantment == Enchantments.LUCK_OF_THE_SEA
|| enchantment == Enchantments.LURE) && getCompositeRace().includes(Race.SEAPONY)) { || enchantment == Enchantments.LURE) && getCompositeRace().includes(Race.SEAPONY)) {
return MathHelper.clamp(initial + 3, enchantment.getMinLevel(), enchantment.getMaxLevel()); return MathHelper.clamp(initial + 3, enchantment.value().getMinLevel(), enchantment.value().getMaxLevel());
} }
return initial; return initial;
@ -742,7 +744,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
} }
if (getObservedSpecies() == Race.KIRIN if (getObservedSpecies() == Race.KIRIN
&& (stack.isIn(UTags.Items.COOLS_OFF_KIRINS) || PotionUtil.getPotion(stack) == Potions.WATER)) { && (stack.isIn(UTags.Items.COOLS_OFF_KIRINS) || stack.get(DataComponentTypes.POTION_CONTENTS) == PotionContentsComponent.DEFAULT)) {
getMagicalReserves().getCharge().multiply(0.5F); getMagicalReserves().getCharge().multiply(0.5F);
getSpellSlot().get(SpellType.RAGE).ifPresent(RageAbilitySpell::setExtenguishing); getSpellSlot().get(SpellType.RAGE).ifPresent(RageAbilitySpell::setExtenguishing);
} }
@ -824,34 +826,34 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound, WrapperLookup lookup) {
compound.put("mana", mana.toNBT()); compound.put("mana", mana.toNBT(lookup));
compound.putInt("levels", levels.get()); compound.putInt("levels", levels.get());
compound.putInt("corruption", corruption.get()); compound.putInt("corruption", corruption.get());
super.toNBT(compound); super.toNBT(compound, lookup);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
levels.set(compound.getInt("levels")); levels.set(compound.getInt("levels"));
corruption.set(compound.getInt("corruption")); corruption.set(compound.getInt("corruption"));
mana.fromNBT(compound.getCompound("mana")); mana.fromNBT(compound.getCompound("mana"), lookup);
super.fromNBT(compound); super.fromNBT(compound, lookup);
} }
@Override @Override
public void toSyncronisedNbt(NbtCompound compound) { public void toSyncronisedNbt(NbtCompound compound, WrapperLookup lookup) {
super.toSyncronisedNbt(compound); super.toSyncronisedNbt(compound, lookup);
compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString()); compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString());
compound.putString("suppressedSpecies", Race.REGISTRY.getId(getSuppressedRace()).toString()); compound.putString("suppressedSpecies", Race.REGISTRY.getId(getSuppressedRace()).toString());
compound.putFloat("magicExhaustion", magicExhaustion); compound.putFloat("magicExhaustion", magicExhaustion);
compound.putInt("ticksInSun", ticksInSun); compound.putInt("ticksInSun", ticksInSun);
compound.putBoolean("hasShades", hasShades); compound.putBoolean("hasShades", hasShades);
compound.put("acrobatics", acrobatics.toNBT()); compound.put("acrobatics", acrobatics.toNBT(lookup));
compound.put("powers", powers.toNBT()); compound.put("powers", powers.toNBT(lookup));
compound.put("gravity", gravity.toNBT()); compound.put("gravity", gravity.toNBT(lookup));
compound.put("charms", charms.toNBT()); compound.put("charms", charms.toNBT(lookup));
compound.put("discoveries", discoveries.toNBT()); compound.put("discoveries", discoveries.toNBT(lookup));
compound.putInt("ticksInvulnerable", ticksInvulnerable); compound.putInt("ticksInvulnerable", ticksInvulnerable);
compound.putInt("ticksMetamorphising", ticksMetamorphising); compound.putInt("ticksMetamorphising", ticksMetamorphising);
NbtCompound progress = new NbtCompound(); NbtCompound progress = new NbtCompound();
@ -862,15 +864,15 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
} }
@Override @Override
public void fromSynchronizedNbt(NbtCompound compound) { public void fromSynchronizedNbt(NbtCompound compound, WrapperLookup lookup) {
super.fromSynchronizedNbt(compound); super.fromSynchronizedNbt(compound, lookup);
setSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN)); setSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN));
setSuppressedRace(Race.fromName(compound.getString("suppressedSpecies"), Race.UNSET)); setSuppressedRace(Race.fromName(compound.getString("suppressedSpecies"), Race.UNSET));
powers.fromNBT(compound.getCompound("powers")); powers.fromNBT(compound.getCompound("powers"), lookup);
gravity.fromNBT(compound.getCompound("gravity")); gravity.fromNBT(compound.getCompound("gravity"), lookup);
charms.fromNBT(compound.getCompound("charms")); charms.fromNBT(compound.getCompound("charms"), lookup);
discoveries.fromNBT(compound.getCompound("discoveries")); discoveries.fromNBT(compound.getCompound("discoveries"), lookup);
acrobatics.fromNBT(compound.getCompound("acrobatics")); acrobatics.fromNBT(compound.getCompound("acrobatics"), lookup);
magicExhaustion = compound.getFloat("magicExhaustion"); magicExhaustion = compound.getFloat("magicExhaustion");
ticksInvulnerable = compound.getInt("ticksInvulnerable"); ticksInvulnerable = compound.getInt("ticksInvulnerable");
ticksInSun = compound.getInt("ticksInSun"); ticksInSun = compound.getInt("ticksInSun");

View file

@ -14,11 +14,11 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.PlayerListEntry; import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.render.entity.PlayerModelPart;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerModelPart;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.GameMode; import net.minecraft.world.GameMode;

View file

@ -8,6 +8,7 @@ import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableMultimap;
import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.block.UBlocks;
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
import com.minelittlepony.unicopia.entity.*; import com.minelittlepony.unicopia.entity.*;
@ -28,9 +29,10 @@ import it.unimi.dsi.fastutil.objects.Object2FloatMaps;
import it.unimi.dsi.fastutil.objects.Object2FloatOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2FloatOpenHashMap;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.EnchantmentEffectComponentTypes;
import net.minecraft.component.type.ItemEnchantmentsComponent;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments; import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.*; import net.minecraft.entity.*;
@ -41,10 +43,14 @@ import net.minecraft.entity.decoration.ItemFrameEntity;
import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.effect.StatusEffects;
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.TooltipType;
import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.DamageTypeTags; import net.minecraft.registry.tag.DamageTypeTags;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
@ -58,8 +64,8 @@ import net.minecraft.world.World;
import net.minecraft.world.World.ExplosionSourceType; import net.minecraft.world.World.ExplosionSourceType;
public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackable, ItemImpl.ClingyItem, ItemImpl.GroundTickCallback { public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackable, ItemImpl.ClingyItem, ItemImpl.GroundTickCallback {
private static final UUID EFFECT_UUID = UUID.fromString("c0a870f5-99ef-4716-a23e-f320ee834b26"); private static final Identifier EFFECT_ID = Unicopia.id("alicorn_amulet_modifiers");
private static final Object2FloatMap<EntityAttribute> EFFECT_SCALES = Object2FloatMaps.unmodifiable(new Object2FloatOpenHashMap<>(Map.of( private static final Object2FloatMap<RegistryEntry<EntityAttribute>> EFFECT_SCALES = Object2FloatMaps.unmodifiable(new Object2FloatOpenHashMap<>(Map.of(
EntityAttributes.GENERIC_ATTACK_DAMAGE, 0.2F, EntityAttributes.GENERIC_ATTACK_DAMAGE, 0.2F,
EntityAttributes.GENERIC_ATTACK_KNOCKBACK, 0.05F, EntityAttributes.GENERIC_ATTACK_KNOCKBACK, 0.05F,
EntityAttributes.GENERIC_ATTACK_SPEED, 0.2F, EntityAttributes.GENERIC_ATTACK_SPEED, 0.2F,
@ -67,16 +73,16 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
EntityAttributes.GENERIC_ARMOR, 0.01F EntityAttributes.GENERIC_ARMOR, 0.01F
))); )));
private static final Float2ObjectFunction<EntityAttributeModifier> EFFECT_FACTORY = v -> { private static final Float2ObjectFunction<EntityAttributeModifier> EFFECT_FACTORY = v -> {
return new EntityAttributeModifier(EFFECT_UUID, "Alicorn Amulet Modifier", v, EntityAttributeModifier.Operation.ADDITION); return new EntityAttributeModifier(EFFECT_ID, v, EntityAttributeModifier.Operation.ADD_VALUE);
}; };
public AlicornAmuletItem(FabricItemSettings settings) { public AlicornAmuletItem(Item.Settings settings) {
super(settings, 0, ImmutableMultimap.of()); super(settings, 0);
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
@Override @Override
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext tooltipContext) { public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip, TooltipType type) {
Pony iplayer = Pony.of(MinecraftClient.getInstance().player); Pony iplayer = Pony.of(MinecraftClient.getInstance().player);
if (iplayer != null) { if (iplayer != null) {
@ -177,7 +183,7 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
public static void updateAttributes(Living<?> wearer, float effectScale) { public static void updateAttributes(Living<?> wearer, float effectScale) {
EFFECT_SCALES.object2FloatEntrySet().forEach(entry -> { EFFECT_SCALES.object2FloatEntrySet().forEach(entry -> {
wearer.updateAttributeModifier(EFFECT_UUID, entry.getKey(), entry.getFloatValue() * effectScale, EFFECT_FACTORY, false); wearer.updateAttributeModifier(EFFECT_ID, entry.getKey(), entry.getFloatValue() * effectScale, EFFECT_FACTORY, false);
}); });
} }
@ -248,10 +254,10 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
// bind to the player after 3 days // bind to the player after 3 days
if (daysAttached >= 3 && !pony.asEntity().isCreative()) { if (daysAttached >= 3 && !pony.asEntity().isCreative()) {
stack = living.getArmour().getEquippedStack(TrinketsDelegate.NECKLACE).stack(); stack = living.getArmour().getEquippedStack(TrinketsDelegate.NECKLACE).stack();
if (stack.getItem() == this && !EnchantmentHelper.hasBindingCurse(stack)) { if (stack.getItem() == this && !EnchantmentHelper.hasAnyEnchantmentsWith(stack, EnchantmentEffectComponentTypes.PREVENT_ARMOR_CHANGE)) {
pony.playSound(USounds.ITEM_ALICORN_AMULET_HALLUCINATION, 3, 1); pony.playSound(USounds.ITEM_ALICORN_AMULET_HALLUCINATION, 3, 1);
stack = stack.copy(); stack = stack.copy();
stack.addEnchantment(Enchantments.BINDING_CURSE, 1); stack.addEnchantment(pony.entryFor(Enchantments.BINDING_CURSE), 1);
pony.getArmour().equipStack(TrinketsDelegate.NECKLACE, stack); pony.getArmour().equipStack(TrinketsDelegate.NECKLACE, stack);
} }
} }
@ -330,7 +336,8 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
if ((entity.age / 1000) % 10 == 0 && entity.age % 50 == 0) { if ((entity.age / 1000) % 10 == 0 && entity.age % 50 == 0) {
for (Entity target : VecHelper.findInRange(entity, entity.getWorld(), entity.getPos(), 10, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR)) { for (Entity target : VecHelper.findInRange(entity, entity.getWorld(), entity.getPos(), 10, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR)) {
for (ItemStack equipment : target.getItemsEquipped()) { if (target instanceof LivingEntity l) {
for (ItemStack equipment : l.getEquippedItems()) {
if (equipment.getItem() == UItems.GROGARS_BELL) { if (equipment.getItem() == UItems.GROGARS_BELL) {
ChargeableItem chargeable = (ChargeableItem)UItems.GROGARS_BELL; ChargeableItem chargeable = (ChargeableItem)UItems.GROGARS_BELL;
if (chargeable.hasCharge(equipment)) { if (chargeable.hasCharge(equipment)) {
@ -344,4 +351,5 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
} }
} }
} }
}
} }

View file

@ -2,49 +2,42 @@ package com.minelittlepony.unicopia.item;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import com.minelittlepony.unicopia.Unicopia;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext; import net.minecraft.component.type.AttributeModifiersComponent;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ArmorMaterials; import net.minecraft.item.ArmorMaterials;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.text.MutableText; import net.minecraft.text.MutableText;
import net.minecraft.text.StringVisitable; import net.minecraft.text.StringVisitable;
import net.minecraft.text.Style; import net.minecraft.text.Style;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.world.World; import net.minecraft.util.Identifier;
public class AmuletItem extends WearableItem implements ChargeableItem { public class AmuletItem extends WearableItem implements ChargeableItem {
public static final Identifier AMULET_MODIFIERS_ID = Unicopia.id("amulet_modifiers");
private final int maxEnergy; private final int maxEnergy;
private final ImmutableMultimap<EntityAttribute, EntityAttributeModifier> modifiers; public AmuletItem(Item.Settings settings, int maxEnergy) {
public AmuletItem(FabricItemSettings settings, int maxEnergy) {
this(settings, maxEnergy, ImmutableMultimap.of());
}
public AmuletItem(FabricItemSettings settings, int maxEnergy, ImmutableMultimap<EntityAttribute, EntityAttributeModifier> modifiers) {
super(settings); super(settings);
this.maxEnergy = maxEnergy; this.maxEnergy = maxEnergy;
this.modifiers = modifiers; }
public AmuletItem(Item.Settings settings, int maxEnergy, AttributeModifiersComponent modifiers) {
this(settings.attributeModifiers(modifiers), maxEnergy);
} }
@Override @Override
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> list, TooltipContext tooltipContext) { 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)) {
@ -62,8 +55,8 @@ public class AmuletItem extends WearableItem implements ChargeableItem {
} }
@Override @Override
public SoundEvent getEquipSound() { public RegistryEntry<SoundEvent> getEquipSound() {
return ArmorMaterials.IRON.getEquipSound(); return ArmorMaterials.IRON.value().equipSound();
} }
@Override @Override
@ -76,11 +69,6 @@ public class AmuletItem extends WearableItem implements ChargeableItem {
return !isChargable() || stack.hasEnchantments() || ChargeableItem.getEnergy(stack) > 0; return !isChargable() || stack.hasEnchantments() || ChargeableItem.getEnergy(stack) > 0;
} }
@Override
public Multimap<EntityAttribute, EntityAttributeModifier> getAttributeModifiers(EquipmentSlot slot) {
return slot == EquipmentSlot.CHEST ? modifiers : ImmutableMultimap.of();
}
public boolean isApplicable(ItemStack stack) { public boolean isApplicable(ItemStack stack) {
return stack.getItem() == this && (!isChargable() || ChargeableItem.getEnergy(stack) > 0); return stack.getItem() == this && (!isChargable() || ChargeableItem.getEnergy(stack) > 0);
} }
@ -105,19 +93,4 @@ public class AmuletItem extends WearableItem implements ChargeableItem {
.findFirst() .findFirst()
.orElse(TrinketsDelegate.EquippedStack.EMPTY); .orElse(TrinketsDelegate.EquippedStack.EMPTY);
} }
public static class ModifiersBuilder {
private static final UUID SLOT_UUID = UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E");
private final ImmutableMultimap.Builder<EntityAttribute, EntityAttributeModifier> modifiers = new ImmutableMultimap.Builder<>();
public ModifiersBuilder add(EntityAttribute attribute, double amount) {
modifiers.put(attribute, new EntityAttributeModifier(SLOT_UUID, "Armor modifier", amount, EntityAttributeModifier.Operation.ADDITION));
return this;
}
public ImmutableMultimap<EntityAttribute, EntityAttributeModifier> build() {
return modifiers.build();
}
}
} }

View file

@ -47,7 +47,7 @@ public class AppleItem {
float bob = MathHelper.sin(((float)item.getAge() + 1) / 10F + entity.uniqueOffset) * 0.1F + 0.1F; float bob = MathHelper.sin(((float)item.getAge() + 1) / 10F + entity.uniqueOffset) * 0.1F + 0.1F;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
entity.getWorld().addParticle(ParticleTypes.AMBIENT_ENTITY_EFFECT, entity.getX(), entity.getY() + bob, entity.getZ(), entity.getWorld().addParticle(ParticleTypes.EFFECT, entity.getX(), entity.getY() + bob, entity.getZ(),
entity.getWorld().random.nextGaussian() - 0.5F, entity.getWorld().random.nextGaussian() - 0.5F,
entity.getWorld().random.nextGaussian() - 0.5F, entity.getWorld().random.nextGaussian() - 0.5F,
entity.getWorld().random.nextGaussian() - 0.5F); entity.getWorld().random.nextGaussian() - 0.5F);

View file

@ -6,6 +6,7 @@ import net.minecraft.entity.projectile.FishingBobberEntity;
import net.minecraft.item.FishingRodItem; import net.minecraft.item.FishingRodItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.server.world.ServerWorld;
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;
@ -23,16 +24,13 @@ public class BaitedFishingRodItem extends FishingRodItem {
if (user.fishHook != null) { if (user.fishHook != null) {
user.fishHook.discard(); user.fishHook.discard();
ItemStack stack = user.getStackInHand(hand); ItemStack stack = user.getStackInHand(hand);
int lure = (EnchantmentHelper.getLure(stack) + 1) * 2; int lure = (int)((EnchantmentHelper.getFishingTimeReduction((ServerWorld)world, stack, user) + 1) * 20F);
int luck = (EnchantmentHelper.getLuckOfTheSea(stack) + 1) * 2; int luck = (EnchantmentHelper.getFishingLuckBonus((ServerWorld)world, stack, user) + 1) * 2;
world.spawnEntity(new FishingBobberEntity(user, world, luck, lure)); world.spawnEntity(new FishingBobberEntity(user, world, luck, lure));
} }
if (result.getValue().isOf(this)) { if (result.getValue().isOf(this)) {
ItemStack stack = Items.FISHING_ROD.getDefaultStack(); ItemStack stack = result.getValue().withItem(Items.FISHING_ROD);
if (result.getValue().hasNbt()) {
stack.setNbt(result.getValue().getNbt().copy());
}
return TypedActionResult.success(stack, world.isClient()); return TypedActionResult.success(stack, world.isClient());
} }
} }

View file

@ -42,7 +42,7 @@ public class BedsheetsItem extends Item {
FancyBedBlock.setBedPattern(world, context.getBlockPos(), pattern); FancyBedBlock.setBedPattern(world, context.getBlockPos(), pattern);
context.getStack().decrement(1); context.getStack().decrement(1);
PlayerEntity player = context.getPlayer(); PlayerEntity player = context.getPlayer();
world.playSound(player, pos, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, SoundCategory.BLOCKS, 1, 1); world.playSound(player, pos, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC.value(), SoundCategory.BLOCKS, 1, 1);
return ActionResult.success(world.isClient); return ActionResult.success(world.isClient);
} }

View file

@ -1,8 +1,6 @@
package com.minelittlepony.unicopia.item; package com.minelittlepony.unicopia.item;
import java.util.List; import java.util.List;
import org.jetbrains.annotations.Nullable;
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;
@ -15,7 +13,6 @@ import com.minelittlepony.unicopia.particle.UParticles;
import com.minelittlepony.unicopia.util.VecHelper; import com.minelittlepony.unicopia.util.VecHelper;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.CreeperEntity; import net.minecraft.entity.mob.CreeperEntity;
import net.minecraft.entity.mob.IllagerEntity; import net.minecraft.entity.mob.IllagerEntity;
@ -23,6 +20,7 @@ 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.text.Text;
@ -44,12 +42,12 @@ public class BellItem extends Item implements ChargeableItem {
} }
@Override @Override
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> list, TooltipContext tooltipContext) { public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> list, TooltipType type) {
list.add(Text.translatable(getTranslationKey() + ".charges", (int)Math.floor(ChargeableItem.getEnergy(stack)), getMaxCharge())); list.add(Text.translatable(getTranslationKey() + ".charges", (int)Math.floor(ChargeableItem.getEnergy(stack)), getMaxCharge()));
} }
@Override @Override
public int getMaxUseTime(ItemStack stack) { public int getMaxUseTime(ItemStack stack, LivingEntity user) {
return 3000; return 3000;
} }
@ -109,7 +107,7 @@ public class BellItem extends Item implements ChargeableItem {
Living.getOrEmpty(userEntity).ifPresent(user -> { Living.getOrEmpty(userEntity).ifPresent(user -> {
user.getTarget().ifPresent(living -> { user.getTarget().ifPresent(living -> {
float maxUseTime = getMaxUseTime(stack); float maxUseTime = getMaxUseTime(stack, userEntity);
float progress = (maxUseTime - remainingUseTicks) / maxUseTime; float progress = (maxUseTime - remainingUseTicks) / maxUseTime;
if (tickDraining(user, living, stack, progress)) { if (tickDraining(user, living, stack, progress)) {

View file

@ -2,21 +2,15 @@ package com.minelittlepony.unicopia.item;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity; import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
import com.minelittlepony.unicopia.item.component.UDataComponentTypes;
import com.minelittlepony.unicopia.item.group.MultiItem; import com.minelittlepony.unicopia.item.group.MultiItem;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.nbt.NbtElement;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.world.World;
public class ButterflyItem extends Item implements MultiItem { public class ButterflyItem extends Item implements MultiItem {
@ -30,22 +24,17 @@ public class ButterflyItem extends Item implements MultiItem {
} }
@Override @Override
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext context) { public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip, TooltipType type) {
tooltip.add(Text.literal(getVariant(stack).name()).formatted(Formatting.LIGHT_PURPLE)); tooltip.add(Text.literal(getVariant(stack).name()).formatted(Formatting.LIGHT_PURPLE));
} }
public static ButterflyEntity.Variant getVariant(ItemStack stack) { public static ButterflyEntity.Variant getVariant(ItemStack stack) {
NbtCompound nbt = stack.getNbt(); return stack.getOrDefault(UDataComponentTypes.BUTTERFLY_VARIANT, ButterflyEntity.Variant.BUTTERFLY);
if (nbt == null || !nbt.contains("variant", NbtElement.STRING_TYPE)) {
return ButterflyEntity.Variant.BUTTERFLY;
}
String variant = nbt.getString("variant");
return ButterflyEntity.Variant.byName(variant);
} }
public static ItemStack setVariant(ItemStack stack, ButterflyEntity.Variant variant) { public static ItemStack setVariant(ItemStack stack, ButterflyEntity.Variant variant) {
if (stack.isOf(UItems.BUTTERFLY)) { if (stack.isOf(UItems.BUTTERFLY)) {
stack.getOrCreateNbt().putString("variant", variant.name().toLowerCase(Locale.ROOT)); stack.set(UDataComponentTypes.BUTTERFLY_VARIANT, variant);
} }
return stack; return stack;
} }

View file

@ -52,13 +52,7 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art
private static ItemStack fill(ItemStack stack) { private static ItemStack fill(ItemStack stack) {
Item item = ITEM_MAP.get().getOrDefault(stack.getItem(), stack.getItem()); Item item = ITEM_MAP.get().getOrDefault(stack.getItem(), stack.getItem());
if (item == stack.getItem()) { return item == stack.getItem() ? stack : stack.withItem(item);
return stack;
}
ItemStack newStack = item.getDefaultStack();
newStack.setNbt(stack.getNbt());
newStack.setCount(stack.getCount());
return newStack;
} }
public CrystalHeartItem(Settings settings) { public CrystalHeartItem(Settings settings) {

View file

@ -75,7 +75,7 @@ public class CuringJokeItem extends BlockItem {
static boolean removeEffect(LivingEntity user) { static boolean removeEffect(LivingEntity user) {
return user.getStatusEffects().stream().filter(effect -> { return user.getStatusEffects().stream().filter(effect -> {
return !effect.getEffectType().isBeneficial(); return !effect.getEffectType().value().isBeneficial();
}).findAny().filter(effect -> { }).findAny().filter(effect -> {
user.removeStatusEffect(effect.getEffectType()); user.removeStatusEffect(effect.getEffectType());
return true; return true;
@ -114,6 +114,6 @@ public class CuringJokeItem extends BlockItem {
return InventoryUtil.stream(owner.getInventory()); return InventoryUtil.stream(owner.getInventory());
} }
return StreamSupport.stream(entity.getItemsEquipped().spliterator(), false); return StreamSupport.stream(entity.getEquippedItems().spliterator(), false);
} }
} }

View file

@ -1,12 +1,11 @@
package com.minelittlepony.unicopia.item; package com.minelittlepony.unicopia.item;
import java.util.UUID;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.server.world.DragonBreathStore; import com.minelittlepony.unicopia.server.world.DragonBreathStore;
import com.minelittlepony.unicopia.server.world.UnicopiaWorldProperties; import com.minelittlepony.unicopia.server.world.UnicopiaWorldProperties;
import net.minecraft.component.DataComponentTypes;
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;
@ -27,13 +26,13 @@ public class DragonBreathScrollItem extends Item {
ItemStack stack = player.getStackInHand(hand); ItemStack stack = player.getStackInHand(hand);
ItemStack payload = player.getStackInHand(hand == Hand.MAIN_HAND ? Hand.OFF_HAND : Hand.MAIN_HAND); ItemStack payload = player.getStackInHand(hand == Hand.MAIN_HAND ? Hand.OFF_HAND : Hand.MAIN_HAND);
if (payload.isEmpty() || !stack.hasCustomName()) { if (payload.isEmpty() || !stack.contains(DataComponentTypes.CUSTOM_NAME)) {
return TypedActionResult.fail(stack); return TypedActionResult.fail(stack);
} }
stack.split(1); stack.split(1);
if (!world.isClient) { if (!world.isClient) {
String recipient = stack.getName().getString(); String recipient = stack.get(DataComponentTypes.CUSTOM_NAME).getString();
UCriteria.SEND_DRAGON_BREATH.triggerSent(player, payload, recipient, (counterName, count) -> { UCriteria.SEND_DRAGON_BREATH.triggerSent(player, payload, recipient, (counterName, count) -> {
if (count == 1 && "dings_on_celestias_head".equals(counterName)) { if (count == 1 && "dings_on_celestias_head".equals(counterName)) {
UnicopiaWorldProperties properties = UnicopiaWorldProperties.forWorld((ServerWorld)world); UnicopiaWorldProperties properties = UnicopiaWorldProperties.forWorld((ServerWorld)world);
@ -46,9 +45,4 @@ public class DragonBreathScrollItem extends Item {
player.playSound(USounds.ITEM_DRAGON_BREATH_SCROLL_USE, 1, 1); player.playSound(USounds.ITEM_DRAGON_BREATH_SCROLL_USE, 1, 1);
return TypedActionResult.consume(stack); return TypedActionResult.consume(stack);
} }
public static ItemStack setRecipient(ItemStack stack, UUID recipient) {
stack.getOrCreateSubNbt("recipient").putUuid("id", recipient);
return stack;
}
} }

View file

@ -1,15 +1,16 @@
package com.minelittlepony.unicopia.item; package com.minelittlepony.unicopia.item;
import com.minelittlepony.unicopia.item.component.UDataComponentTypes;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
public interface GlowableItem { public interface GlowableItem {
default boolean isGlowing(ItemStack stack) { static boolean isGlowing(ItemStack stack) {
NbtCompound tag = stack.getSubNbt("display"); Boolean glowing = stack.get(UDataComponentTypes.GLOWING);
return tag != null && tag.getBoolean("glowing"); return glowing != null && glowing;
} }
default void setGlowing(ItemStack stack, boolean glowing) { static void setGlowing(ItemStack stack, boolean glowing) {
stack.getOrCreateSubNbt("display").putBoolean("glowing", glowing); stack.set(UDataComponentTypes.GLOWING, glowing);
} }
} }

View file

@ -4,8 +4,6 @@ import java.util.List;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
@ -14,12 +12,13 @@ import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity; import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity;
import net.minecraft.client.item.TooltipContext; import net.minecraft.component.type.AttributeModifierSlot;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.component.type.AttributeModifiersComponent;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
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.TooltipType;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
@ -30,16 +29,14 @@ public class HorseShoeItem extends HeavyProjectileItem {
private final float projectileInnacuracy; private final float projectileInnacuracy;
private final float baseProjectileSpeed; private final float baseProjectileSpeed;
private final Multimap<EntityAttribute, EntityAttributeModifier> attributeModifiers; public HorseShoeItem(Item.Settings settings, float projectileDamage, float projectileInnacuracy, float baseProjectileSpeed) {
super(settings.attributeModifiers(AttributeModifiersComponent.builder().add(
public HorseShoeItem(Settings settings, float projectileDamage, float projectileInnacuracy, float baseProjectileSpeed) { UEntityAttributes.EXTENDED_ATTACK_DISTANCE,
super(settings, projectileDamage); new EntityAttributeModifier(PolearmItem.ATTACK_RANGE_MODIFIER_ID, -3F, EntityAttributeModifier.Operation.ADD_VALUE),
AttributeModifierSlot.MAINHAND
).build()), projectileDamage);
this.projectileInnacuracy = projectileInnacuracy; this.projectileInnacuracy = projectileInnacuracy;
this.baseProjectileSpeed = baseProjectileSpeed; this.baseProjectileSpeed = baseProjectileSpeed;
ImmutableMultimap.Builder<EntityAttribute, EntityAttributeModifier> builder = ImmutableMultimap.builder();
builder.put(UEntityAttributes.EXTENDED_ATTACK_DISTANCE, new EntityAttributeModifier(PolearmItem.ATTACK_RANGE_MODIFIER_ID, "Weapon modifier", -3F, EntityAttributeModifier.Operation.ADDITION));
attributeModifiers = builder.build();
} }
@Override @Override
@ -48,7 +45,7 @@ public class HorseShoeItem extends HeavyProjectileItem {
} }
@Override @Override
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext context) { public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip, TooltipType type) {
float degradation = (stack.getDamage() / (float)stack.getMaxDamage()); float degradation = (stack.getDamage() / (float)stack.getMaxDamage());
float inaccuracy = projectileInnacuracy + degradation * 30; float inaccuracy = projectileInnacuracy + degradation * 30;
tooltip.add(Text.empty()); tooltip.add(Text.empty());
@ -97,15 +94,6 @@ public class HorseShoeItem extends HeavyProjectileItem {
@Override @Override
public SoundEvent getThrowSound(ItemStack stack) { public SoundEvent getThrowSound(ItemStack stack) {
return USounds.Vanilla.ITEM_TRIDENT_THROW; return USounds.Vanilla.ITEM_TRIDENT_THROW.value();
} }
@Override
public Multimap<EntityAttribute, EntityAttributeModifier> getAttributeModifiers(EquipmentSlot slot) {
if (slot == EquipmentSlot.MAINHAND) {
return attributeModifiers;
}
return super.getAttributeModifiers(slot);
}
} }

View file

@ -2,14 +2,22 @@ package com.minelittlepony.unicopia.item;
import java.util.Optional; 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 { public interface ItemDuck extends ItemConvertible, ItemImpl.TickableItem, DietView.Holder {
@Deprecated
void setFoodComponent(FoodComponent food); 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(); Optional<FoodComponent> getOriginalFoodComponent();
@Deprecated
default void resetFoodComponent() { default void resetFoodComponent() {
setFoodComponent(getOriginalFoodComponent().orElse(null)); setFoodComponent(getOriginalFoodComponent().orElse(null));
} }

View file

@ -1,64 +1,43 @@
package com.minelittlepony.unicopia.item; package com.minelittlepony.unicopia.item;
import java.util.UUID; import java.util.List;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.UTags;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import com.minelittlepony.unicopia.item.enchantment.CustomEnchantableItem;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.enchantment.Enchantment; import net.minecraft.component.DataComponentTypes;
import net.minecraft.enchantment.Enchantments; import net.minecraft.component.type.AttributeModifierSlot;
import net.minecraft.component.type.ToolComponent;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.*; import net.minecraft.entity.attribute.*;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class PolearmItem extends SwordItem implements CustomEnchantableItem { public class PolearmItem extends ToolItem {
static final UUID ATTACK_RANGE_MODIFIER_ID = UUID.fromString("A7B3659C-AA74-469C-963A-09A391DCAA0F"); static final Identifier ATTACK_RANGE_MODIFIER_ID = Unicopia.id("attack_reach_modifier");
private final Multimap<EntityAttribute, EntityAttributeModifier> attributeModifiers;
private final int attackRange;
public PolearmItem(ToolMaterial material, int damage, float speed, int range, Settings settings) { public PolearmItem(ToolMaterial material, int damage, float speed, int range, Settings settings) {
super(material, damage, speed, settings); super(material, settings.attributeModifiers(SwordItem.createAttributeModifiers(material, damage, speed).with(
this.attackRange = range; UEntityAttributes.EXTENDED_REACH_DISTANCE, new EntityAttributeModifier(ATTACK_RANGE_MODIFIER_ID, range, EntityAttributeModifier.Operation.ADD_VALUE), AttributeModifierSlot.MAINHAND
ImmutableMultimap.Builder<EntityAttribute, EntityAttributeModifier> builder = ImmutableMultimap.builder(); ).with(
builder.putAll(super.getAttributeModifiers(EquipmentSlot.MAINHAND)); UEntityAttributes.EXTENDED_ATTACK_DISTANCE, new EntityAttributeModifier(ATTACK_RANGE_MODIFIER_ID, range, EntityAttributeModifier.Operation.ADD_VALUE), AttributeModifierSlot.MAINHAND
builder.put(UEntityAttributes.EXTENDED_REACH_DISTANCE, new EntityAttributeModifier(ATTACK_RANGE_MODIFIER_ID, "Weapon modifier", attackRange, EntityAttributeModifier.Operation.ADDITION)); )).component(DataComponentTypes.TOOL, createToolComponent()));
builder.put(UEntityAttributes.EXTENDED_ATTACK_DISTANCE, new EntityAttributeModifier(ATTACK_RANGE_MODIFIER_ID, "Weapon modifier", attackRange, EntityAttributeModifier.Operation.ADDITION));
attributeModifiers = builder.build();
} }
@Override private static ToolComponent createToolComponent() {
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) { return new ToolComponent(
if (state.isOf(Blocks.COBWEB)) { List.of(ToolComponent.Rule.ofAlwaysDropping(List.of(Blocks.COBWEB), 15.0F), ToolComponent.Rule.of(UTags.Blocks.POLEARM_MINEABLE, 1.5F)), 1.0F, 2
return 1; );
}
return super.getMiningSpeedMultiplier(stack, state);
}
@Override
public boolean isSuitableFor(BlockState state) {
return state.isIn(UTags.Blocks.POLEARM_MINEABLE);
}
@Override
public Multimap<EntityAttribute, EntityAttributeModifier> getAttributeModifiers(EquipmentSlot slot) {
if (slot == EquipmentSlot.MAINHAND) {
return attributeModifiers;
}
return super.getAttributeModifiers(slot);
} }
@Override @Override
public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker) { public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker) {
boolean tooNear = target.distanceTo(attacker) <= 2; boolean tooNear = target.distanceTo(attacker) <= 2;
stack.damage(tooNear ? 4 : 1, attacker, e -> e.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
target.takeKnockback(0.15, attacker.getX() - target.getX(), attacker.getZ() - target.getZ()); target.takeKnockback(0.15, attacker.getX() - target.getX(), attacker.getZ() - target.getZ());
Living.updateVelocity(target); Living.updateVelocity(target);
if (tooNear) { if (tooNear) {
@ -70,7 +49,13 @@ public class PolearmItem extends SwordItem implements CustomEnchantableItem {
} }
@Override @Override
public boolean isAcceptableEnchant(ItemStack stack, Enchantment enchantment) { public boolean canMine(BlockState state, World world, BlockPos pos, PlayerEntity miner) {
return enchantment != Enchantments.SWEEPING; return !miner.isCreative();
}
@Override
public void postDamageEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) {
boolean tooNear = target.distanceTo(attacker) <= 2;
stack.damage(tooNear ? 4 : 1, attacker, EquipmentSlot.MAINHAND);
} }
} }

Some files were not shown because too many files have changed in this diff Show more