diff --git a/gradle.properties b/gradle.properties index bdcf52b..dddb649 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,7 @@ loader_version_range=[2,) mod_id=l2core mod_name=L2Core mod_license=LGPL-2.1 -mod_version=3.0.6 +mod_version=3.0.7-pre4 mod_group_id=dev.xkmc mod_authors=lcy0x1 mod_description=Core Library mod for all L2 mods diff --git a/src/main/java/dev/xkmc/l2core/base/entity/BaseEntity.java b/src/main/java/dev/xkmc/l2core/base/entity/BaseEntity.java new file mode 100644 index 0000000..e473b3c --- /dev/null +++ b/src/main/java/dev/xkmc/l2core/base/entity/BaseEntity.java @@ -0,0 +1,46 @@ +package dev.xkmc.l2core.base.entity; + +import dev.xkmc.l2serial.serialization.codec.PacketCodec; +import dev.xkmc.l2serial.serialization.codec.TagCodec; +import dev.xkmc.l2serial.serialization.marker.SerialClass; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; +import net.neoforged.neoforge.entity.IEntityWithComplexSpawn; + +import javax.annotation.ParametersAreNonnullByDefault; + +@SerialClass +public abstract class BaseEntity extends Entity implements IEntityWithComplexSpawn { + + public BaseEntity(EntityType type, Level world) { + super(type, world); + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + var dat = new TagCodec(registryAccess()).toTag(new CompoundTag(), this); + if (dat != null) tag.put("auto-serial", dat); + } + + @Override + protected void readAdditionalSaveData(CompoundTag tag) { + if (!tag.contains("auto-serial")) return; + new TagCodec(registryAccess()).fromTag(tag.getCompound("auto-serial"), this.getClass(), this); + } + + @Override + public void writeSpawnData(RegistryFriendlyByteBuf buffer) { + PacketCodec.to(buffer, this); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + public void readSpawnData(RegistryFriendlyByteBuf data) { + PacketCodec.from(data, (Class) this.getClass(), this); + } + +} diff --git a/src/main/java/dev/xkmc/l2core/base/entity/SyncedData.java b/src/main/java/dev/xkmc/l2core/base/entity/SyncedData.java new file mode 100644 index 0000000..0e4bb92 --- /dev/null +++ b/src/main/java/dev/xkmc/l2core/base/entity/SyncedData.java @@ -0,0 +1,116 @@ +package dev.xkmc.l2core.base.entity; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.UUIDUtil; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializer; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public class SyncedData { + + public static final Serializer INT; + public static final Serializer BLOCK_POS; + public static final Serializer> UUID; + + static { + INT = new Serializer<>(EntityDataSerializers.INT, Codec.INT); + BLOCK_POS = new Serializer<>(EntityDataSerializers.BLOCK_POS, BlockPos.CODEC); + UUID = new Serializer<>(EntityDataSerializers.OPTIONAL_UUID, UUIDUtil.CODEC.xmap(Optional::of, Optional::get)); + } + + private final Definer cls; + + private final List> list = new ArrayList<>(); + + public SyncedData(Definer cls) { + this.cls = cls; + } + + public void register(SynchedEntityData.Builder data) { + for (Data entry : list) { + entry.register(data); + } + } + + public EntityDataAccessor define(Serializer ser, T init, @Nullable String name) { + Data data = new Data<>(ser, init, name); + list.add(data); + return data.data; + } + + public void write(RegistryAccess pvd, CompoundTag tag, SynchedEntityData entityData) { + for (Data entry : list) { + entry.write(pvd, tag, entityData); + } + } + + public void read(RegistryAccess pvd, CompoundTag tag, SynchedEntityData entityData) { + for (Data entry : list) { + entry.read(pvd, tag, entityData); + } + } + + private class Data { + + private final Serializer ser; + private final EntityDataAccessor data; + private final T init; + private final String name; + + private Data(Serializer ser, T init, @Nullable String name) { + this.ser = ser; + this.data = cls.define(ser.ser()); + this.init = init; + this.name = name; + } + + private void register(SynchedEntityData.Builder data) { + data.define(this.data, this.init); + } + + public void write(RegistryAccess pvd, CompoundTag tag, SynchedEntityData entityData) { + if (name == null) return; + Tag ans = ser.write(pvd, entityData.get(data)); + if (ans != null) tag.put(name, ans); + } + + public void read(RegistryAccess pvd, CompoundTag tag, SynchedEntityData entityData) { + if (name == null) return; + var in = tag.get(name); + entityData.set(data, Optional.ofNullable(in).map(e -> ser.read(pvd, e)).orElse(init)); + } + } + + public record Serializer(EntityDataSerializer ser, Codec codec) { + + @Nullable + public Tag write(RegistryAccess pvd, T t) { + return codec.encodeStart(pvd.createSerializationContext(NbtOps.INSTANCE), t).getOrThrow(); + } + + @Nullable + public T read(RegistryAccess pvd, Tag tag) { + return codec.decode(pvd.createSerializationContext(NbtOps.INSTANCE), tag).getOrThrow().getFirst(); + } + + } + + public interface Definer { + + EntityDataAccessor define(EntityDataSerializer ser); + + } + +} diff --git a/src/main/java/dev/xkmc/l2core/base/entity/package-info.java b/src/main/java/dev/xkmc/l2core/base/entity/package-info.java new file mode 100644 index 0000000..b2cca45 --- /dev/null +++ b/src/main/java/dev/xkmc/l2core/base/entity/package-info.java @@ -0,0 +1,8 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault + +package dev.xkmc.l2core.base.entity; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java b/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java index a0b3243..3fca142 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java @@ -46,6 +46,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.TreeMap; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -122,7 +123,7 @@ public class L2Registrate extends AbstractRegistrate { Registries.PARTICLE_TYPE, sup)).register(); RegistrateDistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> OneTimeEventReceiver.addModListener(this, RegisterParticleProvidersEvent.class, - event -> pvd.get().register(event, ans.get()))); + event -> pvd.get().register().accept(event, ans.get()))); return new Val.Registrate<>(ans); } @@ -270,19 +271,19 @@ public class L2Registrate extends AbstractRegistrate { public interface ParticleSupplier { - static ParticleSupplier provider(ParticleProvider pvd) { - return (event, type) -> event.registerSpecial(type, pvd); + static ParticleSupplier provider(NonNullSupplier> pvd) { + return () -> (event, type) -> event.registerSpecial(type, pvd.get()); } - static ParticleSupplier sprite(ParticleProvider.Sprite pvd) { - return (event, type) -> event.registerSprite(type, pvd); + static ParticleSupplier sprite(NonNullSupplier> pvd) { + return () -> (event, type) -> event.registerSprite(type, pvd.get()); } - static ParticleSupplier spriteSet(ParticleEngine.SpriteParticleRegistration pvd) { - return (event, type) -> event.registerSpriteSet(type, pvd); + static ParticleSupplier spriteSet(NonNullSupplier> pvd) { + return () -> (event, type) -> event.registerSpriteSet(type, pvd.get()); } - void register(RegisterParticleProvidersEvent event, ParticleType type); + BiConsumer> register(); } diff --git a/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java b/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java index b07949b..21cf45d 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java @@ -3,9 +3,10 @@ package dev.xkmc.l2core.init.reg.simple; import com.mojang.serialization.Codec; import dev.xkmc.l2core.util.DCStack; import dev.xkmc.l2serial.serialization.codec.CodecAdaptor; +import dev.xkmc.l2serial.util.Wrappers; +import net.minecraft.core.UUIDUtil; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentSerialization; @@ -17,6 +18,9 @@ import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; import java.util.UUID; public record DCReg(DeferredRegister> reg) { @@ -31,11 +35,24 @@ public record DCReg(DeferredRegister> reg) { return new DCValImpl<>(reg.register(id, builder::build)); } + public DCVal> list(String id, Codec codec, StreamCodec stream, boolean cache) { + var builder = DataComponentType.>builder() + .persistent(codec.listOf()) + .networkSynchronized(stream.apply(Wrappers.cast(ByteBufCodecs.list()))); + if (cache) builder.cacheEncoding(); + return new DCValImpl<>(reg.register(id, builder::build)); + } + public DCVal reg(String id, Class cls, boolean cache) { var cdc = new CodecAdaptor<>(cls); return reg(id, cdc, cdc.toNetwork(), cache); } + public DCVal> list(String id, Class cls, boolean cache) { + var cdc = new CodecAdaptor<>(cls); + return reg(id, cdc.listOf(), ByteBufCodecs.list().apply(cdc.toNetwork()), cache); + } + public DCVal unit(String id) { return reg(id, Unit.CODEC, StreamCodec.unit(Unit.INSTANCE), false); } @@ -56,9 +73,17 @@ public record DCReg(DeferredRegister> reg) { return reg(id, Codec.STRING, ByteBufCodecs.STRING_UTF8, false); } + public DCVal loc(String id) { + return reg(id, ResourceLocation.CODEC, ResourceLocation.STREAM_CODEC, false); + } + public DCVal uuid(String id) { - return reg(id, Codec.STRING.xmap(UUID::fromString, UUID::toString), - StreamCodec.of((b, e) -> FriendlyByteBuf.writeUUID(b, e), b -> FriendlyByteBuf.readUUID(b)), true); + return reg(id, UUIDUtil.CODEC, UUIDUtil.STREAM_CODEC, true); + } + + public DCVal> uuidSet(String id) { + return reg(id, UUIDUtil.CODEC_LINKED_SET, UUIDUtil.STREAM_CODEC.apply( + ByteBufCodecs.collection(LinkedHashSet::newLinkedHashSet)), true); } public DCVal stack(String id) { diff --git a/src/main/java/dev/xkmc/l2core/serial/advancements/CriterionBuilder.java b/src/main/java/dev/xkmc/l2core/serial/advancements/CriterionBuilder.java index c46c3e6..dc66fd2 100644 --- a/src/main/java/dev/xkmc/l2core/serial/advancements/CriterionBuilder.java +++ b/src/main/java/dev/xkmc/l2core/serial/advancements/CriterionBuilder.java @@ -15,6 +15,7 @@ import net.neoforged.neoforge.common.conditions.ICondition; import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class CriterionBuilder implements IAdvBuilder { @@ -71,6 +72,10 @@ public class CriterionBuilder implements IAdvBuilder { new EnchantmentPredicate(enchantment, MinMaxBounds.Ints.ANY)))))); } + public static CriterionBuilder player(PlayerTrigger trigger) { + return one(trigger.createCriterion(new PlayerTrigger.TriggerInstance(Optional.empty()))); + } + public static CriterionBuilder one(Criterion instance) { return new CriterionBuilder(RequirementsStrategy.AND).add(instance); }