mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +01:00
Updating to 1.21 (part 3)
This commit is contained in:
parent
259b0cddc4
commit
433149cc99
139 changed files with 1446 additions and 1531 deletions
|
@ -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");
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 -> {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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) -> {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
));
|
));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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() {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())));
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue