commit 41e6b7f243c87e98d2203fcacd02816f0de1f849 Author: dfsek Date: Sun Oct 17 15:05:52 2021 -0700 Initial commit diff --git a/common/addons/config-locators/build.gradle.kts b/common/addons/config-locators/build.gradle.kts new file mode 100644 index 000000000..7d82dc72f --- /dev/null +++ b/common/addons/config-locators/build.gradle.kts @@ -0,0 +1,2 @@ +dependencies { +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/LocatorAddon.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/LocatorAddon.java new file mode 100644 index 000000000..bffc6a2d5 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/LocatorAddon.java @@ -0,0 +1,76 @@ +package com.dfsek.terra.addons.feature.locator; + +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import java.util.function.Supplier; + +import com.dfsek.terra.addons.feature.locator.config.AndLocatorTemplate; +import com.dfsek.terra.addons.feature.locator.config.Noise3DLocatorTemplate; +import com.dfsek.terra.addons.feature.locator.config.NoiseLocatorTemplate; +import com.dfsek.terra.addons.feature.locator.config.OrLocatorTemplate; +import com.dfsek.terra.addons.feature.locator.config.PatternLocatorTemplate; +import com.dfsek.terra.addons.feature.locator.config.RandomLocatorTemplate; +import com.dfsek.terra.addons.feature.locator.config.SurfaceLocatorTemplate; +import com.dfsek.terra.addons.feature.locator.config.pattern.AirMatchPatternTemplate; +import com.dfsek.terra.addons.feature.locator.config.pattern.AndPatternTemplate; +import com.dfsek.terra.addons.feature.locator.config.pattern.BlockSetMatchPatternTemplate; +import com.dfsek.terra.addons.feature.locator.config.pattern.NotPatternTemplate; +import com.dfsek.terra.addons.feature.locator.config.pattern.OrPatternTemplate; +import com.dfsek.terra.addons.feature.locator.config.pattern.SingleBlockMatchPatternTemplate; +import com.dfsek.terra.addons.feature.locator.config.pattern.SolidMatchPatternTemplate; +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +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; +import com.dfsek.terra.api.registry.CheckedRegistry; +import com.dfsek.terra.api.structure.feature.Locator; +import com.dfsek.terra.api.util.reflection.TypeKey; + + +@Addon("config-locators") +@Version("1.0.0") +@Author("Terra") +public class LocatorAddon extends TerraAddon { + + public static final TypeKey>> LOCATOR_TOKEN = new TypeKey<>() { + }; + public static final TypeKey>> PATTERN_TOKEN = new TypeKey<>() { + }; + @Inject + private Platform platform; + + @Override + public void initialize() { + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(this, ConfigPackPreLoadEvent.class) + .then(event -> { + CheckedRegistry>> locatorRegistry = event.getPack().getOrCreateRegistry(LOCATOR_TOKEN); + locatorRegistry.register("SURFACE", () -> new SurfaceLocatorTemplate(platform)); + locatorRegistry.register("RANDOM", RandomLocatorTemplate::new); + locatorRegistry.register("PATTERN", PatternLocatorTemplate::new); + locatorRegistry.register("NOISE", NoiseLocatorTemplate::new); + locatorRegistry.register("NOISE_3D", Noise3DLocatorTemplate::new); + + locatorRegistry.register("AND", AndLocatorTemplate::new); + locatorRegistry.register("OR", OrLocatorTemplate::new); + }) + .then(event -> { + CheckedRegistry>> patternRegistry = event.getPack().getOrCreateRegistry(PATTERN_TOKEN); + patternRegistry.register("MATCH_AIR", AirMatchPatternTemplate::new); + patternRegistry.register("MATCH_SOLID", SolidMatchPatternTemplate::new); + patternRegistry.register("MATCH", SingleBlockMatchPatternTemplate::new); + patternRegistry.register("MATCH_SET", BlockSetMatchPatternTemplate::new); + + patternRegistry.register("AND", AndPatternTemplate::new); + patternRegistry.register("OR", OrPatternTemplate::new); + patternRegistry.register("NOT", NotPatternTemplate::new); + }) + .failThrough(); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/AndLocatorTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/AndLocatorTemplate.java new file mode 100644 index 000000000..404c38a8a --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/AndLocatorTemplate.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.feature.locator.config; + +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 java.util.List; + +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.structure.feature.Locator; + + +public class AndLocatorTemplate implements ObjectTemplate, ValidatedConfigTemplate { + @Value("locators") + private @Meta List<@Meta Locator> locators; + + @Override + public Locator get() { + Locator current = locators.remove(0); + while(!locators.isEmpty()) { + current = current.and(locators.remove(0)); + } + return current; + } + + @Override + public boolean validate() throws ValidationException { + if(locators.isEmpty()) throw new ValidationException("AND Pattern must specify at least 1 pattern."); + return true; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/Noise3DLocatorTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/Noise3DLocatorTemplate.java new file mode 100644 index 000000000..2a61e39dd --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/Noise3DLocatorTemplate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.feature.locator.config; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import com.dfsek.terra.addons.feature.locator.locators.Noise3DLocator; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.structure.feature.Locator; + + +public class Noise3DLocatorTemplate implements ObjectTemplate { + @Value("sampler") + private @Meta NoiseSampler sampler; + + @Override + public Locator get() { + return new Noise3DLocator(sampler); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/NoiseLocatorTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/NoiseLocatorTemplate.java new file mode 100644 index 000000000..ca0f33137 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/NoiseLocatorTemplate.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.feature.locator.config; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import java.util.List; + +import com.dfsek.terra.addons.feature.locator.locators.NoiseLocator; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.structure.feature.Locator; + + +public class NoiseLocatorTemplate implements ObjectTemplate { + @Value("samplers") + private @Meta List<@Meta NoiseSampler> samplers; + + @Override + public Locator get() { + return new NoiseLocator(samplers); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/OrLocatorTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/OrLocatorTemplate.java new file mode 100644 index 000000000..38e0d660c --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/OrLocatorTemplate.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.feature.locator.config; + +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 java.util.List; + +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.structure.feature.Locator; + + +public class OrLocatorTemplate implements ObjectTemplate, ValidatedConfigTemplate { + @Value("locators") + private @Meta List<@Meta Locator> locators; + + @Override + public Locator get() { + Locator current = locators.remove(0); + while(!locators.isEmpty()) { + current = current.or(locators.remove(0)); + } + return current; + } + + @Override + public boolean validate() throws ValidationException { + if(locators.isEmpty()) throw new ValidationException("AND Pattern must specify at least 1 pattern."); + return true; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/PatternLocatorTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/PatternLocatorTemplate.java new file mode 100644 index 000000000..c27054675 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/PatternLocatorTemplate.java @@ -0,0 +1,24 @@ +package com.dfsek.terra.addons.feature.locator.config; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import com.dfsek.terra.addons.feature.locator.locators.PatternLocator; +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +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 PatternLocatorTemplate implements ObjectTemplate { + @Value("range") + private @Meta Range range; + + @Value("pattern") + private @Meta Pattern pattern; + + @Override + public Locator get() { + return new PatternLocator(pattern, range); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/RandomLocatorTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/RandomLocatorTemplate.java new file mode 100644 index 000000000..347294d3f --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/RandomLocatorTemplate.java @@ -0,0 +1,23 @@ +package com.dfsek.terra.addons.feature.locator.config; + +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.api.config.meta.Meta; +import com.dfsek.terra.api.structure.feature.Locator; +import com.dfsek.terra.api.util.Range; + + +public class RandomLocatorTemplate implements ObjectTemplate { + @Value("height") + private @Meta Range height; + + @Value("amount") + private @Meta Range amount; + + @Override + public Locator get() { + return new RandomLocator(height, amount); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/SurfaceLocatorTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/SurfaceLocatorTemplate.java new file mode 100644 index 000000000..fce147df8 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/SurfaceLocatorTemplate.java @@ -0,0 +1,27 @@ +package com.dfsek.terra.addons.feature.locator.config; + +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.Platform; +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 SurfaceLocatorTemplate implements ObjectTemplate { + private final Platform platform; + + @Value("range") + private @Meta Range range; + + public SurfaceLocatorTemplate(Platform platform) { + this.platform = platform; + } + + @Override + public Locator get() { + return new SurfaceLocator(range, platform); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/AirMatchPatternTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/AirMatchPatternTemplate.java new file mode 100644 index 000000000..dfd65ec38 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/AirMatchPatternTemplate.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.feature.locator.config.pattern; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern; +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.util.Range; + + +public class AirMatchPatternTemplate implements ObjectTemplate { + @Value("offset") + private @Meta Range offset; + + + @Override + public Pattern get() { + return new MatchPattern(offset, BlockState::isAir); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/AndPatternTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/AndPatternTemplate.java new file mode 100644 index 000000000..78ff11428 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/AndPatternTemplate.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.feature.locator.config.pattern; + +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 java.util.List; + +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.config.meta.Meta; + + +public class AndPatternTemplate implements ObjectTemplate, ValidatedConfigTemplate { + @Value("patterns") + private @Meta List<@Meta Pattern> patterns; + + @Override + public Pattern get() { + Pattern current = patterns.remove(0); + while(!patterns.isEmpty()) { + current = current.and(patterns.remove(0)); + } + return current; + } + + @Override + public boolean validate() throws ValidationException { + if(patterns.isEmpty()) throw new ValidationException("AND Pattern must specify at least 1 pattern."); + return true; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/BlockSetMatchPatternTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/BlockSetMatchPatternTemplate.java new file mode 100644 index 000000000..6f15ac36d --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/BlockSetMatchPatternTemplate.java @@ -0,0 +1,24 @@ +package com.dfsek.terra.addons.feature.locator.config.pattern; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern; +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.util.Range; +import com.dfsek.terra.api.util.collection.MaterialSet; + + +public class BlockSetMatchPatternTemplate implements ObjectTemplate { + @Value("blocks") + private @Meta MaterialSet blocks; + + @Value("offset") + private @Meta Range offset; + + @Override + public Pattern get() { + return new MatchPattern(offset, blockState -> blocks.contains(blockState.getBlockType())); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/NotPatternTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/NotPatternTemplate.java new file mode 100644 index 000000000..fcf40e57b --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/NotPatternTemplate.java @@ -0,0 +1,18 @@ +package com.dfsek.terra.addons.feature.locator.config.pattern; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.config.meta.Meta; + + +public class NotPatternTemplate implements ObjectTemplate { + @Value("pattern") + private @Meta Pattern pattern; + + @Override + public Pattern get() { + return pattern.not(); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/OrPatternTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/OrPatternTemplate.java new file mode 100644 index 000000000..5e1369724 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/OrPatternTemplate.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.feature.locator.config.pattern; + +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 java.util.List; + +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.config.meta.Meta; + + +public class OrPatternTemplate implements ObjectTemplate, ValidatedConfigTemplate { + @Value("patterns") + private @Meta List<@Meta Pattern> patterns; + + @Override + public Pattern get() { + Pattern current = patterns.remove(0); + while(!patterns.isEmpty()) { + current = current.or(patterns.remove(0)); + } + return current; + } + + @Override + public boolean validate() throws ValidationException { + if(patterns.isEmpty()) throw new ValidationException("AND Pattern must specify at least 1 pattern."); + return true; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/SingleBlockMatchPatternTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/SingleBlockMatchPatternTemplate.java new file mode 100644 index 000000000..782d0ca5d --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/SingleBlockMatchPatternTemplate.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.addons.feature.locator.config.pattern; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern; +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.util.Range; + + +public class SingleBlockMatchPatternTemplate implements ObjectTemplate { + @Value("block") + private @Meta BlockState block; + + @Value("offset") + private @Meta Range offset; + + + @Override + public Pattern get() { + return new MatchPattern(offset, block::matches); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/SolidMatchPatternTemplate.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/SolidMatchPatternTemplate.java new file mode 100644 index 000000000..eebb03197 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/config/pattern/SolidMatchPatternTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.feature.locator.config.pattern; + +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.loading.object.ObjectTemplate; + +import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern; +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.util.Range; + + +public class SolidMatchPatternTemplate implements ObjectTemplate { + @Value("offset") + private Range offset; + + @Override + public Pattern get() { + return new MatchPattern(offset, blockState -> blockState.getBlockType().isSolid()); + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/Noise3DLocator.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/Noise3DLocator.java new file mode 100644 index 000000000..571a33aa6 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/Noise3DLocator.java @@ -0,0 +1,27 @@ +package com.dfsek.terra.addons.feature.locator.locators; + +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.structure.feature.BinaryColumn; +import com.dfsek.terra.api.structure.feature.Locator; +import com.dfsek.terra.api.world.Column; + + +public class Noise3DLocator implements Locator { + private final NoiseSampler sampler; + + public Noise3DLocator(NoiseSampler sampler) { + this.sampler = sampler; + } + + @Override + public BinaryColumn getSuitableCoordinates(Column column) { + BinaryColumn results = column.newBinaryColumn(); + long seed = column.getWorld().getSeed(); + int x = column.getX(); + int z = column.getZ(); + column.forEach(y -> { + if(sampler.getNoiseSeeded(seed, x, y, z) > 0) results.set(y); + }); + return results; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/NoiseLocator.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/NoiseLocator.java new file mode 100644 index 000000000..b88ad0295 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/NoiseLocator.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.addons.feature.locator.locators; + +import net.jafama.FastMath; + +import java.util.List; + +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.structure.feature.BinaryColumn; +import com.dfsek.terra.api.structure.feature.Locator; +import com.dfsek.terra.api.world.Column; + + +public class NoiseLocator implements Locator { + private final List samplers; + + public NoiseLocator(List samplers) { + this.samplers = samplers; + } + + @Override + public BinaryColumn getSuitableCoordinates(Column column) { + BinaryColumn results = new BinaryColumn(column.getMinY(), column.getMaxY()); + + long seed = column.getWorld().getSeed(); + samplers.forEach(sampler -> { + int y = FastMath.floorToInt(sampler.getNoiseSeeded(seed, column.getX(), column.getX())); + if(y >= column.getMaxY() || y < column.getMinY()) return; + results.set(y); + }); + + return results; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/PatternLocator.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/PatternLocator.java new file mode 100644 index 000000000..a5faddf4c --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/PatternLocator.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.feature.locator.locators; + +import com.dfsek.terra.addons.feature.locator.patterns.Pattern; +import com.dfsek.terra.api.structure.feature.BinaryColumn; +import com.dfsek.terra.api.structure.feature.Locator; +import com.dfsek.terra.api.util.Range; +import com.dfsek.terra.api.world.Column; + + +public class PatternLocator implements Locator { + private final Pattern pattern; + private final Range search; + + public PatternLocator(Pattern pattern, Range search) { + this.pattern = pattern; + this.search = search; + } + + @Override + public BinaryColumn getSuitableCoordinates(Column column) { + BinaryColumn locations = new BinaryColumn(column.getMinY(), column.getMaxY()); + + for(int y : search) { + if(pattern.matches(y, column)) locations.set(y); + } + + return locations; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/RandomLocator.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/RandomLocator.java new file mode 100644 index 000000000..78df7b875 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/RandomLocator.java @@ -0,0 +1,38 @@ +package com.dfsek.terra.addons.feature.locator.locators; + +import java.util.Random; + +import com.dfsek.terra.api.structure.feature.BinaryColumn; +import com.dfsek.terra.api.structure.feature.Locator; +import com.dfsek.terra.api.util.Range; +import com.dfsek.terra.api.world.Column; + + +public class RandomLocator implements Locator { + private final Range height; + + private final Range points; + + public RandomLocator(Range height, Range points) { + this.height = height; + this.points = points; + } + + @Override + public BinaryColumn getSuitableCoordinates(Column column) { + long seed = column.getWorld().getSeed(); + seed = 31 * seed + column.getX(); + seed = 31 * seed + column.getZ(); + + Random r = new Random(seed); + + int size = points.get(r); + + BinaryColumn results = new BinaryColumn(column.getMinY(), column.getMaxY()); + for(int i = 0; i < size; i++) { + results.set(height.get(r)); + } + + return results; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/SurfaceLocator.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/SurfaceLocator.java new file mode 100644 index 000000000..942d45236 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/SurfaceLocator.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.feature.locator.locators; + +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.structure.feature.BinaryColumn; +import com.dfsek.terra.api.structure.feature.Locator; +import com.dfsek.terra.api.util.Range; +import com.dfsek.terra.api.world.Column; + + +public class SurfaceLocator implements Locator { + private final Range search; + + private final BlockState air; + + public SurfaceLocator(Range search, Platform platform) { + this.search = search; + this.air = platform.getWorldHandle().air(); + } + + @Override + public BinaryColumn getSuitableCoordinates(Column column) { + BinaryColumn location = new BinaryColumn(column.getMinY(), column.getMaxY()); + for(int y : search) { + if(column.getBlock(y).matches(air) && !column.getBlock(y - 1).matches(air)) { + location.set(y); + return location; + } + } + return location; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/patterns/MatchPattern.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/patterns/MatchPattern.java new file mode 100644 index 000000000..d305d64d8 --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/patterns/MatchPattern.java @@ -0,0 +1,26 @@ +package com.dfsek.terra.addons.feature.locator.patterns; + +import java.util.function.Predicate; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.util.Range; +import com.dfsek.terra.api.world.Column; + + +public class MatchPattern implements Pattern { + private final Range range; + private final Predicate matches; + + public MatchPattern(Range range, Predicate matches) { + this.range = range; + this.matches = matches; + } + + @Override + public boolean matches(int y, Column column) { + for(int i : range) { + if(!matches.test(column.getBlock(y + i))) return false; + } + return true; + } +} diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/patterns/Pattern.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/patterns/Pattern.java new file mode 100644 index 000000000..2aae3af0d --- /dev/null +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/patterns/Pattern.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.feature.locator.patterns; + +import com.dfsek.terra.api.world.Column; + + +public interface Pattern { + boolean matches(int y, Column column); + + default Pattern and(Pattern that) { + return (y, column) -> this.matches(y, column) && that.matches(y, column); + } + + default Pattern or(Pattern that) { + return (y, column) -> this.matches(y, column) || that.matches(y, column); + } + + default Pattern not() { + return (y, column) -> !this.matches(y, column); + } +}