diff --git a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/PipelineBiomeProvider.java b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/PipelineBiomeProvider.java index c045c905a0..f6704e9cde 100644 --- a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/PipelineBiomeProvider.java +++ b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/PipelineBiomeProvider.java @@ -83,8 +83,8 @@ public Biome getBiome(int x, int y, int z, long seed) { public Biome getBiome(int x, int z, long seed) { - x += mutator.getSample(seed + 1, x, z) * noiseAmp; - z += mutator.getSample(seed + 2, x, z) * noiseAmp; + x += (int) (mutator.getSample(seed + 1, x, z) * noiseAmp); + z += (int) (mutator.getSample(seed + 2, x, z) * noiseAmp); x /= resolution; z /= resolution; diff --git a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/pipeline/BiomeChunkImpl.java b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/pipeline/BiomeChunkImpl.java index 6781908969..8fa8ab651e 100644 --- a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/pipeline/BiomeChunkImpl.java +++ b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/pipeline/BiomeChunkImpl.java @@ -2,6 +2,8 @@ import java.util.List; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.biome.pipeline.api.BiomeChunk; import com.dfsek.terra.addons.biome.pipeline.api.Expander; import com.dfsek.terra.addons.biome.pipeline.api.Stage; @@ -98,7 +100,7 @@ protected static int calculateChunkOriginArrayIndex(int totalExpanderCount, List // chunk samples points on the same overall grid. // Without this, shared chunk borders (required because of adjacent cell reads) will not be identical // because points would be sampled on grids at different offsets, resulting in artifacts at borders. - return (int) Math.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval; + return FloatingPointFunctions.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval; } private static int calculateFinalGridOrigin(int totalExpanderCount, List stages) { diff --git a/common/addons/chunk-generator-layered/build.gradle.kts b/common/addons/chunk-generator-layered/build.gradle.kts new file mode 100644 index 0000000000..29e3850bca --- /dev/null +++ b/common/addons/chunk-generator-layered/build.gradle.kts @@ -0,0 +1,11 @@ +version = version("0.1.0") + +dependencies { + compileOnlyApi(project(":common:addons:manifest-addon-loader")) + api("com.dfsek", "paralithic", Versions.Libraries.paralithic) +} + +tasks.named("shadowJar") { + relocate("net.jafama", "com.dfsek.terra.addons.chunkgenerator.lib.jafama") + relocate("com.dfsek.paralithic", "com.dfsek.terra.addons.chunkgenerator.lib.paralithic") +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java new file mode 100644 index 0000000000..48a53185ab --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java @@ -0,0 +1,177 @@ +package com.dfsek.terra.addons.chunkgenerator; + +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.config.sampler.ElevationLayerSamplerTemplate; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.ElevationLayerSampler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.Supplier; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPalettePackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPredicatePackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerResolverPackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerSamplerPackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomeDefinedLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.DotProductLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.PlatformAirLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.SimpleLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.AdjacentPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.SimplePointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CubePointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CuboidPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.SphericalPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.DifferencePointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.ExpressionFilterPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.IntersectionPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.UnionPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.BelowLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.RangeLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerListLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.resolve.PaletteLayerResolverTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.resolve.PredicateLayerResolverTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.sampler.BiomeDefinedLayerSamplerTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.sampler.DensityLayerSamplerTemplate; +import com.dfsek.terra.addons.chunkgenerator.generation.LayeredChunkGenerator; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.addons.manifest.api.AddonInitializer; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.BaseAddon; +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; +import com.dfsek.terra.api.event.functional.FunctionalEventHandler; +import com.dfsek.terra.api.inject.annotations.Inject; +import com.dfsek.terra.api.registry.CheckedRegistry; +import com.dfsek.terra.api.util.reflection.TypeKey; +import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider; + + +public class LayeredChunkGeneratorAddon implements AddonInitializer { + + private static final Logger logger = LoggerFactory.getLogger( LayeredChunkGeneratorAddon.class); + + public static final TypeKey>> POINT_SET_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_SAMPLER_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey> LAYER_SAMPLER_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_PALETTE_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey> LAYER_PALETTE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_PREDICATE_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey> LAYER_PREDICATE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_RESOLVER_TYPE_TOKEN = new TypeKey<>() { + }; + + @Inject + private Platform platform; + + @Inject + private BaseAddon addon; + + @Override + public void initialize() { + + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(addon, ConfigPackPreLoadEvent.class) + .priority(1000) + .then(event -> { + event.getPack().applyLoader(RelationalOperator.class, + (type, o, loader, depthTracker) -> RelationalOperator.valueOf((String) o)); + + CheckedRegistry>> pointSetTypeRegistry = event.getPack().getOrCreateRegistry( + POINT_SET_TYPE_TOKEN); + pointSetTypeRegistry.register(addon.key("LIST"), SimplePointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("ADJACENT"), AdjacentPointSetTemplate::new); + + pointSetTypeRegistry.register(addon.key("SPHERE"), SphericalPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("CUBOID"), CuboidPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("CUBE"), CubePointSetTemplate::new); + + pointSetTypeRegistry.register(addon.key("UNION"), UnionPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("INTERSECTION"), IntersectionPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("DIFFERENCE"), DifferencePointSetTemplate::new); + + pointSetTypeRegistry.register(addon.key("EXPRESSION"), ExpressionFilterPointSetTemplate::new); + }) + .then(event -> { + CheckedRegistry>> samplerTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TYPE_TOKEN); + CheckedRegistry> samplerRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TOKEN); + samplerTypeRegistry.register(addon.key("DENSITY"), DensityLayerSamplerTemplate::new); + samplerTypeRegistry.register(addon.key("ELEVATION"), ElevationLayerSamplerTemplate::new); + samplerTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerSamplerTemplate::new); + + event.loadTemplate(new LayerSamplerPackConfigTemplate()).getSamplers().forEach((key, sampler) -> { + samplerRegistry.register(addon.key(key), new InstanceWrapper<>(sampler)); + }); + }) + .then(event -> { + CheckedRegistry>> predicateTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TYPE_TOKEN); + predicateTypeRegistry.register(addon.key("BELOW"), BelowLayerPredicateTemplate::new); + predicateTypeRegistry.register(addon.key("RANGE"), RangeLayerPredicateTemplate::new); + predicateTypeRegistry.register(addon.key("SAMPLER"), SamplerLayerPredicateTemplate::new); + predicateTypeRegistry.register(addon.key("SAMPLER_POINTS"), SamplerListLayerPredicateTemplate::new); + + CheckedRegistry> predicateRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TOKEN); + event.loadTemplate(new LayerPredicatePackConfigTemplate()).getPredicates().forEach((key, predicate) -> { + predicateRegistry.register(addon.key(key), new InstanceWrapper<>(predicate)); + }); + }) + .then(event -> { + CheckedRegistry>> paletteTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TYPE_TOKEN); + paletteTypeRegistry.register(addon.key("PALETTE"), SimpleLayerPaletteTemplate::new); + paletteTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerPaletteTemplate::new); + paletteTypeRegistry.register(addon.key("AIR"), () -> new PlatformAirLayerPaletteTemplate(platform)); + paletteTypeRegistry.register(addon.key("SURFACE_NORMAL"), DotProductLayerPaletteTemplate::new); + + event.getPack().applyLoader(LayerPalette.Group.class, new LayerPalette.Group.Loader(event.getPack())); + + CheckedRegistry> paletteRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TOKEN); + event.loadTemplate(new LayerPalettePackConfigTemplate()).getPalettes().forEach((key, palette) -> { + paletteRegistry.register(addon.key(key), new InstanceWrapper<>(palette)); + }); + }) + .then(event -> { + CheckedRegistry>> resolverTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_RESOLVER_TYPE_TOKEN); + resolverTypeRegistry.register(addon.key("TEST"), PredicateLayerResolverTemplate::new); + resolverTypeRegistry.register(addon.key("LAYER"), PaletteLayerResolverTemplate::new); + LayerResolver resolver = event.loadTemplate(new LayerResolverPackConfigTemplate()).getResolver(); + + event.getPack() + .getOrCreateRegistry(ChunkGeneratorProvider.class) + .register(addon.key("LAYERED"), + pack -> new LayeredChunkGenerator(platform, resolver)); + }) + .failThrough(); + + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(addon, ConfigurationLoadEvent.class) + .priority(1000) + .then(BiomeDefinedLayerPalette.injectLayerPalettes) + .then(BiomeDefinedLayerSampler.injectLayerSamplers); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPalette.java new file mode 100644 index 0000000000..bce83f62b3 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPalette.java @@ -0,0 +1,72 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.HashMap; +import java.util.Map; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.properties.Properties; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public abstract class LayerPalette { + + private final Group group; + + private final boolean resetsGroup; + + protected LayerPalette(Group group, boolean resetsGroup) { + this.group = group; + this.resetsGroup = resetsGroup; + } + + public abstract Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider); + + public final Group getGroup() { + return group; + } + + public final boolean resetsGroup() { + return resetsGroup; + } + + public static class Group { + + public static Group NO_GROUP = new Group(); + + private Group() {} + + public static Group get(String string, ConfigPack pack) { + if (!pack.getContext().has(Holder.class)) { + pack.getContext().put(new Holder(new HashMap<>())); + } + return pack.getContext().get(Holder.class).groups.computeIfAbsent(string, s -> new Group()); + } + + private record Holder(Map groups) implements Properties {} + + public static class Loader implements TypeLoader { + + private final ConfigPack pack; + + public Loader(ConfigPack pack) { + this.pack = pack; + } + + @Override + public Group load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, + DepthTracker depthTracker) throws LoadException { + String groupName = (String) o; + return Group.get(groupName, pack); + } + } + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPredicate.java new file mode 100644 index 0000000000..95c09b7989 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPredicate.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public interface LayerPredicate { + boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerResolver.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerResolver.java new file mode 100644 index 0000000000..5d0efbd069 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerResolver.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public interface LayerResolver { + LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerSampler.java new file mode 100644 index 0000000000..eb9af9334d --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerSampler.java @@ -0,0 +1,12 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public interface LayerSampler { + double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider); + ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider); + double getBlendWeight(); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/chunk/ChunkLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/chunk/ChunkLayerSampler.java new file mode 100644 index 0000000000..fdfcac0834 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/chunk/ChunkLayerSampler.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.addons.chunkgenerator.api.chunk; + +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public interface ChunkLayerSampler { + double sample(int fmX, int y, int fmZ); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPalettePackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPalettePackConfigTemplate.java new file mode 100644 index 0000000000..8485ec8366 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPalettePackConfigTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerPalettePackConfigTemplate implements ConfigTemplate { + + @Value("generation.layers") + private @Meta Map palettes; + + public Map getPalettes() { + return palettes; + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPredicatePackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPredicatePackConfigTemplate.java new file mode 100644 index 0000000000..cf4bb2172b --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPredicatePackConfigTemplate.java @@ -0,0 +1,24 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.LinkedHashMap; +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerPredicatePackConfigTemplate implements ConfigTemplate { + + @Value("generation.tests") + @Default + private @Meta Map predicates = new LinkedHashMap<>(); + + public Map getPredicates() { + return predicates; + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerResolverPackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerResolverPackConfigTemplate.java new file mode 100644 index 0000000000..71e8363afd --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerResolverPackConfigTemplate.java @@ -0,0 +1,18 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerResolverPackConfigTemplate implements ConfigTemplate { + + @Value("generation.resolver") + private @Meta LayerResolver resolver; + + public LayerResolver getResolver() { + return resolver; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerSamplerPackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerSamplerPackConfigTemplate.java new file mode 100644 index 0000000000..e811314007 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerSamplerPackConfigTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerSamplerPackConfigTemplate implements ConfigTemplate { + + @Value("generation.samplers") + private @Meta Map samplers; + + public Map getSamplers() { + return samplers; + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomeDefinedLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomeDefinedLayerPaletteTemplate.java new file mode 100644 index 0000000000..f04d81ffd7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomeDefinedLayerPaletteTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class BiomeDefinedLayerPaletteTemplate extends LayerPaletteTemplate { + + @Value("default") + @Default + private Palette defaultPalette = null; + + @Override + public LayerPalette get() { + return new BiomeDefinedLayerPalette(group, resetsGroup, defaultPalette); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java new file mode 100644 index 0000000000..400cc5dc95 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java @@ -0,0 +1,44 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.HashMap; +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.DotProductLayerPalette; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.AdjacentPointSet; +import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class DotProductLayerPaletteTemplate extends LayerPaletteTemplate { + + @Value("normal.approximation-points") + @Default + private PointSet normalApproximationPoints = new AdjacentPointSet(); + + @Value("normal.direction") + @Default + private Vector3 direction = Vector3.of(0, 1, 0); + + @Value("normal.sampler") + private InstanceWrapper sampler; + + @Value("palettes") + private Map palettes; + + @Override + public LayerPalette get() { + Map paletteMap = new HashMap<>(); + palettes.forEach((s, p) -> { + paletteMap.put(Double.parseDouble(s), p); + }); + return new DotProductLayerPalette(group, resetsGroup, normalApproximationPoints, new DoubleNavigableHolder<>(paletteMap), sampler.get(), direction); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/LayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/LayerPaletteTemplate.java new file mode 100644 index 0000000000..e925c7ef86 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/LayerPaletteTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; + + +public abstract class LayerPaletteTemplate implements ObjectTemplate { + + @Value("group") + @Default + protected LayerPalette.Group group = LayerPalette.Group.NO_GROUP; + + @Value("resets-group") + @Default + protected boolean resetsGroup = false; + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PlatformAirLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PlatformAirLayerPaletteTemplate.java new file mode 100644 index 0000000000..00e4feadf3 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PlatformAirLayerPaletteTemplate.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.SimpleLayerPalette; +import com.dfsek.terra.addons.chunkgenerator.palette.SingletonPalette; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.block.state.BlockState; + + +public class PlatformAirLayerPaletteTemplate extends LayerPaletteTemplate { + + private BlockState air; + + public PlatformAirLayerPaletteTemplate(Platform platform) { + this.air = platform.getWorldHandle().air(); + } + + @Override + public LayerPalette get() { + return new SimpleLayerPalette(group, resetsGroup, new SingletonPalette(air)); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SimpleLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SimpleLayerPaletteTemplate.java new file mode 100644 index 0000000000..43432b43cb --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SimpleLayerPaletteTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.SimpleLayerPalette; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class SimpleLayerPaletteTemplate extends LayerPaletteTemplate { + + @Value("palette") + private Palette palette; + + @Override + public LayerPalette get() { + return new SimpleLayerPalette(group, resetsGroup, palette); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/AdjacentPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/AdjacentPointSetTemplate.java new file mode 100644 index 0000000000..8379cce2e9 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/AdjacentPointSetTemplate.java @@ -0,0 +1,15 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative; + +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.AdjacentPointSet; + + +public class AdjacentPointSetTemplate implements ObjectTemplate { + + @Override + public PointSet get() { + return new AdjacentPointSet(); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/SimplePointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/SimplePointSetTemplate.java new file mode 100644 index 0000000000..825c4724e0 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/SimplePointSetTemplate.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.Set; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.SimplePointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + + +public class SimplePointSetTemplate implements ObjectTemplate { + + @Value("points") + private Set list; + + @Override + public PointSet get() { + return new SimplePointSet(list); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CubePointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CubePointSetTemplate.java new file mode 100644 index 0000000000..340dd1985d --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CubePointSetTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.CuboidPointSet; + + +public class CubePointSetTemplate implements ObjectTemplate { + + @Value("size") + private int size; + + @Override + public PointSet get() { + return new CuboidPointSet(-size, -size, -size, size, size, size); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CuboidPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CuboidPointSetTemplate.java new file mode 100644 index 0000000000..457548a2ae --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CuboidPointSetTemplate.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.CuboidPointSet; + + +public class CuboidPointSetTemplate implements ObjectTemplate { + + @Value("size.x") + private int xSize; + + @Value("size.y") + private int ySize; + + @Value("size.z") + private int zSize; + + @Override + public PointSet get() { + return new CuboidPointSet(-xSize, -ySize, -zSize, xSize, ySize, zSize); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/SphericalPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/SphericalPointSetTemplate.java new file mode 100644 index 0000000000..b822f119f7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/SphericalPointSetTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.SphericalPointSet; + + +public class SphericalPointSetTemplate implements ObjectTemplate { + + @Value("radius") + private double radius; + + @Override + public PointSet get() { + return new SphericalPointSet(radius); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/DifferencePointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/DifferencePointSetTemplate.java new file mode 100644 index 0000000000..5a381513e2 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/DifferencePointSetTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.List; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.DifferencePointSet; + + +public class DifferencePointSetTemplate implements ObjectTemplate { + + @Value("point-sets") + private List set; + + @Override + public PointSet get() { + return new DifferencePointSet(set); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/ExpressionFilterPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/ExpressionFilterPointSetTemplate.java new file mode 100644 index 0000000000..ef30b76658 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/ExpressionFilterPointSetTemplate.java @@ -0,0 +1,27 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.paralithic.eval.tokenizer.ParseException; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.ExpressionFilterPointSet; + + +public class ExpressionFilterPointSetTemplate implements ObjectTemplate { + + @Value("point-set") + private PointSet set; + + @Value("expression") + private String expression; + + @Override + public PointSet get() { + try { + return new ExpressionFilterPointSet(set, expression); + } catch(ParseException e) { + throw new RuntimeException("Failed to parse expression.", e); + } + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/IntersectionPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/IntersectionPointSetTemplate.java new file mode 100644 index 0000000000..d860287e61 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/IntersectionPointSetTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.List; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.IntersectionPointSet; + + +public class IntersectionPointSetTemplate implements ObjectTemplate { + + @Value("point-sets") + private List sets; + + @Override + public PointSet get() { + return new IntersectionPointSet(sets); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/UnionPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/UnionPointSetTemplate.java new file mode 100644 index 0000000000..2a4ba8ac97 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/UnionPointSetTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.List; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.UnionPointSet; + + +public class UnionPointSetTemplate implements ObjectTemplate { + + @Value("point-sets") + private List sets; + + @Override + public PointSet get() { + return new UnionPointSet(sets); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/BelowLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/BelowLayerPredicateTemplate.java new file mode 100644 index 0000000000..b6ec6d6c11 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/BelowLayerPredicateTemplate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.BelowLayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.config.meta.Meta; + + +public class BelowLayerPredicateTemplate implements ObjectTemplate { + + @Value("y") + private @Meta int y; + + @Override + public LayerPredicate get() { + return new BelowLayerPredicate(y); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/RangeLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/RangeLayerPredicateTemplate.java new file mode 100644 index 0000000000..37904c5411 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/RangeLayerPredicateTemplate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.RangeLayerPredicate; +import com.dfsek.terra.api.util.range.Range; + + +public class RangeLayerPredicateTemplate implements ObjectTemplate { + + @Value("range") + private Range range; + + @Override + public LayerPredicate get() { + return new RangeLayerPredicate(range); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerLayerPredicateTemplate.java new file mode 100644 index 0000000000..4477acaedc --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerLayerPredicateTemplate.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerLayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.api.config.meta.Meta; + + +public class SamplerLayerPredicateTemplate implements ObjectTemplate { + + @Value("sampler") + private @Meta InstanceWrapper sampler; + + @Value("threshold") + @Default + private double threshold = 0; + + @Value("operator") + @Default + private RelationalOperator operator = RelationalOperator.GreaterThan; + + @Override + public LayerPredicate get() { + return new SamplerLayerPredicate(sampler.get(), operator, threshold); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerListLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerListLayerPredicateTemplate.java new file mode 100644 index 0000000000..06f814f738 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerListLayerPredicateTemplate.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerListLayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.config.meta.Meta; + + +public class SamplerListLayerPredicateTemplate implements ObjectTemplate { + + @Value("sampler") + private @Meta InstanceWrapper sampler; + + @Value("point-set") + private PointSet points; + + @Value("threshold") + @Default + private double defaultThreshold = 0; + + @Value("operator") + @Default + private RelationalOperator defaultOperator = RelationalOperator.GreaterThan; + + @Override + public LayerPredicate get() { + return new SamplerListLayerPredicate(sampler.get(), defaultThreshold, defaultOperator, points); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PaletteLayerResolverTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PaletteLayerResolverTemplate.java new file mode 100644 index 0000000000..de1474dbff --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PaletteLayerResolverTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.resolve; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.addons.chunkgenerator.layer.resolve.PaletteLayerResolver; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; + + +public class PaletteLayerResolverTemplate implements ObjectTemplate { + + @Value("layer") + private InstanceWrapper palette; + + @Override + public LayerResolver get() { + return new PaletteLayerResolver(palette.get()); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PredicateLayerResolverTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PredicateLayerResolverTemplate.java new file mode 100644 index 0000000000..b143a9c839 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PredicateLayerResolverTemplate.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.addons.chunkgenerator.config.resolve; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.addons.chunkgenerator.layer.resolve.PredicateLayerResolver; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.api.config.meta.Meta; + + +public class PredicateLayerResolverTemplate implements ObjectTemplate { + + @Value("if") + private @Meta InstanceWrapper predicate; + + @Value("then") + private @Meta LayerResolver trueResolver; + + @Value("else") + private @Meta LayerResolver falseResolver; + + @Override + public PredicateLayerResolver get() { + return new PredicateLayerResolver(predicate.get(), trueResolver, falseResolver); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/BiomeDefinedLayerSamplerTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/BiomeDefinedLayerSamplerTemplate.java new file mode 100644 index 0000000000..cdfe673d49 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/BiomeDefinedLayerSamplerTemplate.java @@ -0,0 +1,23 @@ +package com.dfsek.terra.addons.chunkgenerator.config.sampler; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.seismic.type.sampler.Sampler; + + +public class BiomeDefinedLayerSamplerTemplate extends LayerSamplerTemplate { + + @Value("default") + @Default + private @Meta Sampler defaultSampler = null; + + @Override + public LayerSampler get() { + return new BiomeDefinedLayerSampler(defaultSampler, blend); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/DensityLayerSamplerTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/DensityLayerSamplerTemplate.java new file mode 100644 index 0000000000..77ed279168 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/DensityLayerSamplerTemplate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.config.sampler; + +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.DensityLayerSampler; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.seismic.type.sampler.Sampler; + + +public class DensityLayerSamplerTemplate extends LayerSamplerTemplate { + + @Value("sampler") + private @Meta Sampler sampler; + + @Override + public LayerSampler get() { + return new DensityLayerSampler(sampler, blend); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/ElevationLayerSamplerTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/ElevationLayerSamplerTemplate.java new file mode 100644 index 0000000000..e65df49a02 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/ElevationLayerSamplerTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.sampler; + +import com.dfsek.seismic.type.sampler.Sampler; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.DensityLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.ElevationLayerSampler; +import com.dfsek.terra.api.config.meta.Meta; + + +public class ElevationLayerSamplerTemplate extends LayerSamplerTemplate { + + @Value("sampler") + private @Meta Sampler sampler; + + @Override + public LayerSampler get() { + return new ElevationLayerSampler(sampler, blend); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/LayerSamplerTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/LayerSamplerTemplate.java new file mode 100644 index 0000000000..681d73b672 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/LayerSamplerTemplate.java @@ -0,0 +1,15 @@ +package com.dfsek.terra.addons.chunkgenerator.config.sampler; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties; +import com.dfsek.terra.api.config.meta.Meta; + + +public abstract class LayerSamplerTemplate implements ObjectTemplate { + @Value("blend") + protected @Meta BlendProperties blend; +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/blend/BlendPropertiesConfig.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/blend/BlendPropertiesConfig.java new file mode 100644 index 0000000000..e960a6bb1a --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/blend/BlendPropertiesConfig.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.addons.chunkgenerator.config.sampler.blend; + +import com.dfsek.seismic.type.sampler.DerivativeSampler; +import com.dfsek.tectonic.api.config.template.ValidatedConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.tectonic.api.exception.ValidationException; + +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties; +import com.dfsek.terra.api.config.meta.Meta; + + +public class BlendPropertiesConfig implements ValidatedConfigTemplate, ObjectTemplate { + @Value("density") + @Default + private @Meta int density = 3; + + @Value("weight") + @Default + private @Meta double weight = 1; + + @Override + public boolean validate() throws ValidationException { + return density > 1 && weight > 1 && density % 18 == 0; + } + + @Override + public BlendProperties get() { + return BlendProperties.of(density, weight); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/LayeredChunkGenerator.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/LayeredChunkGenerator.java new file mode 100644 index 0000000000..ae096ca6f7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/LayeredChunkGenerator.java @@ -0,0 +1,90 @@ +package com.dfsek.terra.addons.chunkgenerator.generation; + +import org.jetbrains.annotations.NotNull; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.util.Column; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; +import com.dfsek.terra.api.world.chunk.generation.ProtoChunk; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class LayeredChunkGenerator implements ChunkGenerator { + + private final Platform platform; + private final LayerResolver resolver; + + public LayeredChunkGenerator(Platform platform, LayerResolver resolver) { + this.platform = platform; + this.resolver = resolver; + } + + @Override + public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldProperties world, @NotNull BiomeProvider biomeProvider, + int chunkX, int chunkZ) { + + platform.getProfiler().push("chunk_base_layered"); + + int xOrig = (chunkX << 4); + int zOrig = (chunkZ << 4); + long seed = world.getSeed(); + + for(int x = 0; x < 16; x++) { + for(int z = 0; z < 16; z++) { + + int cx = xOrig + x; + int cz = zOrig + z; + int paletteLevel = 0; + LayerPalette previousLayerPalette = null; + Column biomeColumn = biomeProvider.getColumn(cx, cz, world); + + for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) { + + Biome biome = biomeColumn.get(y); + + LayerPalette layerPalette = resolver.resolve(cx, y, cz, world, biomeProvider); + + if (previousLayerPalette == layerPalette) { + paletteLevel++; + } else if (layerPalette.resetsGroup()) { + paletteLevel = 0; + } else if (previousLayerPalette != null && layerPalette.getGroup() == previousLayerPalette.getGroup()) { + paletteLevel++; + } else { + paletteLevel = 0; + } + previousLayerPalette = layerPalette; + + chunk.setBlock(cx, y, cz, layerPalette.get(cx, y, cz, world, biomeProvider) + .get(paletteLevel, cx, y, cz, seed)); + } + } + } + + platform.getProfiler().pop("chunk_base_layered"); + } + + @Override + public BlockState getBlock(WorldProperties world, int x, int y, int z, BiomeProvider biomeProvider) { + long seed = world.getSeed(); + Biome biome = biomeProvider.getBiome(x, y, z, seed); + int layer = 0; // Default to layer 0 for now + return resolver.resolve(x, y, z, world, biomeProvider) + .get(x, y, z, world, biomeProvider) + .get(layer, x, y, z, seed); + } + + @Override + public Palette getPalette(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + long seed = world.getSeed(); + Biome biome = biomeProvider.getBiome(x, y, z, seed); + return resolver.resolve(x, y, z, world, biomeProvider) + .get(x, y, z, world, biomeProvider); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/BiomeDefinedLayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/BiomeDefinedLayerPalette.java new file mode 100644 index 0000000000..2eb965f031 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/BiomeDefinedLayerPalette.java @@ -0,0 +1,70 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.palette; + +import com.dfsek.tectonic.api.config.template.dynamic.DynamicTemplate; +import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.terra.api.properties.Properties; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class BiomeDefinedLayerPalette extends LayerPalette { + + private final Palette defaultPalette; + + public BiomeDefinedLayerPalette(Group group, boolean resetsGroup, Palette defaultPalette) { + super(group, resetsGroup); + this.defaultPalette = defaultPalette; + } + + @Override + public Palette get(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return biomeProvider.getBiome(x, y, z, worldProperties.getSeed()).getContext().get(BiomeLayerPalettes.class).palettes().get(this); + } + + public Optional getDefaultPalette() { + return Optional.ofNullable(defaultPalette); + } + + public static Consumer injectLayerPalettes = event -> { + if(event.is(Biome.class)) { + + Map paletteFields = new HashMap<>(); + DynamicTemplate.Builder templateBuilder = DynamicTemplate.builder(); + + event.getPack().getRegistry(LayeredChunkGeneratorAddon.LAYER_PALETTE_TOKEN).forEach((registryKey, registryEntry) -> { + LayerPalette layerPalette = registryEntry.get(); + // Add template value for each BiomeDefinedLayerPalette + if (layerPalette instanceof BiomeDefinedLayerPalette biomeLayerPalette) { + String id = registryKey.getID(); + String fieldName = id + "LayerPalette"; + paletteFields.put(biomeLayerPalette, fieldName); + DynamicValue.Builder value = DynamicValue.builder("generation.layers." + id, Palette.class); + biomeLayerPalette.getDefaultPalette().ifPresent(value::setDefault); + templateBuilder.value(fieldName, value.build()); + } + }); + + DynamicTemplate layerPaletteBiomeTemplate = event.load(templateBuilder.build()); + + Map paletteMap = paletteFields.entrySet().stream().collect( + Collectors.toMap(Entry::getKey, entry -> layerPaletteBiomeTemplate.get(entry.getValue(), Palette.class))); + event.getLoadedObject(Biome.class).getContext().put(new BiomeLayerPalettes(paletteMap)); + } + }; + + public record BiomeLayerPalettes(Map palettes) implements Properties { + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java new file mode 100644 index 0000000000..1a8b0c2e64 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java @@ -0,0 +1,43 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.palette; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder; +import com.dfsek.seismic.type.vector.Vector3; +import com.dfsek.seismic.type.vector.Vector3Int; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class DotProductLayerPalette extends LayerPalette { + + private static final Logger logger = LoggerFactory.getLogger(DotProductLayerPalette.class); + private final DoubleNavigableHolder palettes; + private final Vector3Int[] samplePoints; + private final LayerSampler sampler; + private final Vector3 direction; + + public DotProductLayerPalette(Group group, boolean resetsGroup, + PointSet points, DoubleNavigableHolder palettes, LayerSampler sampler, Vector3 direction) { + super(group, resetsGroup); + this.palettes = palettes; + this.sampler = sampler; + this.direction = direction; + this.samplePoints = points.toArray(); + } + + @Override + public Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + Vector3.Mutable surfaceNormalApproximation = Vector3.Mutable.of(0, 0, 0); + for(Vector3Int point : samplePoints) { + double scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ(), world, biomeProvider); + surfaceNormalApproximation.add(point.toFloat().mutable().mulScalar(scalar)); + } + return palettes.get(direction.dot(surfaceNormalApproximation.normalize())); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/SimpleLayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/SimpleLayerPalette.java new file mode 100644 index 0000000000..ff98582302 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/SimpleLayerPalette.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.palette; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class SimpleLayerPalette extends LayerPalette { + + private final Palette palette; + + public SimpleLayerPalette(Group group, boolean resetsGroup, Palette palette) { + super(group, resetsGroup); + this.palette = palette; + } + + @Override + public Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return palette; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/BelowLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/BelowLayerPredicate.java new file mode 100644 index 0000000000..2f5f4faf38 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/BelowLayerPredicate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class BelowLayerPredicate implements LayerPredicate { + + private final int y; + + public BelowLayerPredicate(int y) { + this.y = y; + } + + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return y < this.y; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/RangeLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/RangeLayerPredicate.java new file mode 100644 index 0000000000..c08eaf6eee --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/RangeLayerPredicate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.util.range.Range; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class RangeLayerPredicate implements LayerPredicate { + + private final Range range; + + public RangeLayerPredicate(Range range) { + this.range = range; + } + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return range.isInRange(y); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerLayerPredicate.java new file mode 100644 index 0000000000..7a5a5d33a8 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerLayerPredicate.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class SamplerLayerPredicate implements LayerPredicate { + + private final LayerSampler sampler; + + private final double threshold; + + private final RelationalOperator operator; + + public SamplerLayerPredicate(LayerSampler sampler, RelationalOperator operator, double threshold) { + this.sampler = sampler; + this.operator = operator; + this.threshold = threshold; + } + + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return operator.test(sampler.sample(x, y, z, worldProperties, biomeProvider), threshold); + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerListLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerListLayerPredicate.java new file mode 100644 index 0000000000..7ec83ca35e --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerListLayerPredicate.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class SamplerListLayerPredicate implements LayerPredicate { + + private final Vector3Int[] points; + private final RelationalOperator operator; + private final LayerSampler sampler; + private final double threshold; + + public SamplerListLayerPredicate(LayerSampler sampler, double threshold, RelationalOperator operator, PointSet points) { + this.sampler = sampler; + this.threshold = threshold; + this.operator = operator; + this.points = points.toArray(); + } + + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + for (Vector3Int point : points) { + if (operator.test(sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ(), worldProperties, biomeProvider), threshold)) return true; + } + return false; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PaletteLayerResolver.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PaletteLayerResolver.java new file mode 100644 index 0000000000..8c16970e76 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PaletteLayerResolver.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.resolve; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class PaletteLayerResolver implements LayerResolver { + + private final LayerPalette palette; + + public PaletteLayerResolver(LayerPalette palette) { + this.palette = palette; + } + + @Override + public LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return palette; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PredicateLayerResolver.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PredicateLayerResolver.java new file mode 100644 index 0000000000..27bc0f363a --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PredicateLayerResolver.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.resolve; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class PredicateLayerResolver implements LayerResolver { + + private final LayerPredicate predicate; + + private final LayerResolver trueResolver; + + private final LayerResolver falseResolver; + + public PredicateLayerResolver(LayerPredicate predicate, LayerResolver trueResolver, LayerResolver falseResolver) { + this.predicate = predicate; + this.trueResolver = trueResolver; + this.falseResolver = falseResolver; + } + + @Override + public LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return predicate.test(x, y, z, world, biomeProvider) ? trueResolver.resolve(x, y, z, world, biomeProvider) : falseResolver.resolve(x, y, z, world, biomeProvider); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/BiomeDefinedLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/BiomeDefinedLayerSampler.java new file mode 100644 index 0000000000..3a80216597 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/BiomeDefinedLayerSampler.java @@ -0,0 +1,90 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler; + +import com.dfsek.tectonic.api.config.template.dynamic.DynamicTemplate; +import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue; + +import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties; + +import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.seismic.type.sampler.Sampler; +import com.dfsek.terra.api.properties.Properties; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class BiomeDefinedLayerSampler implements LayerSampler { + + private final Sampler defaultSampler; + private final BlendProperties blendProperties; + + public BiomeDefinedLayerSampler(@Nullable Sampler defaultSampler, BlendProperties blendProperties) { + this.defaultSampler = defaultSampler; + this.blendProperties = blendProperties; + } + + @Override + public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return biomeProvider.getBiome(x, y, z, world.getSeed()) + .getContext() + .get(BiomeLayerSamplers.class) + .samplers() + .get(this) + .getSample(world.getSeed(), x, y, z); + } + + @Override + public ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider) { + return null; + } + + @Override + public double getBlendWeight() { + return blendProperties.weight(); + } + + private Optional getDefaultSampler() { + return Optional.ofNullable(defaultSampler); + } + + public static Consumer injectLayerSamplers = event -> { + if(event.is(Biome.class)) { + + Map samplerFields = new HashMap<>(); + DynamicTemplate.Builder templateBuilder = DynamicTemplate.builder(); + + event.getPack().getRegistry(LayeredChunkGeneratorAddon.LAYER_SAMPLER_TOKEN).forEach((registryKey, registryEntry) -> { + LayerSampler layerSampler = registryEntry.get(); + + if (layerSampler instanceof BiomeDefinedLayerSampler biomeLayerSampler) { + String id = registryKey.getID(); + String fieldName = id + "LayerSampler"; + samplerFields.put(biomeLayerSampler, fieldName); + DynamicValue.Builder value = DynamicValue.builder("generation.samplers." + id, Sampler.class); + biomeLayerSampler.getDefaultSampler().ifPresent(value::setDefault); + templateBuilder.value(fieldName, value.build()); + } + }); + + DynamicTemplate layerSamplerBiomeTemplate = event.load(templateBuilder.build()); + + Map samplerMap = samplerFields.entrySet().stream().collect( + Collectors.toMap(Entry::getKey, entry -> layerSamplerBiomeTemplate.get(entry.getValue(), Sampler.class))); + event.getLoadedObject(Biome.class).getContext().put(new BiomeLayerSamplers(samplerMap)); + } + }; + + public record BiomeLayerSamplers(Map samplers) implements Properties { + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/DensityLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/DensityLayerSampler.java new file mode 100644 index 0000000000..f9ad2d2554 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/DensityLayerSampler.java @@ -0,0 +1,41 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler; + +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; +import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.seismic.type.sampler.Sampler; + +import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk.DensityChunkLayerSampler; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class DensityLayerSampler implements LayerSampler { + + private final Sampler sampler; + private final BlendProperties blendProperties; + + public DensityLayerSampler(Sampler sampler, BlendProperties blendProperties) { + this.sampler = sampler; + this.blendProperties = blendProperties; + } + + @Override + public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + //TODO if needed make this match chunk impl + return sampler.getSample(world.getSeed(), x, y, z); + } + + @Override + public ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider) { + return new DensityChunkLayerSampler(chunkX, chunkZ, world, biomeProvider, this, blendProperties); + } + + @Override + public double getBlendWeight() { + return blendProperties.weight(); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/ElevationLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/ElevationLayerSampler.java new file mode 100644 index 0000000000..313bb61dc6 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/ElevationLayerSampler.java @@ -0,0 +1,39 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler; + +import com.dfsek.seismic.type.sampler.Sampler; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk.DensityChunkLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk.ElevationChunkLayerSampler; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class ElevationLayerSampler implements LayerSampler { + + private final Sampler sampler; + private final BlendProperties blendProperties; + + public ElevationLayerSampler(Sampler sampler, BlendProperties blendProperties) { + this.sampler = sampler; + this.blendProperties = blendProperties; + } + + @Override + public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + //TODO if needed make this match chunk impl + return sampler.getSample(world.getSeed(), x, z); + } + + @Override + public ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider) { + return new ElevationChunkLayerSampler(chunkX, chunkZ, world, biomeProvider, this, blendProperties); + } + + @Override + public double getBlendWeight() { + return blendProperties.weight(); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/blend/BlendProperties.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/blend/BlendProperties.java new file mode 100644 index 0000000000..bea76029f6 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/blend/BlendProperties.java @@ -0,0 +1,7 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend; + +public record BlendProperties(int density, double weight, int extent) { + public static BlendProperties of(int density, double weight) { + return new BlendProperties(density, weight, Math.max((18 / density) + 1, 1)); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/chunk/DensityChunkLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/chunk/DensityChunkLayerSampler.java new file mode 100644 index 0000000000..d3fc0f9044 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/chunk/DensityChunkLayerSampler.java @@ -0,0 +1,100 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk; + +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; +import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.DensityLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + +public class DensityChunkLayerSampler implements ChunkLayerSampler { + double[] samples; + + private final int blendExtent; + + private final int min; + private final int blendExtentYExtent; + + private final int blendExtentMinus2; + private final int blendYExtendMinus2; + private final int blendDensity; + + public DensityChunkLayerSampler(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider, DensityLayerSampler layerSampler, BlendProperties blendProperties) { + this.min = world.getMinHeight() - 1; + int worldMax = world.getMaxHeight() + 1; + + blendDensity = blendProperties.density(); + + int blendYRange = worldMax - min + 1; + + int max; + int blendYExtend; + if (blendYRange % blendDensity == 0) { + blendYExtend = blendYRange / blendDensity; + max = worldMax; + } else { + blendYExtend = (blendYRange / blendDensity) + 1; + max = worldMax + 1; + } + + blendExtent = blendProperties.extent(); + blendExtentYExtent = blendYExtend * blendExtent; + blendExtentMinus2 = blendExtent - 2; + blendYExtendMinus2 = blendYExtend - 2; + + samples = new double[blendExtentYExtent * blendExtent]; + + int xOrigin = (chunkX << 4) - 1; + int zOrigin = (chunkZ << 4) - 1; + + for (int x = 0; x < 18; x += blendDensity) { + for (int z = 0; z < 18; z += blendDensity) { + int cx = xOrigin + x; + int cz = zOrigin + z; + for (int y = this.min; y <= max; y++) { + int yi = y - this.min; + int index = x * blendExtentYExtent + yi * blendExtent + z; + samples[index] = layerSampler.sample(cx, y, cz, world, biomeProvider); + } + } + } + } + + private double getSample(int x, int y, int z) { + int index = x * blendExtentYExtent + y * blendExtent + z; + return samples[index]; + } + + @Override + public double sample(int fmX, int y, int fmZ) { + double gx = (double)(fmX + 1) / blendDensity; + double gz = (double)(fmZ + 1) / blendDensity; + double gy = (double)(y - min) / blendDensity; + + int x0 = Math.max(0, Math.min(blendExtentMinus2, FloatingPointFunctions.floor(gx))); + int z0 = Math.max(0, Math.min(blendExtentMinus2, FloatingPointFunctions.floor(gz))); + int y0 = Math.max(0, Math.min(blendYExtendMinus2, FloatingPointFunctions.floor(gy))); + + int x1 = x0 + 1; + int z1 = z0 + 1; + int y1 = y0 + 1; + + double tx = gx - x0; + double tz = gz - z0; + double ty = gy - y0; + + // Fetch 8 corners + double c000 = getSample(x0, y0, z0); + double c100 = getSample(x1, y0, z0); + double c010 = getSample(x0, y1, z0); + double c110 = getSample(x1, y1, z0); + double c001 = getSample(x0, y0, z1); + double c101 = getSample(x1, y0, z1); + double c011 = getSample(x0, y1, z1); + double c111 = getSample(x1, y1, z1); + + return InterpolationFunctions.triLerp(c000, c100, c010, c110, c001, c101, c011, c111, tx, ty, tz); + } +} \ No newline at end of file diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/chunk/ElevationChunkLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/chunk/ElevationChunkLayerSampler.java new file mode 100644 index 0000000000..9f3cf57dd2 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/chunk/ElevationChunkLayerSampler.java @@ -0,0 +1,37 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.ElevationLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class ElevationChunkLayerSampler implements ChunkLayerSampler { + double[] samples; + + public ElevationChunkLayerSampler(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider, ElevationLayerSampler layerSampler, + BlendProperties blendProperties) { + //I see no reason to implement sparse blending here, elevation is inexpensive. If that changes, it can be easily implemented here. + samples = new double[16 * 16]; + + int xOrigin = chunkX << 4; + int zOrigin = chunkZ << 4; + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + int cx = xOrigin + x; + int cz = zOrigin + z; + int index = x * 16 + z; + samples[index] = layerSampler.sample(cx, 0, cz, world, biomeProvider); + } + } + } + + @Override + public double sample(int fmX, int y, int fmZ) { + int index = fmX * 16 + fmZ; + return samples[index]; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/RelationalOperator.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/RelationalOperator.java new file mode 100644 index 0000000000..a36b526bc0 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/RelationalOperator.java @@ -0,0 +1,45 @@ +package com.dfsek.terra.addons.chunkgenerator.math; + +import com.dfsek.terra.addons.chunkgenerator.util.DoubleBiPredicate; + + +public enum RelationalOperator implements DoubleBiPredicate { + GreaterThan { + @Override + public boolean test(double a, double b) { + return a > b; + } + }, + GreaterThanOrEqual { + @Override + public boolean test(double a, double b) { + return a >= b; + } + }, + LessThan { + @Override + public boolean test(double a, double b) { + return a < b; + } + }, + LessThanOrEqual { + @Override + public boolean test(double a, double b) { + return a <= b; + } + }, + Equals { + @Override + public boolean test(double a, double b) { + return a == b; + } + }, + NotEquals { + @Override + public boolean test(double a, double b) { + return a != b; + } + }; + + public abstract boolean test(double a, double b); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/PointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/PointSet.java new file mode 100644 index 0000000000..bd00a19593 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/PointSet.java @@ -0,0 +1,14 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset; + +import java.util.function.Supplier; +import java.util.stream.Stream; + +import com.dfsek.seismic.type.vector.Vector3Int; + + +public interface PointSet extends Supplier> { + + default Vector3Int[] toArray() { + return this.get().distinct().toArray(Vector3Int[]::new); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/AdjacentPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/AdjacentPointSet.java new file mode 100644 index 0000000000..cf1d739715 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/AdjacentPointSet.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative; + +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + +public class AdjacentPointSet implements PointSet { + @Override + public Stream get() { + return Stream.of( + Vector3Int.of(0, 0, -1), + Vector3Int.of(0, 0, 1), + Vector3Int.of(0, -1, 0), + Vector3Int.of(0, 1, 0), + Vector3Int.of(-1, 0, 0), + Vector3Int.of(1, 0, 0) + ); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/SimplePointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/SimplePointSet.java new file mode 100644 index 0000000000..c962e09a44 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/SimplePointSet.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative; + +import java.util.Set; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + + +public class SimplePointSet implements PointSet { + + private final Stream points; + + public SimplePointSet(Set points) { + this.points = points.stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/CuboidPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/CuboidPointSet.java new file mode 100644 index 0000000000..25ac2430bd --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/CuboidPointSet.java @@ -0,0 +1,31 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + + +public class CuboidPointSet implements PointSet { + + private final Stream points; + + public CuboidPointSet(int x1, int y1, int z1, int x2, int y2, int z2) { + Set points = new HashSet<>(); + for (int x = x1; x <= x2; x = x + 1) { + for (int y = y1; y <= y2; y = y + 1) { + for (int z = z1; z <= z2; z = z + 1) { + points.add(Vector3Int.of(x, y, z)); + } + } + } + this.points = points.stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/SphericalPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/SphericalPointSet.java new file mode 100644 index 0000000000..859112d6ec --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/SphericalPointSet.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric; + +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; +import com.dfsek.seismic.type.DistanceFunction; + + +public class SphericalPointSet implements PointSet { + + private final Stream points; + + public SphericalPointSet(double radius) { + Stream.Builder streamBuilder = Stream.builder(); + int roundedRadius = FloatingPointFunctions.ceil(radius); + for(int x = -roundedRadius; x <= roundedRadius; x++) { + for(int y = -roundedRadius; y <= roundedRadius; y++) { + for(int z = -roundedRadius; z <= roundedRadius; z++) { + Vector3Int pos = Vector3Int.of(x, y, z); + double length = pos.toFloat().length(DistanceFunction.Euclidean); + if (length == 0) continue; + if (length > radius) continue; + streamBuilder.add(pos); + } + } + } + this.points = streamBuilder.build(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/DifferencePointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/DifferencePointSet.java new file mode 100644 index 0000000000..4649f0a3c6 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/DifferencePointSet.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.google.common.collect.Sets; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + +public class DifferencePointSet implements PointSet { + + private final Stream points; + + public DifferencePointSet(List sets) { + points = sets.stream() + .map(PointSet::get) + .map(s -> s.collect(Collectors.toSet())) + .reduce(Sets::difference).orElse(Collections.emptySet()) + .stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/ExpressionFilterPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/ExpressionFilterPointSet.java new file mode 100644 index 0000000000..f91d5180ac --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/ExpressionFilterPointSet.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.dfsek.paralithic.Expression; +import com.dfsek.paralithic.eval.parser.Parser; +import com.dfsek.paralithic.eval.parser.Scope; +import com.dfsek.paralithic.eval.tokenizer.ParseException; + +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + + +public class ExpressionFilterPointSet implements PointSet { + + private final Stream points; + + public ExpressionFilterPointSet(PointSet set, String eq) throws ParseException { + Parser parser = new Parser(); + Scope scope = new Scope(); + scope.addInvocationVariable("x"); + scope.addInvocationVariable("y"); + scope.addInvocationVariable("z"); + Expression expression = parser.parse(eq, scope); + this.points = set.get().filter(v -> expression.evaluate(v.getX(), v.getY(), v.getZ()) == 1); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/IntersectionPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/IntersectionPointSet.java new file mode 100644 index 0000000000..a7ea9c5c67 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/IntersectionPointSet.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.google.common.collect.Sets; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + +public class IntersectionPointSet implements PointSet { + + private final Stream points; + + public IntersectionPointSet(List sets) { + points = sets.stream() + .map(PointSet::get) + .map(s -> s.collect(Collectors.toSet())) + .reduce(Sets::intersection).orElse(Collections.emptySet()) + .stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/UnionPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/UnionPointSet.java new file mode 100644 index 0000000000..c808ba2e37 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/UnionPointSet.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.google.common.collect.Sets; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.seismic.type.vector.Vector3Int; + +public class UnionPointSet implements PointSet { + + private final Stream points; + + public UnionPointSet(List sets) { + points = sets.stream() + .map(PointSet::get) + .map(s -> s.collect(Collectors.toSet())) + .reduce(Sets::union).orElse(Collections.emptySet()) + .stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java new file mode 100644 index 0000000000..2f0a9f91b0 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java @@ -0,0 +1,34 @@ +package com.dfsek.terra.addons.chunkgenerator.palette; + +import java.util.Map; +import java.util.NavigableMap; +import java.util.TreeMap; + + +public class DoubleNavigableHolder { + + private final NavigableMap map; + + public DoubleNavigableHolder(Map inputMap) { + NavigableMap map = new TreeMap<>(inputMap); + map.put(Double.MAX_VALUE, map.lastEntry().getValue()); + this.map = map; + } + + public T get(double threshold) { + return map.ceilingEntry(threshold).getValue(); + } + + enum Method { + CEILING, + FLOOR, + CLOSEST + } + + public class Single extends DoubleNavigableHolder { + + public Single(Map inputMap) { + super(inputMap); + } + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SingletonPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SingletonPalette.java new file mode 100644 index 0000000000..fb83db0ea3 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SingletonPalette.java @@ -0,0 +1,18 @@ +package com.dfsek.terra.addons.chunkgenerator.palette; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class SingletonPalette implements Palette { + private final BlockState blockState; + + public SingletonPalette(BlockState blockState) { + this.blockState = blockState; + } + + @Override + public BlockState get(int layer, double x, double y, double z, long seed) { + return blockState; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/DoubleBiPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/DoubleBiPredicate.java new file mode 100644 index 0000000000..948a0fc32f --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/DoubleBiPredicate.java @@ -0,0 +1,6 @@ +package com.dfsek.terra.addons.chunkgenerator.util; + +@FunctionalInterface +public interface DoubleBiPredicate { + boolean test(double a, double b); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/InstanceWrapper.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/InstanceWrapper.java new file mode 100644 index 0000000000..ebb1e6ad7a --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/InstanceWrapper.java @@ -0,0 +1,12 @@ +package com.dfsek.terra.addons.chunkgenerator.util; + +import java.util.function.Supplier; + + +public record InstanceWrapper(T instance) implements Supplier { + + @Override + public T get() { + return instance; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/resources/terra.addon.yml b/common/addons/chunk-generator-layered/src/main/resources/terra.addon.yml new file mode 100644 index 0000000000..1b7a2d3427 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/resources/terra.addon.yml @@ -0,0 +1,12 @@ +schema-version: 1 +contributors: + - Terra contributors +id: chunk-generator-layered +version: @VERSION@ +entrypoints: + - "com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon" +website: + issues: https://github.com/PolyhedralDev/Terra/issues + source: https://github.com/PolyhedralDev/Terra + docs: https://terra.polydev.org +license: MIT License \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java index dcab4df141..9473872982 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java @@ -1,5 +1,6 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; @@ -28,8 +29,8 @@ public LazilyEvaluatedInterpolator(BiomeProvider biomeProvider, int cx, int cz, PropertyKey noisePropertiesKey, int min, int horizontalRes, int verticalRes, long seed) { this.noisePropertiesKey = noisePropertiesKey; - int hSamples = (int) Math.ceil(16.0 / horizontalRes); - int vSamples = (int) Math.ceil((double) (max - min) / verticalRes); + int hSamples = FloatingPointFunctions.ceil(16.0 / horizontalRes); + int vSamples = FloatingPointFunctions.ceil((double) (max - min) / verticalRes); this.zMul = (hSamples + 1); this.yMul = zMul * zMul; samples = new Double[yMul * (vSamples + 1)]; diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java index 90d69461a6..cdab4e40a9 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/samplers/Sampler3D.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator; import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ElevationInterpolator; @@ -26,7 +28,7 @@ public Sampler3D(int x, int z, long seed, int minHeight, int maxHeight, BiomePro } public double sample(double x, double y, double z) { - return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation((int) Math.round(x), (int) Math.round(z)); + return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FloatingPointFunctions.round(x), FloatingPointFunctions.round(z)); } public double sample(int x, int y, int z) { diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java index 84ff59543f..15eb6b3c36 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.random.RandomGenerator; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions; import com.dfsek.seismic.math.trigonometry.TrigonometryFunctions; import com.dfsek.seismic.type.Rotation; @@ -104,7 +105,7 @@ public boolean generate(Vector3Int location, WritableWorld world, RandomGenerato } } - int outset = (int) Math.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F); + int outset = FloatingPointFunctions.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F); int x = (int) (location.getX() - Math.ceil(eighthSize) - outset); int y = location.getY() - 2 - outset; int z = (int) (location.getZ() - Math.ceil(eighthSize) - outset); diff --git a/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/operator/DistanceTransform.java b/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/operator/DistanceTransform.java index f9818c80f4..93f4b2bc34 100644 --- a/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/operator/DistanceTransform.java +++ b/common/addons/library-image/src/main/java/com/dfsek/terra/addons/image/operator/DistanceTransform.java @@ -1,5 +1,7 @@ package com.dfsek.terra.addons.image.operator; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.image.image.Image; import com.dfsek.terra.addons.image.util.ColorUtil; import com.dfsek.terra.addons.image.util.ColorUtil.Channel; @@ -232,7 +234,7 @@ public Noise(DistanceTransform transform, Normalization normalization) { @Override public double getSample(long seed, double x, double y) { if(x < 0 || y < 0 || x >= transform.width || y >= transform.height) return transform.minDistance; - return transform.distances[(int) Math.floor(x)][(int) Math.floor(y)]; + return transform.distances[FloatingPointFunctions.floor(x)][FloatingPointFunctions.floor(y)]; } @Override diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java index 14cb8b3816..3ab8b7c5f1 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java @@ -7,6 +7,7 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; import com.dfsek.seismic.type.vector.Vector2; import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; @@ -45,9 +46,9 @@ public String apply(ImplementationArguments implementationArguments, Scope scope return grid.getBiome(arguments.getOrigin().toFloat() .mutable() - .add(Vector3.of((int) Math.round(xz.getX()), + .add(Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).intValue(), - (int) Math.round(xz.getZ()))).immutable(), arguments.getWorld().getSeed()).getID(); + FloatingPointFunctions.round(xz.getZ()))).immutable(), arguments.getWorld().getSeed()).getID(); } @Override diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java index fb8ffa22ef..66f40696c0 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java @@ -7,6 +7,7 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,9 +72,9 @@ void setBlock(ImplementationArguments implementationArguments, Scope scope, Vector2 xz = Vector2.Mutable.of(x.apply(implementationArguments, scope).doubleValue(), z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation()); try { - Vector3.Mutable set = Vector3.of((int) Math.round(xz.getX()), + Vector3.Mutable set = Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).doubleValue(), - (int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()); + FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()); BlockState current = arguments.getWorld().getBlockState(set); if(overwrite.apply(implementationArguments, scope) || current.isAir()) { arguments.getWorld().setBlockState(set, rot, physics.apply(implementationArguments, scope)); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java index fd3465c451..b0bd358907 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; import com.dfsek.terra.addons.terrascript.parser.lang.Scope; @@ -40,9 +42,9 @@ public String apply(ImplementationArguments implementationArguments, Scope scope String data = arguments.getWorld() .getBlockState(arguments.getOrigin().toFloat() .mutable() - .add(Vector3.of((int) Math.round(xz.getX()), + .add(Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope) - .doubleValue(), (int) Math.round(xz.getZ())))) + .doubleValue(), FloatingPointFunctions.round(xz.getZ())))) .getAsString(); if(data.contains("[")) return data.substring(0, data.indexOf('[')); // Strip properties else return data; diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java index b98dda159e..917a133e8c 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; import com.dfsek.terra.addons.terrascript.parser.lang.Scope; @@ -34,9 +36,9 @@ public String apply(ImplementationArguments implementationArguments, Scope scope Vector2 xz = Vector2.Mutable.of(x.apply(implementationArguments, scope).doubleValue(), z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation()); - String mark = arguments.getMark(Vector3.of((int) Math.floor(xz.getX()), (int) Math.floor( + String mark = arguments.getMark(Vector3.of(FloatingPointFunctions.floor(xz.getX()), FloatingPointFunctions.floor( y.apply(implementationArguments, scope).doubleValue()), - (int) Math.floor(xz.getZ())) + FloatingPointFunctions.floor(xz.getZ())) .mutable() .add(arguments.getOrigin().toFloat()) .immutable()); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java index 5fcc8e46b9..bfb0c6d8ce 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java @@ -7,6 +7,7 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,10 +65,10 @@ public Void apply(ImplementationArguments implementationArguments, Scope scope) registry.get(RegistryKey.parse(id)) .ifPresentOrElse(table -> { - Vector3 apply = Vector3.of((int) Math.round(xz.getX()), + Vector3 apply = Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope) .intValue(), - (int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(); + FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(); try { BlockEntity data = arguments.getWorld().getBlockEntity(apply); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java index b6cbd2bdee..28890580ab 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.terrascript.parser.exceptions.ParseException; import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; @@ -43,8 +45,8 @@ public Void apply(ImplementationArguments implementationArguments, Scope scope) Vector2 xz = Vector2.Mutable.of(x.apply(implementationArguments, scope).doubleValue(), z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation()); - Vector3.Mutable mutable = Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).intValue(), - (int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()); + Vector3.Mutable mutable = Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).intValue(), + FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()); while(mutable.getY() > arguments.getWorld().getMinHeight()) { if(!arguments.getWorld().getBlockState(mutable).isAir()) { arguments.getWorld().setBlockState(mutable, data); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java index 905ff23aef..a485094b37 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; import com.dfsek.terra.addons.terrascript.parser.lang.Scope; @@ -37,10 +39,10 @@ public Void apply(ImplementationArguments implementationArguments, Scope scope) z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation()); - arguments.setMark(Vector3.of((int) Math.floor(xz.getX()), - (int) Math.floor( + arguments.setMark(Vector3.of(FloatingPointFunctions.floor(xz.getX()), + FloatingPointFunctions.floor( y.apply(implementationArguments, scope).doubleValue()), - (int) Math.floor(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(), + FloatingPointFunctions.floor(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(), mark.apply(implementationArguments, scope)); return null; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java index fbc9dfceda..95bdcfe133 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java @@ -7,6 +7,7 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,8 +44,8 @@ public Void apply(ImplementationArguments implementationArguments, Scope scope) z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation()); - Vector3 origin = Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).intValue(), - (int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(); + Vector3 origin = Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).intValue(), + FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(); try { BlockEntity state = arguments.getWorld().getBlockEntity(origin); state.applyState(data.apply(implementationArguments, scope)); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java index c62efde0a5..5eb481354e 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java @@ -7,6 +7,7 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; import com.dfsek.seismic.type.Rotation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,17 +78,17 @@ public Boolean apply(ImplementationArguments implementationArguments, Scope scop if(script instanceof StructureScript structureScript) { return structureScript.generate(arguments.getOrigin(), arguments.getWorld() - .buffer((int) Math.round(xz.getX()), + .buffer(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).intValue(), - (int) Math.round(xz.getZ())), + FloatingPointFunctions.round(xz.getZ())), arguments.getRandom(), arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1); } return script.generate(arguments.getOrigin(), arguments.getWorld() - .buffer((int) Math.round(xz.getX()), + .buffer(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).intValue(), - (int) Math.round(xz.getZ())), + FloatingPointFunctions.round(xz.getZ())), arguments.getRandom(), arguments.getRotation().rotate(rotation1)); }).orElseGet(() -> { diff --git a/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java b/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java index 0e9972fc04..5021935bff 100644 --- a/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java +++ b/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addon.terrascript.check; +import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions; + import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D; import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerProvider; import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; @@ -44,8 +46,8 @@ public String apply(ImplementationArguments implementationArguments, Scope scope z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation()); Vector3 location = arguments.getOrigin().toFloat().mutable().add( - Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).doubleValue(), - (int) Math.round(xz.getZ()))).immutable(); + Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).doubleValue(), + FloatingPointFunctions.round(xz.getZ()))).immutable(); return apply(location, arguments.getWorld()); } diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java index 16177be565..b7ec12691f 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java @@ -20,6 +20,8 @@ import ca.solostudios.strata.version.Version; import ca.solostudios.strata.version.VersionRange; import com.dfsek.paralithic.eval.parser.Parser.ParseOptions; +import com.dfsek.seismic.type.vector.Vector3; +import com.dfsek.seismic.type.vector.Vector3Int; import com.dfsek.tectonic.api.TypeRegistry; import java.util.LinkedHashMap; @@ -37,6 +39,8 @@ import com.dfsek.terra.config.loaders.MaterialSetLoader; import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.RangeLoader; +import com.dfsek.terra.config.loaders.Vector3IntLoader; +import com.dfsek.terra.config.loaders.Vector3Loader; import com.dfsek.terra.config.loaders.VersionLoader; import com.dfsek.terra.config.loaders.VersionRangeLoader; @@ -56,8 +60,9 @@ public void register(TypeRegistry registry) { .registerLoader(MaterialSet.class, new MaterialSetLoader()) .registerLoader(VersionRange.class, new VersionRangeLoader()) .registerLoader(LinkedHashMap.class, new LinkedHashMapLoader()) - .registerLoader(ParseOptions.class, ExpressionParserOptionsTemplate::new); - + .registerLoader(ParseOptions.class, ExpressionParserOptionsTemplate::new) + .registerLoader(Vector3.class, new Vector3Loader()) + .registerLoader(Vector3Int.class, new Vector3IntLoader()); if(platform != null) { registry.registerLoader(BaseAddon.class, platform.getAddons()) .registerLoader(BlockType.class, (type, object, configLoader, depthTracker) -> platform diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3IntLoader.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3IntLoader.java new file mode 100644 index 0000000000..74b720b825 --- /dev/null +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3IntLoader.java @@ -0,0 +1,31 @@ +package com.dfsek.terra.config.loaders; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.List; +import java.util.Map; + +import com.dfsek.seismic.type.vector.Vector3Int; + +public class Vector3IntLoader implements TypeLoader { + + @SuppressWarnings("unchecked") + @Override + public Vector3Int load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, + DepthTracker depthTracker) throws LoadException { + if (o instanceof List) { + List list = (List) o; + return Vector3Int.of(list.get(0), list.get(1), list.get(2)); + } + else { + Map map = (Map) o; + return Vector3Int.of(map.get("x"), map.get("y"), map.get("z")); + } + } +} + diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3Loader.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3Loader.java new file mode 100644 index 0000000000..38b1a7a7e1 --- /dev/null +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3Loader.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.config.loaders; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.List; +import java.util.Map; + +import com.dfsek.seismic.type.vector.Vector3; + + +public class Vector3Loader implements TypeLoader { + + @SuppressWarnings("unchecked") + @Override + public Vector3 load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, + DepthTracker depthTracker) throws LoadException { + if (o instanceof List) { + List list = (List) o; + return Vector3.of(list.get(0), list.get(1), list.get(2)); + } + else { + Map map = (Map) o; + return Vector3.of(map.get("x"), map.get("y"), map.get("z")); + } + } +} + diff --git a/platforms/fabric/build.gradle.kts b/platforms/fabric/build.gradle.kts index ce627df4f6..1738c17c60 100644 --- a/platforms/fabric/build.gradle.kts +++ b/platforms/fabric/build.gradle.kts @@ -38,7 +38,6 @@ loom { mixin { defaultRefmapName.set("terra.fabric.refmap.json") } - }