commit 3d6e9f69dee94dbae1948e1789be39a3ed6f94d6 Author: dfsek Date: Sun Oct 17 15:21:51 2021 -0700 Initial commit diff --git a/common/addons/config-palette/README.md b/common/addons/config-palette/README.md new file mode 100644 index 000000000..7aa0bbe8f --- /dev/null +++ b/common/addons/config-palette/README.md @@ -0,0 +1,3 @@ +# config-palette + +Registers the default configuration for Terra Palettes, `PALETTE`. \ No newline at end of file diff --git a/common/addons/config-palette/build.gradle.kts b/common/addons/config-palette/build.gradle.kts new file mode 100644 index 000000000..7d82dc72f --- /dev/null +++ b/common/addons/config-palette/build.gradle.kts @@ -0,0 +1,2 @@ +dependencies { +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteAddon.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteAddon.java new file mode 100644 index 000000000..358196707 --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteAddon.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.addons.palette; + +import com.dfsek.terra.addons.palette.palette.PaletteLayerHolder; +import com.dfsek.terra.addons.palette.palette.PaletteLayerLoader; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.TerraAddon; +import com.dfsek.terra.api.addon.annotations.Addon; +import com.dfsek.terra.api.addon.annotations.Author; +import com.dfsek.terra.api.addon.annotations.Version; +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; + + +@Addon("config-palette") +@Author("Terra") +@Version("1.0.0") +public class PaletteAddon extends TerraAddon { + @Inject + private Platform platform; + + @Override + public void initialize() { + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(this, ConfigPackPreLoadEvent.class) + .then(event -> { + event.getPack().registerConfigType(new PaletteConfigType(platform), "PALETTE", 2); + event.getPack().applyLoader(PaletteLayerHolder.class, new PaletteLayerLoader()); + }) + .failThrough(); + } +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteConfigType.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteConfigType.java new file mode 100644 index 000000000..37e7e934e --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteConfigType.java @@ -0,0 +1,55 @@ +package com.dfsek.terra.addons.palette; + +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.TypeLoader; + +import java.util.function.Supplier; + +import com.dfsek.terra.addons.palette.palette.PaletteImpl; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.config.ConfigFactory; +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.config.ConfigType; +import com.dfsek.terra.api.registry.OpenRegistry; +import com.dfsek.terra.api.util.reflection.TypeKey; +import com.dfsek.terra.api.world.generator.Palette; + + +public class PaletteConfigType implements ConfigType { + public static final TypeKey PALETTE_TYPE_TOKEN = new TypeKey<>() { + }; + private final PaletteFactory factory = new PaletteFactory(); + private final Platform platform; + + public PaletteConfigType(Platform platform) { + this.platform = platform; + } + + @Override + public Supplier> registrySupplier(ConfigPack pack) { + return () -> pack.getRegistryFactory().create(registry -> (TypeLoader) (t, c, loader) -> { + if(((String) c).startsWith("BLOCK:")) + return new PaletteImpl.Singleton( + platform.getWorldHandle().createBlockData(((String) c).substring(6))); // Return single palette for BLOCK: shortcut. + Palette obj = registry.get((String) c); + if(obj == null) + throw new LoadException("No such " + t.getType().getTypeName() + " matching \"" + c + "\" was found in this registry."); + return obj; + }); + } + + @Override + public PaletteTemplate getTemplate(ConfigPack pack, Platform platform) { + return new PaletteTemplate(); + } + + @Override + public ConfigFactory getFactory() { + return factory; + } + + @Override + public TypeKey getTypeKey() { + return PALETTE_TYPE_TOKEN; + } +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteFactory.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteFactory.java new file mode 100644 index 000000000..3b66f8b22 --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteFactory.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.palette; + +import com.dfsek.terra.addons.palette.palette.NoisePalette; +import com.dfsek.terra.addons.palette.palette.PaletteLayerHolder; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.config.ConfigFactory; +import com.dfsek.terra.api.world.generator.Palette; + + +public class PaletteFactory implements ConfigFactory { + @Override + public Palette build(PaletteTemplate config, Platform platform) { + NoisePalette palette = new NoisePalette(config.getNoise()); + for(PaletteLayerHolder layer : config.getPalette()) { + palette.add(layer.getLayer(), layer.getSize(), layer.getSampler()); + } + return palette; + } +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteTemplate.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteTemplate.java new file mode 100644 index 000000000..8224f2de5 --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/PaletteTemplate.java @@ -0,0 +1,39 @@ +package com.dfsek.terra.addons.palette; + +import com.dfsek.tectonic.annotations.Default; +import com.dfsek.tectonic.annotations.Final; +import com.dfsek.tectonic.annotations.Value; + +import java.util.List; + +import com.dfsek.terra.addons.palette.palette.PaletteLayerHolder; +import com.dfsek.terra.api.config.AbstractableTemplate; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.noise.NoiseSampler; + + +@SuppressWarnings({ "FieldMayBeFinal", "unused" }) +public class PaletteTemplate implements AbstractableTemplate { + @Value("noise") + @Default + private @Meta NoiseSampler noise = NoiseSampler.zero(); + + @Value("id") + @Final + private String id; + + @Value("layers") + private @Meta List<@Meta PaletteLayerHolder> palette; + + public String getID() { + return id; + } + + public List getPalette() { + return palette; + } + + public NoiseSampler getNoise() { + return noise; + } +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/NoisePalette.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/NoisePalette.java new file mode 100644 index 000000000..7f630a4b2 --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/NoisePalette.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.addons.palette.palette; + +import java.util.List; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.noise.NoiseSampler; + + +public class NoisePalette extends PaletteImpl { + private final NoiseSampler sampler; + + public NoisePalette(NoiseSampler sampler) { + this.sampler = sampler; + } + + @Override + public BlockState get(int layer, double x, double y, double z, long seed) { + PaletteLayer paletteLayer; + if(layer > this.getSize()) paletteLayer = this.getLayers().get(this.getLayers().size() - 1); + else { + List pl = getLayers(); + if(layer >= pl.size()) paletteLayer = pl.get(pl.size() - 1); + else paletteLayer = pl.get(layer); + } + NoiseSampler paletteSampler = paletteLayer.getSampler(); + return paletteLayer.get(paletteSampler == null ? sampler : paletteSampler, x, y, z, seed); + } +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteImpl.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteImpl.java new file mode 100644 index 000000000..1201b852e --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteImpl.java @@ -0,0 +1,112 @@ +package com.dfsek.terra.addons.palette.palette; + +import java.util.ArrayList; +import java.util.List; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.util.collection.ProbabilityCollection; +import com.dfsek.terra.api.world.generator.Palette; + + +/** + * A class representation of a "slice" of the world. + * Used to get a section of blocks, based on the depth at which they are found. + */ +public abstract class PaletteImpl implements Palette { + private final List pallet = new ArrayList<>(); + + /** + * Constructs a blank palette. + */ + public PaletteImpl() { + + } + + @Override + public Palette add(BlockState m, int layers, NoiseSampler sampler) { + for(int i = 0; i < layers; i++) { + pallet.add(new PaletteLayer(m, sampler)); + } + return this; + } + + @Override + public Palette add(ProbabilityCollection m, int layers, NoiseSampler sampler) { + for(int i = 0; i < layers; i++) { + pallet.add(new PaletteLayer(m, sampler)); + } + return this; + } + + + @Override + public int getSize() { + return pallet.size(); + } + + public List getLayers() { + return pallet; + } + + /** + * Class representation of a layer of a BlockPalette. + */ + public static class PaletteLayer { + private final boolean col; // Is layer using a collection? + private final NoiseSampler sampler; + private ProbabilityCollection collection; + private BlockState m; + + /** + * Constructs a PaletteLayerHolder with a ProbabilityCollection of materials and a number of layers. + * + * @param type The collection of materials to choose from. + * @param sampler Noise sampler to use + */ + public PaletteLayer(ProbabilityCollection type, NoiseSampler sampler) { + this.sampler = sampler; + this.col = true; + this.collection = type; + } + + /** + * Constructs a PaletteLayerHolder with a single Material and a number of layers. + * + * @param type The material to use. + * @param sampler Noise sampler to use + */ + public PaletteLayer(BlockState type, NoiseSampler sampler) { + this.sampler = sampler; + this.col = false; + this.m = type; + } + + public BlockState get(NoiseSampler random, double x, double y, double z, long seed) { + if(col) return this.collection.get(random, x, y, z, seed); + return m; + } + + public NoiseSampler getSampler() { + return sampler; + } + + public ProbabilityCollection getCollection() { + return collection; + } + } + + + public static class Singleton extends PaletteImpl { + private final BlockState item; + + public Singleton(BlockState item) { + this.item = item; + } + + @Override + public BlockState get(int layer, double x, double y, double z, long seed) { + return item; + } + } +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteLayerHolder.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteLayerHolder.java new file mode 100644 index 000000000..484872036 --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteLayerHolder.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.addons.palette.palette; + +import org.jetbrains.annotations.NotNull; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.util.collection.ProbabilityCollection; + + +public class PaletteLayerHolder { + private final ProbabilityCollection layer; + private final NoiseSampler sampler; + private final int size; + + public PaletteLayerHolder(@NotNull ProbabilityCollection layer, NoiseSampler sampler, int size) { + this.layer = layer; + this.sampler = sampler; + this.size = size; + } + + @NotNull + public ProbabilityCollection getLayer() { + return layer; + } + + public int getSize() { + return size; + } + + public NoiseSampler getSampler() { + return sampler; + } +} diff --git a/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteLayerLoader.java b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteLayerLoader.java new file mode 100644 index 000000000..0f5104930 --- /dev/null +++ b/common/addons/config-palette/src/main/java/com/dfsek/terra/addons/palette/palette/PaletteLayerLoader.java @@ -0,0 +1,43 @@ +package com.dfsek.terra.addons.palette.palette; + +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.ConfigLoader; +import com.dfsek.tectonic.loading.TypeLoader; + +import java.lang.reflect.AnnotatedType; +import java.util.Map; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.util.collection.ProbabilityCollection; + + +@SuppressWarnings("unchecked") +public class PaletteLayerLoader implements TypeLoader { + private static final AnnotatedType BLOCK_DATA_PROBABILITY_COLLECTION_TYPE; + static { + try { + BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = PaletteLayerLoader.class.getDeclaredField("blockStateProbabilityCollection") + .getAnnotatedType(); + } catch(NoSuchFieldException e) { + throw new Error("this should never happen. i dont know what you did to make this happen but something is very wrong.", e); + } + } + @SuppressWarnings("unused") + private ProbabilityCollection blockStateProbabilityCollection; + + @Override + public PaletteLayerHolder load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException { + Map map = (Map) o; + ProbabilityCollection collection = (ProbabilityCollection) configLoader.loadType( + BLOCK_DATA_PROBABILITY_COLLECTION_TYPE, map.get("materials")); + + NoiseSampler sampler = null; + if(map.containsKey("noise")) { + sampler = configLoader.loadType(NoiseSampler.class, map.get("noise")); + } + + if(collection == null) throw new LoadException("Collection is null: " + map.get("materials")); + return new PaletteLayerHolder(collection, sampler, (Integer) map.get("layers")); + } +}