diff --git a/src/main/java/net/frozenblock/lib/gravity/api/GravityAPI.java b/src/main/java/net/frozenblock/lib/gravity/api/GravityAPI.java index e729c3beb..dbd6b501b 100644 --- a/src/main/java/net/frozenblock/lib/gravity/api/GravityAPI.java +++ b/src/main/java/net/frozenblock/lib/gravity/api/GravityAPI.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceKey; import net.minecraft.world.entity.Entity; @@ -96,22 +98,56 @@ public static Optional getAffectingGravityBelt(List be return optionalGravityBelt; } - public record GravityBelt(double minY, double maxY, boolean renderBottom, boolean renderTop, GravityFunction function) { + public record GravityBelt(double minY, double maxY, boolean renderBottom, boolean renderTop, T function) { public boolean affectsPosition(double y) { return y >= minY && y < maxY; } - protected double getGravity(@Nullable Entity entity, double y) { + private double getGravity(@Nullable Entity entity, double y) { if (this.affectsPosition(y)) { return this.function.get(entity, y); } return 1.0; } + + public static Codec> codec(SerializableGravityFunction gravityFunction) { + return RecordCodecBuilder.create(instance -> + instance.group( + Codec.DOUBLE.fieldOf("minY").forGetter(GravityBelt::minY), + Codec.DOUBLE.fieldOf("maxY").forGetter(GravityBelt::maxY), + Codec.BOOL.fieldOf("renderBottom").forGetter(GravityBelt::renderBottom), + Codec.BOOL.fieldOf("renderTop").forGetter(GravityBelt::renderTop), + gravityFunction.codec().fieldOf("gravityFunction").forGetter(belt -> belt.function() instanceof SerializableGravityFunction abs ? (T) abs : null) + ).apply(instance, GravityBelt::new) + ); + } } + public record AbsoluteGravityFunction(double gravity) implements SerializableGravityFunction { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> + instance.group( + Codec.DOUBLE.fieldOf("gravity").forGetter(AbsoluteGravityFunction::gravity) + ).apply(instance, AbsoluteGravityFunction::new) + ); + + @Override + public double get(@Nullable Entity entity, double y) { + return gravity(); + } + + @Override + public Codec codec() { + return CODEC; + } + } + @FunctionalInterface public interface GravityFunction { double get(@Nullable Entity entity, double y); } + + public interface SerializableGravityFunction extends GravityFunction { + Codec codec(); + } } diff --git a/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java b/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java index d3aac5b4b..dc21b7450 100644 --- a/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java +++ b/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java @@ -59,7 +59,7 @@ public void onInitialize() { } - GravityAPI.register(BuiltinDimensionTypes.OVERWORLD, new GravityAPI.GravityBelt(300, 319, true, true, (entity, y) -> 0.1)); + GravityAPI.register(BuiltinDimensionTypes.OVERWORLD, new GravityAPI.GravityBelt<>(300, 319, true, true, new GravityAPI.AbsoluteGravityFunction(0.1))); assert GravityAPI.calculateGravity(BuiltinDimensionTypes.OVERWORLD, 300) == 0.1; //StructurePoolElementIdReplacements.resourceLocationReplacements.put(new ResourceLocation("ancient_city/city_center/city_center_1"), id("ancient_city/city_center/city_center_2")); //StructurePoolElementIdReplacements.resourceLocationReplacements.put(new ResourceLocation("ancient_city/city_center/city_center_2"), id("ancient_city/city_center/city_center_2"));