mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-02 16:05:29 +00:00
Merge pull request #245 from PolyhedralDev/dev/metaconfiguration
Metaconfiguration
This commit is contained in:
commit
36838d8938
@ -6,6 +6,7 @@ import com.dfsek.terra.addons.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||
|
||||
@ -16,13 +17,13 @@ public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
||||
private final TerraPlugin main;
|
||||
@Value("pipeline.initial-size")
|
||||
@Default
|
||||
private int initialSize = 2;
|
||||
private @Meta int initialSize = 2;
|
||||
|
||||
@Value("pipeline.stages")
|
||||
private List<Stage> stages;
|
||||
private @Meta List<@Meta Stage> stages;
|
||||
|
||||
@Value("pipeline.source")
|
||||
private BiomeSource source;
|
||||
private @Meta BiomeSource source;
|
||||
|
||||
public BiomePipelineTemplate(TerraPlugin main) {
|
||||
this.main = main;
|
||||
|
@ -3,17 +3,18 @@ package com.dfsek.terra.addons.biome.pipeline.config;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
@Value("resolution")
|
||||
@Default
|
||||
protected int resolution = 1;
|
||||
protected @Meta int resolution = 1;
|
||||
@Value("blend.noise")
|
||||
@Default
|
||||
protected NoiseSampler blend = NoiseSampler.zero();
|
||||
protected @Meta NoiseSampler blend = NoiseSampler.zero();
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
protected double blendAmp = 0d;
|
||||
protected @Meta double blendAmp = 0d;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.dfsek.terra.addons.biome.pipeline.config;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.biome.pipeline.source.NoiseSource;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
@ -9,10 +10,10 @@ import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
|
||||
|
||||
public class NoiseSourceTemplate extends SourceTemplate {
|
||||
@Value("noise")
|
||||
private NoiseSampler noise;
|
||||
private @Meta NoiseSampler noise;
|
||||
|
||||
@Value("biomes")
|
||||
private ProbabilityCollection<TerraBiome> biomes;
|
||||
private @Meta ProbabilityCollection<@Meta TerraBiome> biomes;
|
||||
|
||||
@Override
|
||||
public BiomeSource get() {
|
||||
|
@ -3,9 +3,10 @@ package com.dfsek.terra.addons.biome.pipeline.config.stage;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
public abstract class StageTemplate implements ObjectTemplate<Stage> {
|
||||
@Value("noise")
|
||||
protected NoiseSampler noise;
|
||||
protected @Meta NoiseSampler noise;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderListMutator;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
|
||||
@ -11,16 +12,16 @@ import java.util.Map;
|
||||
@SuppressWarnings("unused")
|
||||
public class BorderListMutatorTemplate extends MutatorStageTemplate {
|
||||
@Value("from")
|
||||
private String from;
|
||||
private @Meta String from;
|
||||
|
||||
@Value("default-replace")
|
||||
private String defaultReplace;
|
||||
private @Meta String defaultReplace;
|
||||
|
||||
@Value("default-to")
|
||||
private ProbabilityCollection<TerraBiome> defaultTo;
|
||||
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
|
||||
|
||||
@Value("replace")
|
||||
private Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
|
||||
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -3,19 +3,20 @@ package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderMutator;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class BorderMutatorTemplate extends MutatorStageTemplate {
|
||||
@Value("from")
|
||||
private String from;
|
||||
private @Meta String from;
|
||||
|
||||
@Value("replace")
|
||||
private String replace;
|
||||
private @Meta String replace;
|
||||
|
||||
@Value("to")
|
||||
private ProbabilityCollection<TerraBiome> to;
|
||||
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
|
||||
|
||||
@Override
|
||||
public BiomeMutator get() {
|
||||
|
@ -4,11 +4,12 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
public abstract class MutatorStageTemplate implements ObjectTemplate<BiomeMutator> {
|
||||
@Value("noise")
|
||||
protected NoiseSampler noise;
|
||||
protected @Meta NoiseSampler noise;
|
||||
|
||||
@Override
|
||||
public abstract BiomeMutator get();
|
||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceListMutator;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
|
||||
@ -11,13 +12,13 @@ import java.util.Map;
|
||||
@SuppressWarnings("unused")
|
||||
public class ReplaceListMutatorTemplate extends MutatorStageTemplate {
|
||||
@Value("default-from")
|
||||
private String defaultFrom;
|
||||
private @Meta String defaultFrom;
|
||||
|
||||
@Value("default-to")
|
||||
private ProbabilityCollection<TerraBiome> defaultTo;
|
||||
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
|
||||
|
||||
@Value("to")
|
||||
private Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
|
||||
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
|
||||
|
||||
@Override
|
||||
public BiomeMutator get() {
|
||||
|
@ -3,16 +3,17 @@ package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceMutator;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ReplaceMutatorTemplate extends MutatorStageTemplate {
|
||||
@Value("from")
|
||||
private String from;
|
||||
private @Meta String from;
|
||||
|
||||
@Value("to")
|
||||
private ProbabilityCollection<TerraBiome> to;
|
||||
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
|
||||
|
||||
@Override
|
||||
public BiomeMutator get() {
|
||||
|
@ -2,12 +2,13 @@ package com.dfsek.terra.addons.biome.single;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
public class SingleBiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
@Value("biome")
|
||||
private TerraBiome biome;
|
||||
private @Meta TerraBiome biome;
|
||||
|
||||
@Override
|
||||
public BiomeProvider get() {
|
||||
|
@ -6,21 +6,22 @@ import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.generator.Palette;
|
||||
|
||||
public class BiomePaletteTemplate implements ObjectTemplate<PaletteInfo> {
|
||||
@Value("palette")
|
||||
private PaletteHolder palette;
|
||||
private @Meta PaletteHolder palette;
|
||||
|
||||
@Value("slant")
|
||||
@Default
|
||||
private SlantHolder slant = null;
|
||||
private @Meta SlantHolder slant = null;
|
||||
|
||||
@Value("ocean.level")
|
||||
private int seaLevel;
|
||||
private @Meta int seaLevel;
|
||||
|
||||
@Value("ocean.palette")
|
||||
private Palette oceanPalette;
|
||||
private @Meta Palette oceanPalette;
|
||||
|
||||
@Override
|
||||
public PaletteInfo get() {
|
||||
|
@ -9,6 +9,7 @@ import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
@ -27,7 +28,7 @@ public class BiomeTemplate implements AbstractableTemplate, ValidatedConfigTempl
|
||||
|
||||
@Value("id")
|
||||
@Final
|
||||
private String id;
|
||||
private @Meta String id;
|
||||
|
||||
@Value("extends")
|
||||
@Final
|
||||
@ -36,78 +37,78 @@ public class BiomeTemplate implements AbstractableTemplate, ValidatedConfigTempl
|
||||
|
||||
@Value("variables")
|
||||
@Default
|
||||
private Map<String, Double> variables = new HashMap<>();
|
||||
private @Meta Map<String, @Meta Double> variables = new HashMap<>();
|
||||
|
||||
@Value("beta.carving.equation")
|
||||
@Default
|
||||
private NoiseSampler carvingEquation = NoiseSampler.zero();
|
||||
private @Meta NoiseSampler carvingEquation = NoiseSampler.zero();
|
||||
|
||||
@Value("vanilla")
|
||||
private ProbabilityCollection<Biome> vanilla;
|
||||
private @Meta ProbabilityCollection<Biome> vanilla;
|
||||
|
||||
@Value("biome-noise")
|
||||
@Default
|
||||
private NoiseSampler biomeNoise = NoiseSampler.zero();
|
||||
private @Meta NoiseSampler biomeNoise = NoiseSampler.zero();
|
||||
|
||||
@Value("blend.distance")
|
||||
@Default
|
||||
private int blendDistance = 3;
|
||||
private @Meta int blendDistance = 3;
|
||||
|
||||
@Value("blend.weight")
|
||||
@Default
|
||||
private double blendWeight = 1;
|
||||
private @Meta double blendWeight = 1;
|
||||
|
||||
@Value("blend.step")
|
||||
@Default
|
||||
private int blendStep = 4;
|
||||
private @Meta int blendStep = 4;
|
||||
|
||||
@Value("noise")
|
||||
private NoiseSampler noiseEquation;
|
||||
private @Meta NoiseSampler noiseEquation;
|
||||
|
||||
@Value("ocean.level")
|
||||
@Default
|
||||
private int seaLevel = 62;
|
||||
private @Meta int seaLevel = 62;
|
||||
|
||||
@Value("elevation.equation")
|
||||
@Default
|
||||
private NoiseSampler elevationEquation = NoiseSampler.zero();
|
||||
private @Meta NoiseSampler elevationEquation = NoiseSampler.zero();
|
||||
|
||||
@Value("elevation.weight")
|
||||
@Default
|
||||
private double elevationWeight = 1;
|
||||
private @Meta double elevationWeight = 1;
|
||||
|
||||
@Value("slabs.enable")
|
||||
@Default
|
||||
private boolean doSlabs = false;
|
||||
private @Meta boolean doSlabs = false;
|
||||
|
||||
@Value("slabs.threshold")
|
||||
@Default
|
||||
private double slabThreshold = 0.0075D;
|
||||
private @Meta double slabThreshold = 0.0075D;
|
||||
|
||||
@Value("slabs.palettes")
|
||||
@Default
|
||||
private Map<BlockType, Palette> slabPalettes;
|
||||
private @Meta Map<@Meta BlockType, @Meta Palette> slabPalettes;
|
||||
|
||||
@Value("slabs.stair-palettes")
|
||||
@Default
|
||||
private Map<BlockType, Palette> stairPalettes;
|
||||
private @Meta Map<@Meta BlockType, @Meta Palette> stairPalettes;
|
||||
|
||||
@Value("interpolate-elevation")
|
||||
@Default
|
||||
private boolean interpolateElevation = true;
|
||||
private @Meta boolean interpolateElevation = true;
|
||||
|
||||
@Value("color")
|
||||
@Final
|
||||
@Default
|
||||
private int color = 0;
|
||||
private @Meta int color = 0;
|
||||
|
||||
@Value("tags")
|
||||
@Default
|
||||
private Set<String> tags = new HashSet<>();
|
||||
private @Meta Set<@Meta String> tags = new HashSet<>();
|
||||
|
||||
@Value("colors")
|
||||
@Default
|
||||
private Map<String, Integer> colors = new HashMap<>(); // Plain ol' map, so platforms can decide what to do with colors (if anything).
|
||||
private @Meta Map<String, @Meta Integer> colors = new HashMap<>(); // Plain ol' map, so platforms can decide what to do with colors (if anything).
|
||||
|
||||
public BiomeTemplate(ConfigPack pack, TerraPlugin main) {
|
||||
this.pack = pack;
|
||||
|
@ -6,6 +6,7 @@ import com.dfsek.tectonic.annotations.Final;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.ConstantRange;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||
@ -21,76 +22,76 @@ public class CarverTemplate implements AbstractableTemplate {
|
||||
|
||||
@Value("step")
|
||||
@Default
|
||||
private int step = 2;
|
||||
private @Meta int step = 2;
|
||||
|
||||
@Value("recalculate-magnitude")
|
||||
@Default
|
||||
private double recaclulateMagnitude = 4;
|
||||
private @Meta double recaclulateMagnitude = 4;
|
||||
|
||||
@Value("recalculate-direction")
|
||||
@Default
|
||||
private Range recalc = new ConstantRange(8, 10);
|
||||
private @Meta Range recalc = new ConstantRange(8, 10);
|
||||
|
||||
@Value("length")
|
||||
private Range length;
|
||||
private @Meta Range length;
|
||||
|
||||
@Value("start.x")
|
||||
private double startX;
|
||||
private @Meta double startX;
|
||||
|
||||
@Value("start.y")
|
||||
private double startY;
|
||||
private @Meta double startY;
|
||||
|
||||
@Value("start.z")
|
||||
private double startZ;
|
||||
private @Meta double startZ;
|
||||
|
||||
@Value("start.radius.x")
|
||||
private String radMX;
|
||||
private @Meta String radMX;
|
||||
|
||||
@Value("start.radius.y")
|
||||
private String radMY;
|
||||
private @Meta String radMY;
|
||||
|
||||
@Value("start.radius.z")
|
||||
private String radMZ;
|
||||
private @Meta String radMZ;
|
||||
|
||||
@Value("start.height")
|
||||
private Range height;
|
||||
private @Meta Range height;
|
||||
|
||||
@Value("cut.bottom")
|
||||
@Default
|
||||
private int cutBottom = 0;
|
||||
private @Meta int cutBottom = 0;
|
||||
|
||||
@Value("cut.top")
|
||||
@Default
|
||||
private int cutTop = 0;
|
||||
private @Meta int cutTop = 0;
|
||||
|
||||
@Value("mutate.x")
|
||||
private double mutateX;
|
||||
private @Meta double mutateX;
|
||||
|
||||
@Value("mutate.y")
|
||||
private double mutateY;
|
||||
private @Meta double mutateY;
|
||||
|
||||
@Value("mutate.z")
|
||||
private double mutateZ;
|
||||
private @Meta double mutateZ;
|
||||
|
||||
@Value("palette.top")
|
||||
private CarverPalette top;
|
||||
private @Meta CarverPalette top;
|
||||
|
||||
@Value("palette.bottom")
|
||||
private CarverPalette bottom;
|
||||
private @Meta CarverPalette bottom;
|
||||
|
||||
@Value("palette.outer")
|
||||
private CarverPalette outer;
|
||||
private @Meta CarverPalette outer;
|
||||
|
||||
@Value("palette.inner")
|
||||
private CarverPalette inner;
|
||||
private @Meta CarverPalette inner;
|
||||
|
||||
@Value("shift")
|
||||
@Default
|
||||
private Map<BlockType, MaterialSet> shift = new HashMap<>();
|
||||
private @Meta Map<@Meta BlockType, @Meta MaterialSet> shift = new HashMap<>();
|
||||
|
||||
@Value("update")
|
||||
@Default
|
||||
private MaterialSet update = new MaterialSet();
|
||||
private @Meta MaterialSet update = new MaterialSet();
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
|
@ -4,16 +4,17 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.feature.distributor.distributors.NoiseDistributor;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||
|
||||
public class NoiseDistributorTemplate implements ObjectTemplate<Distributor> {
|
||||
@Value("distribution")
|
||||
private NoiseSampler noise;
|
||||
private @Meta NoiseSampler noise;
|
||||
|
||||
@Value("threshold")
|
||||
@Default
|
||||
private double threshold = 0;
|
||||
private @Meta double threshold = 0;
|
||||
|
||||
@Override
|
||||
public Distributor get() {
|
||||
|
@ -4,13 +4,14 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.feature.distributor.distributors.PointSetDistributor;
|
||||
import com.dfsek.terra.addons.feature.distributor.util.Point;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class PointSetDistributorTemplate implements ObjectTemplate<Distributor> {
|
||||
@Value("points")
|
||||
private Set<Point> points;
|
||||
private @Meta Set<@Meta Point> points;
|
||||
|
||||
@Override
|
||||
public Distributor get() {
|
||||
|
@ -2,13 +2,14 @@ package com.dfsek.terra.addons.feature.distributor.util;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
public class PointTemplate implements ObjectTemplate<Point> {
|
||||
@Value("x")
|
||||
private int x;
|
||||
private @Meta int x;
|
||||
|
||||
@Value("z")
|
||||
private int z;
|
||||
private @Meta int z;
|
||||
|
||||
@Override
|
||||
public Point get() {
|
||||
|
@ -4,6 +4,7 @@ import com.dfsek.tectonic.annotations.Final;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||
@ -16,16 +17,16 @@ public class FeatureTemplate implements AbstractableTemplate {
|
||||
private String id;
|
||||
|
||||
@Value("distributor")
|
||||
private Distributor distributor;
|
||||
private @Meta Distributor distributor;
|
||||
|
||||
@Value("locator")
|
||||
private Locator locator;
|
||||
private @Meta Locator locator;
|
||||
|
||||
@Value("structures.distribution")
|
||||
private NoiseSampler structureNoise;
|
||||
private @Meta NoiseSampler structureNoise;
|
||||
|
||||
@Value("structures.structures")
|
||||
private ProbabilityCollection<Structure> structures;
|
||||
private @Meta ProbabilityCollection<Structure> structures;
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
|
@ -6,6 +6,7 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.flora.flora.gen.BlockLayer;
|
||||
import com.dfsek.terra.addons.flora.flora.gen.TerraFlora;
|
||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||
|
||||
@ -18,50 +19,50 @@ public class FloraTemplate implements AbstractableTemplate {
|
||||
private String id;
|
||||
|
||||
@Value("spawnable")
|
||||
private MaterialSet spawnable;
|
||||
private @Meta MaterialSet spawnable;
|
||||
|
||||
@Value("spawn-blacklist")
|
||||
@Default
|
||||
private boolean spawnBlacklist = false;
|
||||
private @Meta boolean spawnBlacklist = false;
|
||||
|
||||
|
||||
@Value("replaceable")
|
||||
@Default
|
||||
private MaterialSet replaceable = MaterialSet.empty();
|
||||
private @Meta MaterialSet replaceable = MaterialSet.empty();
|
||||
|
||||
@Value("irrigable")
|
||||
@Default
|
||||
private MaterialSet irrigable = null;
|
||||
private @Meta MaterialSet irrigable = null;
|
||||
|
||||
@Value("rotatable")
|
||||
@Default
|
||||
private MaterialSet rotatable = MaterialSet.empty();
|
||||
private @Meta MaterialSet rotatable = MaterialSet.empty();
|
||||
|
||||
@Value("physics")
|
||||
@Default
|
||||
private boolean doPhysics = false;
|
||||
private @Meta boolean doPhysics = false;
|
||||
|
||||
@Value("ceiling")
|
||||
@Default
|
||||
private boolean ceiling = false;
|
||||
private @Meta boolean ceiling = false;
|
||||
|
||||
@Value("search")
|
||||
@Default
|
||||
private TerraFlora.Search search = TerraFlora.Search.UP;
|
||||
private TerraFlora.@Meta Search search = TerraFlora.Search.UP;
|
||||
|
||||
@Value("max-placements")
|
||||
@Default
|
||||
private int maxPlacements = -1;
|
||||
private @Meta int maxPlacements = -1;
|
||||
|
||||
@Value("irrigable-offset")
|
||||
@Default
|
||||
private int irrigableOffset;
|
||||
private @Meta int irrigableOffset;
|
||||
|
||||
@Value("layers")
|
||||
private List<BlockLayer> layers;
|
||||
private @Meta List<@Meta BlockLayer> layers;
|
||||
|
||||
@Value("layer-distribution")
|
||||
private NoiseSampler noiseDistribution;
|
||||
private @Meta NoiseSampler noiseDistribution;
|
||||
|
||||
public NoiseSampler getNoiseDistribution() {
|
||||
return noiseDistribution;
|
||||
|
@ -4,14 +4,15 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.flora.flora.gen.BlockLayer;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
public class BlockLayerTemplate implements ObjectTemplate<BlockLayer> {
|
||||
@Value("layers")
|
||||
private int layers;
|
||||
private @Meta int layers;
|
||||
|
||||
@Value("materials")
|
||||
private ProbabilityCollection<BlockState> data;
|
||||
private @Meta ProbabilityCollection<BlockState> data;
|
||||
|
||||
@Override
|
||||
public BlockLayer get() {
|
||||
|
@ -4,15 +4,16 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.feature.locator.locators.RandomLocator;
|
||||
import com.dfsek.terra.addons.feature.locator.locators.SurfaceLocator;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.structure.feature.Locator;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
|
||||
public class RandomLocatorTemplate implements ObjectTemplate<Locator> {
|
||||
@Value("height")
|
||||
private Range height;
|
||||
private @Meta Range height;
|
||||
|
||||
@Value("amount")
|
||||
private Range amount;
|
||||
private @Meta Range amount;
|
||||
|
||||
@Override
|
||||
public Locator get() {
|
||||
|
@ -4,6 +4,7 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.addons.feature.locator.locators.SurfaceLocator;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.structure.feature.Locator;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
|
||||
@ -11,7 +12,7 @@ public class SurfaceLocatorTemplate implements ObjectTemplate<Locator> {
|
||||
private final TerraPlugin main;
|
||||
|
||||
@Value("range")
|
||||
private Range range;
|
||||
private @Meta Range range;
|
||||
|
||||
public SurfaceLocatorTemplate(TerraPlugin main) {
|
||||
this.main = main;
|
||||
|
@ -3,12 +3,13 @@ package com.dfsek.terra.addons.noise;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class NoiseConfigPackTemplate implements ConfigTemplate {
|
||||
@Value("noise")
|
||||
private Map<String, DimensionApplicableNoiseSampler> noiseBuilderMap;
|
||||
private @Meta Map<String, @Meta DimensionApplicableNoiseSampler> noiseBuilderMap;
|
||||
|
||||
public Map<String, DimensionApplicableNoiseSampler> getNoiseBuilderMap() {
|
||||
return noiseBuilderMap;
|
||||
|
@ -2,14 +2,15 @@ package com.dfsek.terra.addons.noise.config;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
public class DimensionApplicableNoiseSampler implements ObjectTemplate<DimensionApplicableNoiseSampler> {
|
||||
@Value("dimensions")
|
||||
private int dimensions;
|
||||
private @Meta int dimensions;
|
||||
|
||||
@Value(".")
|
||||
private NoiseSampler sampler;
|
||||
private @Meta NoiseSampler sampler;
|
||||
|
||||
public int getDimensions() {
|
||||
return dimensions;
|
||||
|
@ -3,23 +3,20 @@ package com.dfsek.terra.addons.noise.config.templates;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.samplers.DomainWarpedSampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class DomainWarpTemplate extends SamplerTemplate<DomainWarpedSampler> {
|
||||
@Value("warp")
|
||||
private NoiseSampler warp;
|
||||
private @Meta NoiseSampler warp;
|
||||
|
||||
@Value("function")
|
||||
private NoiseSampler function;
|
||||
|
||||
@Value("salt")
|
||||
@Default
|
||||
private int salt = 0;
|
||||
private @Meta NoiseSampler function;
|
||||
|
||||
@Value("amplitude")
|
||||
@Default
|
||||
private double amplitude = 1;
|
||||
private @Meta double amplitude = 1;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -2,6 +2,7 @@ package com.dfsek.terra.addons.noise.config.templates;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -11,7 +12,7 @@ public class FunctionTemplate implements ObjectTemplate<FunctionTemplate> {
|
||||
private List<String> args;
|
||||
|
||||
@Value("function")
|
||||
private String function;
|
||||
private @Meta String function;
|
||||
|
||||
public List<String> getArgs() {
|
||||
return args;
|
||||
|
@ -2,6 +2,7 @@ package com.dfsek.terra.addons.noise.config.templates;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.samplers.ImageSampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
@ -10,13 +11,13 @@ import java.awt.image.BufferedImage;
|
||||
public class ImageSamplerTemplate extends SamplerTemplate<ImageSampler> {
|
||||
|
||||
@Value("image")
|
||||
private BufferedImage image;
|
||||
private @Meta BufferedImage image;
|
||||
|
||||
@Value("frequency")
|
||||
private double frequency;
|
||||
private @Meta double frequency;
|
||||
|
||||
@Value("channel")
|
||||
private ImageSampler.Channel channel;
|
||||
private ImageSampler.@Meta Channel channel;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -5,6 +5,7 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ValidationException;
|
||||
import com.dfsek.terra.addons.noise.samplers.KernelSampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
import java.util.List;
|
||||
@ -13,18 +14,18 @@ import java.util.List;
|
||||
public class KernelTemplate extends SamplerTemplate<KernelSampler> implements ValidatedConfigTemplate {
|
||||
|
||||
@Value("kernel")
|
||||
private List<List<Double>> kernel;
|
||||
private @Meta List<@Meta List<@Meta Double>> kernel;
|
||||
|
||||
@Value("factor")
|
||||
@Default
|
||||
private double factor = 1;
|
||||
private @Meta double factor = 1;
|
||||
|
||||
@Value("function")
|
||||
private NoiseSampler function;
|
||||
private @Meta NoiseSampler function;
|
||||
|
||||
@Value("frequency")
|
||||
@Default
|
||||
private double frequency = 1;
|
||||
private @Meta double frequency = 1;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -5,13 +5,14 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ValidationException;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public abstract class SamplerTemplate<T extends NoiseSampler> implements ValidatedConfigTemplate, ObjectTemplate<NoiseSampler> {
|
||||
@Value("dimensions")
|
||||
@Default
|
||||
private int dimensions = 2;
|
||||
private @Meta int dimensions = 2;
|
||||
|
||||
public int getDimensions() {
|
||||
return dimensions;
|
||||
|
@ -4,26 +4,27 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
||||
@Value("distance")
|
||||
@Default
|
||||
private CellularSampler.DistanceFunction cellularDistanceFunction = CellularSampler.DistanceFunction.EuclideanSq;
|
||||
private CellularSampler.@Meta DistanceFunction cellularDistanceFunction = CellularSampler.DistanceFunction.EuclideanSq;
|
||||
|
||||
@Value("return")
|
||||
@Default
|
||||
private CellularSampler.ReturnType cellularReturnType = CellularSampler.ReturnType.Distance;
|
||||
private CellularSampler.@Meta ReturnType cellularReturnType = CellularSampler.ReturnType.Distance;
|
||||
|
||||
@Value("jitter")
|
||||
@Default
|
||||
private double cellularJitter = 1.0D;
|
||||
private @Meta double cellularJitter = 1.0D;
|
||||
|
||||
|
||||
@Value("lookup")
|
||||
@Default
|
||||
private NoiseSampler lookup = new OpenSimplex2Sampler();
|
||||
private @Meta NoiseSampler lookup = new OpenSimplex2Sampler();
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -4,13 +4,14 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.ConstantSampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class ConstantNoiseTemplate extends SamplerTemplate<ConstantSampler> {
|
||||
@Value("value")
|
||||
@Default
|
||||
private double value = 0d;
|
||||
private @Meta double value = 0d;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -15,6 +15,7 @@ import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.ExpressionFunction;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -27,15 +28,18 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
|
||||
private final Map<String, DimensionApplicableNoiseSampler> otherFunctions;
|
||||
@Value("variables")
|
||||
@Default
|
||||
private Map<String, Double> vars = new HashMap<>();
|
||||
private @Meta Map<String, @Meta Double> vars = new HashMap<>();
|
||||
|
||||
@Value("equation")
|
||||
private String equation;
|
||||
private @Meta String equation;
|
||||
|
||||
@Value("functions")
|
||||
@Default
|
||||
private LinkedHashMap<String, DimensionApplicableNoiseSampler> functions = new LinkedHashMap<>();
|
||||
private @Meta LinkedHashMap<String, @Meta DimensionApplicableNoiseSampler> functions = new LinkedHashMap<>();
|
||||
|
||||
@Value("expressions")
|
||||
@Default
|
||||
private LinkedHashMap<String, FunctionTemplate> expressions = new LinkedHashMap<>();
|
||||
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> expressions = new LinkedHashMap<>();
|
||||
|
||||
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> otherFunctions) {
|
||||
this.otherFunctions = otherFunctions;
|
||||
|
@ -3,28 +3,29 @@ package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.GaborNoiseSampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
|
||||
@Value("rotation")
|
||||
@Default
|
||||
private double rotation = 0.25;
|
||||
private @Meta double rotation = 0.25;
|
||||
|
||||
@Value("isotropic")
|
||||
@Default
|
||||
private boolean isotropic = true;
|
||||
private @Meta boolean isotropic = true;
|
||||
|
||||
@Value("deviation")
|
||||
@Default
|
||||
private double deviation = 1.0;
|
||||
private @Meta double deviation = 1.0;
|
||||
|
||||
@Value("impulses")
|
||||
@Default
|
||||
private double impulses = 64d;
|
||||
private @Meta double impulses = 64d;
|
||||
|
||||
@Value("frequency_0")
|
||||
@Default
|
||||
private double f0 = 0.625;
|
||||
private @Meta double f0 = 0.625;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -4,15 +4,16 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public abstract class NoiseTemplate<T extends NoiseFunction> extends SamplerTemplate<T> {
|
||||
@Value("frequency")
|
||||
@Default
|
||||
protected double frequency = 0.02d;
|
||||
protected @Meta double frequency = 0.02d;
|
||||
|
||||
@Value("salt")
|
||||
@Default
|
||||
protected long salt = 0;
|
||||
protected @Meta long salt = 0;
|
||||
}
|
||||
|
@ -4,25 +4,26 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.fractal.FractalNoiseFunction;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
public abstract class FractalTemplate<T extends FractalNoiseFunction> extends SamplerTemplate<T> {
|
||||
@Value("octaves")
|
||||
@Default
|
||||
protected int octaves = 3;
|
||||
protected @Meta int octaves = 3;
|
||||
|
||||
@Value("gain")
|
||||
@Default
|
||||
protected double fractalGain = 0.5D;
|
||||
protected @Meta double fractalGain = 0.5D;
|
||||
|
||||
@Value("lacunarity")
|
||||
@Default
|
||||
protected double fractalLacunarity = 2.0D;
|
||||
protected @Meta double fractalLacunarity = 2.0D;
|
||||
|
||||
@Value("weighted-strength")
|
||||
@Default
|
||||
protected double weightedStrength = 0.0D;
|
||||
protected @Meta double weightedStrength = 0.0D;
|
||||
|
||||
@Value("function")
|
||||
protected NoiseSampler function;
|
||||
protected @Meta NoiseSampler function;
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.fractal.PingPongSampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class PingPongTemplate extends FractalTemplate<PingPongSampler> {
|
||||
@Value("ping-pong")
|
||||
@Default
|
||||
private double pingPong = 2.0D;
|
||||
private @Meta double pingPong = 2.0D;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -2,15 +2,16 @@ package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.normalizer.ClampNormalizer;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class ClampNormalizerTemplate extends NormalizerTemplate<ClampNormalizer> {
|
||||
@Value("max")
|
||||
private double max;
|
||||
private @Meta double max;
|
||||
|
||||
@Value("min")
|
||||
private double min;
|
||||
private @Meta double min;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -2,15 +2,16 @@ package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.normalizer.LinearNormalizer;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class LinearNormalizerTemplate extends NormalizerTemplate<LinearNormalizer> {
|
||||
@Value("max")
|
||||
private double max;
|
||||
private @Meta double max;
|
||||
|
||||
@Value("min")
|
||||
private double min;
|
||||
private @Meta double min;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -3,19 +3,20 @@ package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.normalizer.NormalNormalizer;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class NormalNormalizerTemplate extends NormalizerTemplate<NormalNormalizer> {
|
||||
@Value("mean")
|
||||
private double mean;
|
||||
private @Meta double mean;
|
||||
|
||||
@Value("standard-deviation")
|
||||
private double stdDev;
|
||||
private @Meta double stdDev;
|
||||
|
||||
@Value("groups")
|
||||
@Default
|
||||
private int groups = 16384;
|
||||
private @Meta int groups = 16384;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
@ -3,9 +3,10 @@ package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.normalizer.Normalizer;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
public abstract class NormalizerTemplate<T extends Normalizer> extends SamplerTemplate<T> {
|
||||
@Value("function")
|
||||
protected NoiseSampler function;
|
||||
protected @Meta NoiseSampler function;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||
|
||||
@ -19,29 +20,29 @@ public class OreTemplate implements AbstractableTemplate {
|
||||
private String id;
|
||||
|
||||
@Value("material")
|
||||
private BlockState material;
|
||||
private @Meta BlockState material;
|
||||
|
||||
@Value("material-overrides")
|
||||
@Default
|
||||
private Map<BlockType, BlockState> materials = new HashMap<>();
|
||||
private @Meta Map<@Meta BlockType, @Meta BlockState> materials = new HashMap<>();
|
||||
|
||||
@Value("replace")
|
||||
private MaterialSet replaceable;
|
||||
private @Meta MaterialSet replaceable;
|
||||
|
||||
@Value("physics")
|
||||
@Default
|
||||
private boolean physics = false;
|
||||
private @Meta boolean physics = false;
|
||||
|
||||
@Value("size")
|
||||
private Range size;
|
||||
private @Meta Range size;
|
||||
|
||||
@Value("deform")
|
||||
@Default
|
||||
private double deform = 0.75D;
|
||||
private @Meta double deform = 0.75D;
|
||||
|
||||
@Value("deform-frequency")
|
||||
@Default
|
||||
private double deformFrequency = 0.1D;
|
||||
private @Meta double deformFrequency = 0.1D;
|
||||
|
||||
public double getDeform() {
|
||||
return deform;
|
||||
|
@ -5,6 +5,7 @@ import com.dfsek.tectonic.annotations.Final;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
@ -13,14 +14,14 @@ import java.util.List;
|
||||
public class PaletteTemplate implements AbstractableTemplate {
|
||||
@Value("noise")
|
||||
@Default
|
||||
private NoiseSampler noise = NoiseSampler.zero();
|
||||
private @Meta NoiseSampler noise = NoiseSampler.zero();
|
||||
|
||||
@Value("id")
|
||||
@Final
|
||||
private String id;
|
||||
|
||||
@Value("layers")
|
||||
private List<PaletteLayerHolder> palette;
|
||||
private @Meta List<@Meta PaletteLayerHolder> palette;
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.addons.structure;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -11,7 +12,7 @@ import java.util.Set;
|
||||
public class BiomeStructuresTemplate implements ObjectTemplate<BiomeStructures> {
|
||||
@Value("structures")
|
||||
@Default
|
||||
private Set<ConfiguredStructure> structures = Collections.emptySet();
|
||||
private @Meta Set<@Meta ConfiguredStructure> structures = Collections.emptySet();
|
||||
|
||||
@Override
|
||||
public BiomeStructures get() {
|
||||
|
@ -4,6 +4,7 @@ import com.dfsek.tectonic.annotations.Final;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.structure.StructureSpawn;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
@ -16,13 +17,13 @@ public class StructureTemplate implements AbstractableTemplate, ConfigTemplate {
|
||||
private String id;
|
||||
|
||||
@Value("scripts")
|
||||
private ProbabilityCollection<Structure> structure;
|
||||
private @Meta ProbabilityCollection<@Meta Structure> structure;
|
||||
|
||||
@Value("spawn.start")
|
||||
private Range y;
|
||||
private @Meta Range y;
|
||||
|
||||
@Value("spawn")
|
||||
private StructureSpawn spawn;
|
||||
private @Meta StructureSpawn spawn;
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.addons.generation.feature.config;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.structure.feature.Feature;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -11,7 +12,7 @@ import java.util.List;
|
||||
public class BiomeFeaturesTemplate implements ObjectTemplate<BiomeFeatures> {
|
||||
@Value("features")
|
||||
@Default
|
||||
private List<Feature> features = Collections.emptyList();
|
||||
private @Meta List<@Meta Feature> features = Collections.emptyList();
|
||||
|
||||
@Override
|
||||
public BiomeFeatures get() {
|
||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.addons.generation.flora;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -10,7 +11,7 @@ import java.util.List;
|
||||
public class BiomeFloraTemplate implements ObjectTemplate<BiomeFlora> {
|
||||
@Value("flora")
|
||||
@Default
|
||||
private List<FloraLayer> flora = Collections.emptyList();
|
||||
private @Meta List<@Meta FloraLayer> flora = Collections.emptyList();
|
||||
|
||||
@Override
|
||||
public BiomeFlora get() {
|
||||
|
@ -2,6 +2,7 @@ package com.dfsek.terra.addons.generation.flora;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
@ -9,16 +10,16 @@ import com.dfsek.terra.api.world.Flora;
|
||||
|
||||
public class FloraLayerLoader implements ObjectTemplate<FloraLayer> {
|
||||
@Value("density")
|
||||
private double density;
|
||||
private @Meta double density;
|
||||
|
||||
@Value("y")
|
||||
private Range y;
|
||||
private @Meta Range y;
|
||||
|
||||
@Value("items")
|
||||
private ProbabilityCollection<Flora> items;
|
||||
private @Meta ProbabilityCollection<@Meta Flora> items;
|
||||
|
||||
@Value("distribution")
|
||||
private NoiseSampler distribution;
|
||||
private @Meta NoiseSampler distribution;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -23,6 +23,9 @@ public class YamlAddon extends TerraAddon implements EventListener {
|
||||
}
|
||||
|
||||
public void loadYamlConfigs(ConfigurationDiscoveryEvent event) {
|
||||
event.getLoader().open("", ".yml").thenEntries(entries -> entries.forEach(entry -> event.register(new YamlConfiguration(entry.getValue(), entry.getKey()))));
|
||||
event.getLoader().open("", ".yml").thenEntries(entries -> entries.forEach(entry -> {
|
||||
main.getDebugLogger().info("Discovered config " + entry.getKey());
|
||||
event.register(entry.getKey(), new YamlConfiguration(entry.getValue(), entry.getKey()));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ group = "com.dfsek.terra.common"
|
||||
dependencies {
|
||||
"shadedApi"("com.dfsek:Paralithic:0.4.0")
|
||||
|
||||
"shadedApi"("com.dfsek.tectonic:common:2.1.1")
|
||||
"shadedApi"("com.dfsek.tectonic:yaml:2.1.1")
|
||||
"shadedApi"("com.dfsek.tectonic:common:2.1.2")
|
||||
"shadedApi"("com.dfsek.tectonic:yaml:2.1.2")
|
||||
|
||||
"shadedApi"("net.jafama:jafama:2.3.2")
|
||||
"shadedApi"("org.yaml:snakeyaml:1.27")
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.dfsek.terra.api.config.meta;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE_USE)
|
||||
public @interface Meta {
|
||||
}
|
@ -5,6 +5,7 @@ import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@ -17,9 +18,9 @@ public class ConfigurationDiscoveryEvent implements PackEvent {
|
||||
private final ConfigPack pack;
|
||||
private final Loader loader;
|
||||
|
||||
private final Consumer<Configuration> consumer;
|
||||
private final BiConsumer<String, Configuration> consumer;
|
||||
|
||||
public ConfigurationDiscoveryEvent(ConfigPack pack, Loader loader, Consumer<Configuration> consumer) {
|
||||
public ConfigurationDiscoveryEvent(ConfigPack pack, Loader loader, BiConsumer<String, Configuration> consumer) {
|
||||
this.pack = pack;
|
||||
this.loader = loader;
|
||||
this.consumer = consumer;
|
||||
@ -34,7 +35,7 @@ public class ConfigurationDiscoveryEvent implements PackEvent {
|
||||
return loader;
|
||||
}
|
||||
|
||||
public void register(Configuration config) {
|
||||
consumer.accept(config);
|
||||
public void register(String identifier, Configuration config) {
|
||||
consumer.accept(identifier, config);
|
||||
}
|
||||
}
|
||||
|
@ -7,17 +7,20 @@ import java.util.Objects;
|
||||
public class TypeKey<T> {
|
||||
final Class<? super T> rawType;
|
||||
final Type type;
|
||||
|
||||
final AnnotatedType annotatedType;
|
||||
final int hashCode;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected TypeKey() {
|
||||
this.type = getSuperclassTypeParameter(getClass());
|
||||
this.annotatedType = getAnnotatedSuperclassTypeParameter(getClass());
|
||||
this.rawType = (Class<? super T>) ReflectionUtil.getRawType(type);
|
||||
this.hashCode = type.hashCode();
|
||||
}
|
||||
|
||||
|
||||
static Type getSuperclassTypeParameter(Class<?> subclass) {
|
||||
private static Type getSuperclassTypeParameter(Class<?> subclass) {
|
||||
Type superclass = subclass.getGenericSuperclass();
|
||||
if(superclass instanceof Class) {
|
||||
throw new RuntimeException("Missing type parameter.");
|
||||
@ -26,6 +29,15 @@ public class TypeKey<T> {
|
||||
return parameterized.getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
private static AnnotatedType getAnnotatedSuperclassTypeParameter(Class<?> subclass) {
|
||||
AnnotatedType superclass = subclass.getAnnotatedSuperclass();
|
||||
if(superclass.getType() instanceof Class) {
|
||||
throw new RuntimeException("Missing type parameter.");
|
||||
}
|
||||
AnnotatedParameterizedType parameterized = (AnnotatedParameterizedType) superclass;
|
||||
return parameterized.getAnnotatedActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw (non-generic) type for this type.
|
||||
*/
|
||||
@ -40,6 +52,10 @@ public class TypeKey<T> {
|
||||
return type;
|
||||
}
|
||||
|
||||
public AnnotatedType getAnnotatedType() {
|
||||
return annotatedType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return this.hashCode;
|
||||
|
@ -21,6 +21,8 @@ dependencies {
|
||||
|
||||
"shadedApi"("commons-io:commons-io:2.6")
|
||||
|
||||
"shadedImplementation"("org.apache.commons:commons-text:1.9")
|
||||
|
||||
|
||||
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||
|
||||
|
@ -31,7 +31,6 @@ public class FolderLoader extends LoaderImpl {
|
||||
paths.filter(Files::isRegularFile).filter(file -> file.toString().toLowerCase().endsWith(extension)).forEach(file -> {
|
||||
try {
|
||||
String rel = newPath.toPath().relativize(file).toString();
|
||||
if(rel.equals("pack.yml")) return;
|
||||
streams.put(rel, new FileInputStream(file.toFile()));
|
||||
} catch(FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -27,7 +27,6 @@ public class ZIPLoader extends LoaderImpl {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(entry.getName().equals("pack.yml")) continue;
|
||||
if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(extension)) {
|
||||
try {
|
||||
String rel = entry.getName().substring(directory.length());
|
||||
|
@ -18,6 +18,7 @@ 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.config.Loader;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.event.events.config.ConfigurationDiscoveryEvent;
|
||||
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent;
|
||||
@ -40,6 +41,9 @@ import com.dfsek.terra.config.fileloaders.FolderLoader;
|
||||
import com.dfsek.terra.config.fileloaders.ZIPLoader;
|
||||
import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader;
|
||||
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
|
||||
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaStringPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor;
|
||||
import com.dfsek.terra.config.prototype.ProtoConfig;
|
||||
import com.dfsek.terra.registry.CheckedRegistryImpl;
|
||||
import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||
@ -234,16 +238,30 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
varScope.create(var.getKey(), var.getValue());
|
||||
}
|
||||
|
||||
List<Configuration> configurations = new ArrayList<>();
|
||||
Map<String, Configuration> configurations = new HashMap<>();
|
||||
|
||||
main.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader, configurations::add)); // Create all the configs.
|
||||
main.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader, configurations::put)); // Create all the configs.
|
||||
|
||||
MetaValuePreprocessor valuePreprocessor = new MetaValuePreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
|
||||
MetaListLikePreprocessor listPreprocessor = new MetaListLikePreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, listPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, listPreprocessor);
|
||||
|
||||
MetaStringPreprocessor stringPreprocessor = new MetaStringPreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, stringPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, stringPreprocessor);
|
||||
|
||||
Map<ConfigType<? extends ConfigTemplate, ?>, List<Configuration>> configs = new HashMap<>();
|
||||
|
||||
for(Configuration configuration : configurations) { // Sort the configs
|
||||
ProtoConfig config = new ProtoConfig();
|
||||
selfLoader.load(config, configuration);
|
||||
configs.computeIfAbsent(config.getType(), configType -> new ArrayList<>()).add(configuration);
|
||||
for(Configuration configuration : configurations.values()) { // Sort the configs
|
||||
if(configuration.contains("type")) { // Only sort configs with type key
|
||||
ProtoConfig config = new ProtoConfig();
|
||||
selfLoader.load(config, configuration);
|
||||
configs.computeIfAbsent(config.getType(), configType -> new ArrayList<>()).add(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
for(ConfigType<?, ?> configType : configTypeRegistry.entries()) { // Load the configs
|
||||
|
@ -2,11 +2,12 @@ package com.dfsek.terra.config.pack;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
public class ConfigPackPostTemplate implements ConfigTemplate {
|
||||
@Value("biomes")
|
||||
private BiomeProvider providerBuilder;
|
||||
private @Meta BiomeProvider providerBuilder;
|
||||
|
||||
public BiomeProvider getProviderBuilder() {
|
||||
return providerBuilder;
|
||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.config.pack;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider;
|
||||
import com.dfsek.terra.api.world.generator.GenerationStageProvider;
|
||||
|
||||
@ -18,35 +19,35 @@ public class ConfigPackTemplate implements ConfigTemplate {
|
||||
|
||||
@Value("variables")
|
||||
@Default
|
||||
private Map<String, Double> variables = new HashMap<>();
|
||||
private @Meta Map<String, @Meta Double> variables = new HashMap<>();
|
||||
|
||||
@Value("beta.carving")
|
||||
@Default
|
||||
private boolean betaCarvers = false;
|
||||
private @Meta boolean betaCarvers = false;
|
||||
|
||||
@Value("structures.locatable")
|
||||
@Default
|
||||
private Map<String, String> locatable = new HashMap<>();
|
||||
private @Meta Map<@Meta String, @Meta String> locatable = new HashMap<>();
|
||||
|
||||
@Value("blend.terrain.elevation")
|
||||
@Default
|
||||
private int elevationBlend = 4;
|
||||
private @Meta int elevationBlend = 4;
|
||||
|
||||
@Value("vanilla.mobs")
|
||||
@Default
|
||||
private boolean vanillaMobs = true;
|
||||
private @Meta boolean vanillaMobs = true;
|
||||
|
||||
@Value("vanilla.caves")
|
||||
@Default
|
||||
private boolean vanillaCaves = false;
|
||||
private @Meta boolean vanillaCaves = false;
|
||||
|
||||
@Value("vanilla.decorations")
|
||||
@Default
|
||||
private boolean vanillaDecorations = false;
|
||||
private @Meta boolean vanillaDecorations = false;
|
||||
|
||||
@Value("vanilla.structures")
|
||||
@Default
|
||||
private boolean vanillaStructures = false;
|
||||
private @Meta boolean vanillaStructures = false;
|
||||
|
||||
@Value("author")
|
||||
@Default
|
||||
@ -54,10 +55,10 @@ public class ConfigPackTemplate implements ConfigTemplate {
|
||||
|
||||
@Value("disable.sapling")
|
||||
@Default
|
||||
private boolean disableSaplings = false;
|
||||
private @Meta boolean disableSaplings = false;
|
||||
|
||||
@Value("stages")
|
||||
private List<GenerationStageProvider> stages;
|
||||
private @Meta List<@Meta GenerationStageProvider> stages;
|
||||
|
||||
@Value("version")
|
||||
@Default
|
||||
@ -65,26 +66,26 @@ public class ConfigPackTemplate implements ConfigTemplate {
|
||||
|
||||
@Value("disable.carvers")
|
||||
@Default
|
||||
private boolean disableCarvers = false;
|
||||
private @Meta boolean disableCarvers = false;
|
||||
|
||||
@Value("disable.structures")
|
||||
@Default
|
||||
private boolean disableStructures = false;
|
||||
private @Meta boolean disableStructures = false;
|
||||
|
||||
@Value("disable.ores")
|
||||
@Default
|
||||
private boolean disableOres = false;
|
||||
private @Meta boolean disableOres = false;
|
||||
|
||||
@Value("disable.trees")
|
||||
@Default
|
||||
private boolean disableTrees = false;
|
||||
private @Meta boolean disableTrees = false;
|
||||
|
||||
@Value("disable.flora")
|
||||
@Default
|
||||
private boolean disableFlora = false;
|
||||
private @Meta boolean disableFlora = false;
|
||||
|
||||
@Value("generator")
|
||||
private ChunkGeneratorProvider generatorProvider;
|
||||
private @Meta ChunkGeneratorProvider generatorProvider;
|
||||
|
||||
public ChunkGeneratorProvider getGeneratorProvider() {
|
||||
return generatorProvider;
|
||||
|
@ -0,0 +1,63 @@
|
||||
package com.dfsek.terra.config.preprocessor;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class MetaListLikePreprocessor extends MetaPreprocessor<Meta> {
|
||||
public MetaListLikePreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
if(t.getType() instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) t.getType();
|
||||
if(parameterizedType.getRawType() instanceof Class) { // Should always be true but we check anyways
|
||||
Class<?> baseClass = (Class<?>) parameterizedType.getRawType();
|
||||
|
||||
if((List.class.isAssignableFrom(baseClass) || Set.class.isAssignableFrom(baseClass)) && c instanceof List) { // List or set metaconfig
|
||||
List<Object> list = (List<Object>) c;
|
||||
|
||||
int offset = 0;
|
||||
List<Object> newList = new ArrayList<>((List<Object>) c);
|
||||
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
Object o = list.get(i);
|
||||
if(!(o instanceof String)) continue;
|
||||
String s = ((String) o).trim();
|
||||
if(!s.startsWith("<< ")) continue;
|
||||
String meta = s.substring(3);
|
||||
|
||||
Object metaValue = getMetaValue(meta);
|
||||
|
||||
if(!(metaValue instanceof List)) {
|
||||
throw new LoadException("MetaList/Set injection candidate must be list, is type " + metaValue.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
List<Object> metaList = (List<Object>) metaValue;
|
||||
|
||||
newList.remove(i + offset); // Remove placeholder
|
||||
newList.addAll(i + offset, metaList); // Add metalist values where placeholder was
|
||||
offset += metaList.size() - 1; // add metalist size to offset, subtract one to account for placeholder.
|
||||
}
|
||||
|
||||
return (Result<T>) Result.overwrite(newList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result.noOp();
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.dfsek.terra.config.preprocessor;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaMapPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public MetaMapPreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
private static final TypeKey<List<String>> STRING_LIST = new TypeKey<>() {};
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
if(t.getType() instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) t.getType();
|
||||
if(parameterizedType.getRawType() instanceof Class) { // Should always be true but we check anyways
|
||||
Class<?> baseClass = (Class<?>) parameterizedType.getRawType();
|
||||
|
||||
if(Map.class.isAssignableFrom(baseClass) && c instanceof Map) { // Map metaconfig
|
||||
Map<Object, Object> map = (Map<Object, Object>) c;
|
||||
|
||||
Map<Object, Object> newMap = new HashMap<>(map);
|
||||
|
||||
if(map.containsKey("<<")) {
|
||||
newMap.putAll(map);
|
||||
newMap.remove("<<"); // Remove placeholder
|
||||
|
||||
List<String> keys = (List<String>) loader.loadType(STRING_LIST.getAnnotatedType(), map.get("<<"));
|
||||
keys.forEach(key -> {
|
||||
Object meta = getMetaValue(key);
|
||||
if(!(meta instanceof Map)) {
|
||||
throw new LoadException("MetaMap injection candidate must be list, is type " + meta.getClass().getCanonicalName());
|
||||
}
|
||||
newMap.putAll((Map<?, ?>) meta);
|
||||
});
|
||||
return (Result<T>) Result.overwrite(newMap);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result.noOp();
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.dfsek.terra.config.preprocessor;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.tectonic.util.ReflectionUtil;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public static final TypeKey<String> META_STRING_KEY = new TypeKey<@Meta String>() {};
|
||||
|
||||
public MetaNumberPreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
if(t.getType() instanceof Class && isNumber((Class<?>) t.getType()) && c instanceof String) {
|
||||
String expression = (String) loader.loadType(META_STRING_KEY.getAnnotatedType(), c);
|
||||
try {
|
||||
return (Result<T>) Result.overwrite(new Parser().parse(expression).evaluate());
|
||||
} catch(ParseException e) {
|
||||
throw new LoadException("Invalid expression: ", e);
|
||||
}
|
||||
}
|
||||
return Result.noOp();
|
||||
}
|
||||
|
||||
private static boolean isNumber(Class<?> clazz) {
|
||||
return Number.class.isAssignableFrom(clazz)
|
||||
|| byte.class.equals(clazz)
|
||||
|| int.class.equals(clazz)
|
||||
|| long.class.equals(clazz)
|
||||
|| float.class.equals(clazz)
|
||||
|| double.class.equals(clazz);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.config.preprocessor;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.preprocessor.ValuePreprocessor;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class MetaPreprocessor<A extends Annotation> implements ValuePreprocessor<A> {
|
||||
private final Map<String, Configuration> configs;
|
||||
|
||||
public MetaPreprocessor(Map<String, Configuration> configs) {
|
||||
this.configs = configs;
|
||||
}
|
||||
|
||||
protected Object getMetaValue(String meta) {
|
||||
int sep = meta.indexOf(':');
|
||||
String file = meta.substring(0, sep);
|
||||
String key = meta.substring(sep + 1);
|
||||
|
||||
if(!configs.containsKey(file)) throw new LoadException("Cannot fetch metavalue: No such config: " + file);
|
||||
|
||||
Configuration config = configs.get(file);
|
||||
|
||||
if(!config.contains(key)) {
|
||||
throw new LoadException("Cannot fetch metavalue: No such key " + key + " in configuration " + config.getName());
|
||||
}
|
||||
|
||||
return config.get(key);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.dfsek.terra.config.preprocessor;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import org.apache.commons.text.StringSubstitutor;
|
||||
import org.apache.commons.text.lookup.StringLookup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaStringPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public MetaStringPreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
if(String.class.equals(t.getType()) && c instanceof String) { // String is final so we use #equals
|
||||
String candidate = (String) c;
|
||||
StringSubstitutor substitutor = new StringSubstitutor(key -> {
|
||||
Object meta = getMetaValue(key);
|
||||
if(!(meta instanceof String) && !(meta instanceof Number) && !(meta instanceof Character) && !(meta instanceof Boolean)) {
|
||||
throw new LoadException("MetaString template injection candidate must be string or primitive, is type " + meta.getClass().getCanonicalName());
|
||||
}
|
||||
return meta.toString();
|
||||
});
|
||||
return (Result<T>) Result.overwrite(substitutor.replace(candidate));
|
||||
}
|
||||
return Result.noOp();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.dfsek.terra.config.preprocessor;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaValuePreprocessor extends MetaPreprocessor<Meta> {
|
||||
|
||||
public MetaValuePreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader configLoader, Meta annotation) {
|
||||
if(c instanceof String) { // Can we do standard metaconfig?
|
||||
String value = ((String) c).trim();
|
||||
if(value.startsWith("$")) { // it's a meta value.
|
||||
return (Result<T>) Result.overwrite(getMetaValue(value.substring(1)));
|
||||
}
|
||||
}
|
||||
return Result.noOp();
|
||||
}
|
||||
}
|
127
common/implementation/src/test/java/MetaTest.java
Normal file
127
common/implementation/src/test/java/MetaTest.java
Normal file
@ -0,0 +1,127 @@
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.yaml.YamlConfiguration;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaMapPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaStringPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaTest {
|
||||
@Test
|
||||
public void testMetaList() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
loader.load(new MetaListConfig(), meta).list.forEach(System.out::println);
|
||||
}
|
||||
|
||||
private static final class MetaListConfig implements ConfigTemplate {
|
||||
@Value("list")
|
||||
private @Meta List<@Meta String> list;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaMap() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
loader.load(new MetaMapConfig(), meta).map.forEach((k, v) -> System.out.println(k + ": " + v));
|
||||
}
|
||||
|
||||
private static final class MetaMapConfig implements ConfigTemplate {
|
||||
@Value("map")
|
||||
private @Meta Map<@Meta String, @Meta String> map;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaString() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
System.out.println(loader.load(new MetaStringConfig(), meta).string);
|
||||
}
|
||||
|
||||
private static final class MetaStringConfig implements ConfigTemplate {
|
||||
@Value("string")
|
||||
private @Meta String string;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaNumber() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
System.out.println("int: " + loader.load(new MetaNumberConfig(), meta).integer);
|
||||
System.out.println("double: " + loader.load(new MetaNumberConfig(), meta).aDouble);
|
||||
}
|
||||
|
||||
private static final class MetaNumberConfig implements ConfigTemplate {
|
||||
@Value("int")
|
||||
private @Meta int integer;
|
||||
|
||||
@Value("double")
|
||||
private @Meta double aDouble;
|
||||
}
|
||||
}
|
@ -3,15 +3,16 @@ package noise;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
public class ColorConfigTemplate implements ConfigTemplate {
|
||||
@Value("colors")
|
||||
private ProbabilityCollection<Integer> colors;
|
||||
private @Meta ProbabilityCollection<@Meta Integer> colors;
|
||||
|
||||
@Value("enable")
|
||||
@Default
|
||||
private boolean enable = false;
|
||||
private @Meta boolean enable = false;
|
||||
|
||||
public boolean enable() {
|
||||
return enable;
|
||||
|
18
common/implementation/src/test/resources/meta.yml
Normal file
18
common/implementation/src/test/resources/meta.yml
Normal file
@ -0,0 +1,18 @@
|
||||
list:
|
||||
- ONE
|
||||
- "<< metaTarget.yml:list"
|
||||
- FOUR
|
||||
- FIVE
|
||||
- SIX
|
||||
- "<< metaTarget.yml:list2"
|
||||
- NINE
|
||||
- TEN
|
||||
map:
|
||||
"<<":
|
||||
- metaTarget.yml:map1
|
||||
- metaTarget.yml:map2
|
||||
one: ONE
|
||||
two: TWO
|
||||
string: "one-${metaTarget.yml:string.two}-${metaTarget.yml:string.three}-four-five-${metaTarget.yml:string.six}"
|
||||
int: 2 + 4
|
||||
double: ${metaTarget.yml:double} + 5.6
|
17
common/implementation/src/test/resources/metaTarget.yml
Normal file
17
common/implementation/src/test/resources/metaTarget.yml
Normal file
@ -0,0 +1,17 @@
|
||||
list:
|
||||
- TWO
|
||||
- THREE
|
||||
list2:
|
||||
- SEVEN
|
||||
- EIGHT
|
||||
map1:
|
||||
three: THREE
|
||||
four: FOUR
|
||||
five: FIVE
|
||||
map2:
|
||||
six: SIX
|
||||
string:
|
||||
two: two
|
||||
three: three
|
||||
six: six
|
||||
double: 1
|
@ -253,7 +253,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
if(config.isDebugProfiler()) profiler.start();
|
||||
|
||||
if(!addonRegistry.loadAll(getClass().getClassLoader())) {
|
||||
throw new IllegalStateException("Failed to load addons. Please correct com.dfsek.terra.addon installations to continue.");
|
||||
throw new IllegalStateException("Failed to load addons. Please correct addon installations to continue.");
|
||||
}
|
||||
logger.info("Loaded addons.");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user