mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-10-23 08:30:39 +00:00
Merge remote-tracking branch 'upstream/ver/6.0.0' into architecture/slf4j-logging
# Conflicts: # common/api/core/src/main/java/com/dfsek/terra/api/Logger.java
This commit is contained in:
271 files changed
+123
-3977
No files matched your search
@@ -10,9 +10,6 @@ your specifications, with no knowledge of Java required.
|
||||
etc): [SpigotMC](https://www.spigotmc.org/resources/85151/)
|
||||
* Fabric: [Modrinth](https://modrinth.com/mod/terra)
|
||||
/ [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
||||
* Forge **(ALPHA - NOT
|
||||
PRODUCTION-READY)**: [Modrinth](https://modrinth.com/mod/terra)
|
||||
/ [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
||||
|
||||
## Building and Running Terra
|
||||
|
||||
@@ -23,7 +20,6 @@ will build all platforms, and produce JARs in `platforms/<platform>/build/libs`
|
||||
|
||||
* Bukkit: `Terra-<version>-shaded.jar`
|
||||
* Fabric: `Terra-<version>-shaded-mapped.jar`
|
||||
* Forge: `Terra-<version>-shaded.jar`
|
||||
|
||||
### Building a Specific Platform
|
||||
|
||||
@@ -47,9 +43,7 @@ To run Minecraft with Terra in the IDE (for testing) use the following tasks:
|
||||
* Fabric
|
||||
* `runClient` - Run a Minecraft Fabric client with Terra installed.
|
||||
* `runServer` - Run a Minecraft Fabric server with Terra installed.
|
||||
* Forge
|
||||
* `runClient` - Run a Minecraft Forge client with Terra installed.
|
||||
* `runServer` - Run a Minecraft Forge server with Terra installed.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ fun Project.configureDependencies() {
|
||||
|
||||
if (project(":common:addons").subprojects.contains(this)) { // If this is an addon project, depend on the API.
|
||||
dependencies {
|
||||
"compileOnly"(project(":common:api"))
|
||||
"testImplementation"(project(":common:api"))
|
||||
"compileOnly"(project(":common:api:core"))
|
||||
"testImplementation"(project(":common:api:core"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
# api-features
|
||||
|
||||
Contains the API for feature generation.
|
||||
|
||||
This API implemented in:
|
||||
|
||||
* `config-feature`
|
||||
* `generation-stage-feature`
|
||||
* `config-locators`
|
||||
* `config-distributors`
|
||||
+1
-1
@@ -16,7 +16,7 @@ public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
private final Registry<TerraBiome> biomes;
|
||||
@Value("resolution")
|
||||
@Default
|
||||
private final int resolution = 1;
|
||||
private int resolution = 1;
|
||||
@Value("image.name")
|
||||
private BufferedImage image;
|
||||
@Value("image.align")
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome;
|
||||
|
||||
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
|
||||
public class BlankFunction implements DynamicFunction {
|
||||
private final int args;
|
||||
|
||||
public BlankFunction(int args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double... d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -13,7 +13,7 @@ import com.dfsek.terra.api.structure.feature.Distributor;
|
||||
public class NoiseDistributorTemplate implements ObjectTemplate<Distributor> {
|
||||
@Value("threshold")
|
||||
@Default
|
||||
private final @Meta double threshold = 0;
|
||||
private @Meta double threshold = 0;
|
||||
@Value("distribution")
|
||||
private @Meta NoiseSampler noise;
|
||||
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ public class FeatureAddon extends TerraAddon {
|
||||
main.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> event.getPack().registerConfigType(new FeatureConfigType(), "FEATURE", 2))
|
||||
.then(event -> event.getPack().registerConfigType(new FeatureConfigType(), "FEATURE", 3))
|
||||
.failThrough();
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -7,17 +7,18 @@ import com.dfsek.terra.api.config.ConfigFactory;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.ConfigType;
|
||||
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import com.dfsek.terra.api.world.Flora;
|
||||
|
||||
|
||||
public class FloraConfigType implements ConfigType<FloraTemplate, Flora> {
|
||||
public static final TypeKey<Flora> FLORA_TYPE_TOKEN = new TypeKey<>() {
|
||||
public class FloraConfigType implements ConfigType<FloraTemplate, Structure> {
|
||||
public static final TypeKey<Structure> FLORA_TYPE_TOKEN = new TypeKey<>() {
|
||||
};
|
||||
private final FloraFactory factory = new FloraFactory();
|
||||
|
||||
@Override
|
||||
public Supplier<OpenRegistry<Flora>> registrySupplier(ConfigPack pack) {
|
||||
public Supplier<OpenRegistry<Structure>> registrySupplier(ConfigPack pack) {
|
||||
return pack.getRegistryFactory()::create;
|
||||
}
|
||||
|
||||
@@ -27,12 +28,12 @@ public class FloraConfigType implements ConfigType<FloraTemplate, Flora> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigFactory<FloraTemplate, Flora> getFactory() {
|
||||
public ConfigFactory<FloraTemplate, Structure> getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeKey<Flora> getTypeKey() {
|
||||
public TypeKey<Structure> getTypeKey() {
|
||||
return FLORA_TYPE_TOKEN;
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -3,14 +3,14 @@ package com.dfsek.terra.addons.flora;
|
||||
import com.dfsek.terra.addons.flora.flora.gen.TerraFlora;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.config.ConfigFactory;
|
||||
import com.dfsek.terra.api.world.Flora;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
|
||||
|
||||
public class FloraFactory implements ConfigFactory<FloraTemplate, Flora> {
|
||||
public class FloraFactory implements ConfigFactory<FloraTemplate, Structure> {
|
||||
@Override
|
||||
public TerraFlora build(FloraTemplate config, TerraPlugin main) {
|
||||
return new TerraFlora(config.getLayers(), config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(),
|
||||
config.getReplaceable(), config.getRotatable(), config.getMaxPlacements(), config.getSearch(),
|
||||
config.isSpawnBlacklist(), config.getIrrigableOffset(), main, config.getNoiseDistribution());
|
||||
return new TerraFlora(config.getLayers(), config.doPhysics(), config.isCeiling(),
|
||||
config.getRotatable(),
|
||||
config.getNoiseDistribution(), config.getID());
|
||||
}
|
||||
}
|
||||
-57
@@ -19,23 +19,6 @@ public class FloraTemplate implements AbstractableTemplate {
|
||||
@Value("id")
|
||||
@Final
|
||||
private String id;
|
||||
|
||||
@Value("spawnable")
|
||||
private @Meta MaterialSet spawnable;
|
||||
|
||||
@Value("spawn-blacklist")
|
||||
@Default
|
||||
private @Meta boolean spawnBlacklist = false;
|
||||
|
||||
|
||||
@Value("replaceable")
|
||||
@Default
|
||||
private @Meta MaterialSet replaceable = MaterialSet.empty();
|
||||
|
||||
@Value("irrigable")
|
||||
@Default
|
||||
private @Meta MaterialSet irrigable;
|
||||
|
||||
@Value("rotatable")
|
||||
@Default
|
||||
private @Meta MaterialSet rotatable = MaterialSet.empty();
|
||||
@@ -48,18 +31,6 @@ public class FloraTemplate implements AbstractableTemplate {
|
||||
@Default
|
||||
private @Meta boolean ceiling = false;
|
||||
|
||||
@Value("search")
|
||||
@Default
|
||||
private TerraFlora.@Meta Search search = TerraFlora.Search.UP;
|
||||
|
||||
@Value("max-placements")
|
||||
@Default
|
||||
private @Meta int maxPlacements = -1;
|
||||
|
||||
@Value("irrigable-offset")
|
||||
@Default
|
||||
private @Meta int irrigableOffset;
|
||||
|
||||
@Value("layers")
|
||||
private @Meta List<@Meta BlockLayer> layers;
|
||||
|
||||
@@ -78,30 +49,6 @@ public class FloraTemplate implements AbstractableTemplate {
|
||||
return layers;
|
||||
}
|
||||
|
||||
public int getIrrigableOffset() {
|
||||
return irrigableOffset;
|
||||
}
|
||||
|
||||
public TerraFlora.Search getSearch() {
|
||||
return search;
|
||||
}
|
||||
|
||||
public int getMaxPlacements() {
|
||||
return maxPlacements;
|
||||
}
|
||||
|
||||
public MaterialSet getReplaceable() {
|
||||
return replaceable;
|
||||
}
|
||||
|
||||
public MaterialSet getSpawnable() {
|
||||
return spawnable;
|
||||
}
|
||||
|
||||
public MaterialSet getIrrigable() {
|
||||
return irrigable;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
@@ -110,10 +57,6 @@ public class FloraTemplate implements AbstractableTemplate {
|
||||
return ceiling;
|
||||
}
|
||||
|
||||
public boolean isSpawnBlacklist() {
|
||||
return spawnBlacklist;
|
||||
}
|
||||
|
||||
public MaterialSet getRotatable() {
|
||||
return rotatable;
|
||||
}
|
||||
|
||||
+52
-100
@@ -7,60 +7,40 @@ import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.state.properties.base.Properties;
|
||||
import com.dfsek.terra.api.block.state.properties.enums.Direction;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.structure.buffer.Buffer;
|
||||
import com.dfsek.terra.api.structure.rotation.Rotation;
|
||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.vector.Vector3;
|
||||
import com.dfsek.terra.api.world.Chunk;
|
||||
import com.dfsek.terra.api.world.Flora;
|
||||
import com.dfsek.terra.api.world.World;
|
||||
|
||||
|
||||
public class TerraFlora implements Flora {
|
||||
public class TerraFlora implements Structure {
|
||||
private final List<ProbabilityCollection<BlockState>> layers;
|
||||
private final boolean physics;
|
||||
private final boolean ceiling;
|
||||
|
||||
private final MaterialSet irrigable;
|
||||
|
||||
private final MaterialSet spawnable;
|
||||
private final MaterialSet replaceable;
|
||||
|
||||
private final MaterialSet testRotation;
|
||||
|
||||
private final int maxPlacements;
|
||||
|
||||
private final Search search;
|
||||
|
||||
private final boolean spawnBlacklist;
|
||||
|
||||
private final int irrigableOffset;
|
||||
|
||||
private final TerraPlugin main;
|
||||
|
||||
private final NoiseSampler distribution;
|
||||
|
||||
public TerraFlora(List<BlockLayer> layers, boolean physics, boolean ceiling, MaterialSet irrigable, MaterialSet spawnable,
|
||||
MaterialSet replaceable, MaterialSet testRotation, int maxPlacements, Search search, boolean spawnBlacklist,
|
||||
int irrigableOffset, TerraPlugin main, NoiseSampler distribution) {
|
||||
private final String id;
|
||||
|
||||
public TerraFlora(List<BlockLayer> layers, boolean physics, boolean ceiling,
|
||||
MaterialSet testRotation,
|
||||
NoiseSampler distribution, String id) {
|
||||
this.physics = physics;
|
||||
this.testRotation = testRotation;
|
||||
this.spawnBlacklist = spawnBlacklist;
|
||||
this.ceiling = ceiling;
|
||||
this.irrigable = irrigable;
|
||||
this.spawnable = spawnable;
|
||||
this.replaceable = replaceable;
|
||||
this.maxPlacements = maxPlacements;
|
||||
this.search = search;
|
||||
this.irrigableOffset = irrigableOffset;
|
||||
this.main = main;
|
||||
this.distribution = distribution;
|
||||
|
||||
this.id = id;
|
||||
|
||||
this.layers = new ArrayList<>();
|
||||
layers.forEach(layer -> {
|
||||
for(int i = 0; i < layer.getLayers(); i++) {
|
||||
@@ -69,78 +49,12 @@ public class TerraFlora implements Flora {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean plant(Vector3 location, World world) {
|
||||
boolean doRotation = testRotation.size() > 0;
|
||||
int size = layers.size();
|
||||
int c = ceiling ? -1 : 1;
|
||||
|
||||
EnumSet<Direction> faces = doRotation ? getFaces(location.clone().add(0, c, 0), world) : EnumSet.noneOf(Direction.class);
|
||||
if(doRotation && faces.size() == 0) return false; // Don't plant if no faces are valid.
|
||||
|
||||
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
|
||||
int lvl = (FastMath.abs(i));
|
||||
BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(),
|
||||
location.getZ(), world.getSeed()).clone();
|
||||
if(doRotation) {
|
||||
Direction oneFace = new ArrayList<>(faces).get(
|
||||
new Random(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())); // Get random face.
|
||||
|
||||
data.setIfPresent(Properties.DIRECTION, oneFace.opposite())
|
||||
.setIfPresent(Properties.NORTH, faces.contains(Direction.NORTH))
|
||||
.setIfPresent(Properties.SOUTH, faces.contains(Direction.SOUTH))
|
||||
.setIfPresent(Properties.EAST, faces.contains(Direction.EAST))
|
||||
.setIfPresent(Properties.WEST, faces.contains(Direction.WEST));
|
||||
}
|
||||
world.setBlockData(location.clone().add(0, i + c, 0), data, physics);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Vector3> getValidSpawnsAt(Chunk chunk, int x, int z, Range range) {
|
||||
int size = layers.size();
|
||||
Vector3 current = new Vector3(x, search.equals(Search.UP) ? range.getMin() : range.getMax(), z);
|
||||
List<Vector3> blocks = new ArrayList<>();
|
||||
int cx = chunk.getX() << 4;
|
||||
int cz = chunk.getZ() << 4;
|
||||
for(int y : range) {
|
||||
if(y > 255 || y < 0) continue;
|
||||
current = current.add(0, search.equals(Search.UP) ? 1 : -1, 0);
|
||||
if((spawnBlacklist != spawnable.contains(
|
||||
chunk.getBlock(current.getBlockX(), current.getBlockY(), current.getBlockZ()).getBlockType())) && isIrrigated(
|
||||
current.clone().add(cx, irrigableOffset, cz), chunk.getWorld()) && valid(size, current.clone().add(cx, 0, cz),
|
||||
chunk.getWorld())) {
|
||||
blocks.add(current.clone());
|
||||
if(maxPlacements > 0 && blocks.size() >= maxPlacements) break;
|
||||
}
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
private boolean valid(int size, Vector3 block, World world) {
|
||||
for(int i = 0; i < size; i++) { // Down if ceiling, up if floor
|
||||
if(block.getY() + 1 > 255 || block.getY() < 0) return false;
|
||||
block.add(0, ceiling ? -1 : 1, 0);
|
||||
if(!replaceable.contains(world.getBlockData(block).getBlockType())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void test(EnumSet<Direction> faces, Direction f, Vector3 b, World world) {
|
||||
if(testRotation.contains(
|
||||
world.getBlockData(b.getBlockX() + f.getModX(), b.getBlockY() + f.getModY(), b.getBlockZ() + f.getModZ()).getBlockType()))
|
||||
faces.add(f);
|
||||
}
|
||||
|
||||
private boolean isIrrigated(Vector3 b, World world) {
|
||||
if(irrigable == null) return true;
|
||||
return irrigable.contains(world.getBlockData(b.getBlockX() + 1, b.getBlockY(), b.getBlockZ()).getBlockType())
|
||||
|| irrigable.contains(world.getBlockData(b.getBlockX() - 1, b.getBlockY(), b.getBlockZ()).getBlockType())
|
||||
|| irrigable.contains(world.getBlockData(b.getBlockX(), b.getBlockY(), b.getBlockZ() + 1).getBlockType())
|
||||
|| irrigable.contains(world.getBlockData(b.getBlockX(), b.getBlockY(), b.getBlockZ() - 1).getBlockType());
|
||||
}
|
||||
|
||||
private ProbabilityCollection<BlockState> getStateCollection(int layer) {
|
||||
return layers.get(FastMath.max(FastMath.min(layer, layers.size() - 1), 0));
|
||||
}
|
||||
@@ -154,8 +68,46 @@ public class TerraFlora implements Flora {
|
||||
return faces;
|
||||
}
|
||||
|
||||
public enum Search {
|
||||
UP,
|
||||
DOWN
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation) {
|
||||
return generate(location, world, random, rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Buffer buffer, World world, Random random, Rotation rotation, int recursions) {
|
||||
return generate(buffer.getOrigin(), world, random, rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3 location, World world, Random random, Rotation rotation) {
|
||||
boolean doRotation = testRotation.size() > 0;
|
||||
int size = layers.size();
|
||||
int c = ceiling ? -1 : 1;
|
||||
|
||||
EnumSet<Direction> faces = doRotation ? getFaces(location.clone().add(0, c, 0), world) : EnumSet.noneOf(Direction.class);
|
||||
if(doRotation && faces.size() == 0) return false; // Don't plant if no faces are valid.
|
||||
|
||||
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
|
||||
int lvl = (FastMath.abs(i));
|
||||
BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(),
|
||||
location.getZ(), world.getSeed()).clone();
|
||||
if(doRotation) {
|
||||
Direction oneFace = new ArrayList<>(faces).get(
|
||||
new Random(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())); // Get random face.
|
||||
|
||||
data.setIfPresent(Properties.DIRECTION, oneFace.opposite())
|
||||
.setIfPresent(Properties.NORTH, faces.contains(Direction.NORTH))
|
||||
.setIfPresent(Properties.SOUTH, faces.contains(Direction.SOUTH))
|
||||
.setIfPresent(Properties.EAST, faces.contains(Direction.EAST))
|
||||
.setIfPresent(Properties.WEST, faces.contains(Direction.WEST));
|
||||
}
|
||||
world.setBlockData(location.clone().add(0, i + c, 0), data, physics);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -11,23 +11,23 @@ import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
|
||||
@Value("rotation")
|
||||
@Default
|
||||
private final @Meta double rotation = 0.25;
|
||||
private @Meta double rotation = 0.25;
|
||||
|
||||
@Value("isotropic")
|
||||
@Default
|
||||
private final @Meta boolean isotropic = true;
|
||||
private @Meta boolean isotropic = true;
|
||||
|
||||
@Value("deviation")
|
||||
@Default
|
||||
private final @Meta double deviation = 1.0;
|
||||
private @Meta double deviation = 1.0;
|
||||
|
||||
@Value("impulses")
|
||||
@Default
|
||||
private final @Meta double impulses = 64d;
|
||||
private @Meta double impulses = 64d;
|
||||
|
||||
@Value("frequency_0")
|
||||
@Default
|
||||
private final @Meta double f0 = 0.625;
|
||||
private @Meta double f0 = 0.625;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
|
||||
+4
-2
@@ -7,6 +7,8 @@ import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
import com.dfsek.paralithic.node.Statefulness;
|
||||
|
||||
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||
|
||||
|
||||
@@ -44,7 +46,7 @@ public class UserDefinedFunction implements DynamicFunction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless() {
|
||||
return true;
|
||||
public Statefulness statefulness() {
|
||||
return Statefulness.STATELESS;
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -3,6 +3,8 @@ package com.dfsek.terra.addons.noise.paralithic.noise;
|
||||
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
import com.dfsek.paralithic.node.Statefulness;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
@@ -29,7 +31,7 @@ public class NoiseFunction2 implements DynamicFunction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless() {
|
||||
return false;
|
||||
public Statefulness statefulness() {
|
||||
return Statefulness.CONTEXTUAL;
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -3,6 +3,8 @@ package com.dfsek.terra.addons.noise.paralithic.noise;
|
||||
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
|
||||
import com.dfsek.paralithic.node.Statefulness;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
@@ -29,7 +31,7 @@ public class NoiseFunction3 implements DynamicFunction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless() {
|
||||
return false;
|
||||
public Statefulness statefulness() {
|
||||
return Statefulness.CONTEXTUAL;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@ import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
public class BiomeStructuresTemplate implements ObjectTemplate<BiomeStructures> {
|
||||
@Value("structures")
|
||||
@Default
|
||||
private final @Meta Set<@Meta ConfiguredStructure> structures = Collections.emptySet();
|
||||
private @Meta Set<@Meta ConfiguredStructure> structures = Collections.emptySet();
|
||||
|
||||
@Override
|
||||
public BiomeStructures get() {
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import com.dfsek.terra.api.structure.feature.Feature;
|
||||
public class BiomeFeaturesTemplate implements ObjectTemplate<BiomeFeatures> {
|
||||
@Value("features")
|
||||
@Default
|
||||
private final @Meta List<@Meta Feature> features = Collections.emptyList();
|
||||
private @Meta List<@Meta Feature> features = Collections.emptyList();
|
||||
|
||||
@Override
|
||||
public BiomeFeatures get() {
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package com.dfsek.terra.addons.generation.flora;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
|
||||
public class BiomeFlora implements Properties {
|
||||
private final List<FloraLayer> layers;
|
||||
|
||||
public BiomeFlora(List<FloraLayer> layers) {
|
||||
this.layers = layers;
|
||||
}
|
||||
|
||||
public List<FloraLayer> getLayers() {
|
||||
return layers;
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
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 java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
|
||||
public class BiomeFloraTemplate implements ObjectTemplate<BiomeFlora> {
|
||||
@Value("flora")
|
||||
@Default
|
||||
private final @Meta List<@Meta FloraLayer> flora = Collections.emptyList();
|
||||
|
||||
@Override
|
||||
public BiomeFlora get() {
|
||||
return new BiomeFlora(flora);
|
||||
}
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
package com.dfsek.terra.addons.generation.flora;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
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.ConfigurationLoadEvent;
|
||||
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.generator.GenerationStageProvider;
|
||||
|
||||
|
||||
@Addon("generation-stage-flora")
|
||||
@Version("1.0.0")
|
||||
@Author("Terra")
|
||||
public class FloraGenerationAddon extends TerraAddon {
|
||||
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
main.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> {
|
||||
event.getPack().applyLoader(FloraLayer.class, FloraLayerLoader::new);
|
||||
event.getPack().getOrCreateRegistry(GenerationStageProvider.class).register("FLORA",
|
||||
pack -> new FloraGenerationStage(main));
|
||||
})
|
||||
.failThrough();
|
||||
|
||||
main.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, ConfigurationLoadEvent.class)
|
||||
.then(event -> {
|
||||
if(event.is(TerraBiome.class)) {
|
||||
event.getLoadedObject(TerraBiome.class).getContext().put(event.load(new BiomeFloraTemplate()).get());
|
||||
}
|
||||
})
|
||||
.failThrough();
|
||||
}
|
||||
}
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
package com.dfsek.terra.addons.generation.flora;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.profiler.ProfileFrame;
|
||||
import com.dfsek.terra.api.util.PopulationUtil;
|
||||
import com.dfsek.terra.api.vector.Vector2;
|
||||
import com.dfsek.terra.api.world.Chunk;
|
||||
import com.dfsek.terra.api.world.World;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.generator.GenerationStage;
|
||||
|
||||
|
||||
/**
|
||||
* Populates Flora
|
||||
*/
|
||||
public class FloraGenerationStage implements GenerationStage {
|
||||
private final TerraPlugin main;
|
||||
|
||||
public FloraGenerationStage(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@SuppressWarnings("try")
|
||||
@Override
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
try(ProfileFrame ignore = main.getProfiler().profile("flora")) {
|
||||
if(world.getConfig().disableFlora()) return;
|
||||
|
||||
long seed = world.getSeed();
|
||||
BiomeProvider provider = world.getBiomeProvider();
|
||||
Map<Vector2, List<FloraLayer>> layers = new HashMap<>();
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
Vector2 l = new Vector2(x, z);
|
||||
layers.put(l, provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, seed)
|
||||
.getContext()
|
||||
.get(BiomeFlora.class)
|
||||
.getLayers());
|
||||
}
|
||||
}
|
||||
|
||||
Random random = PopulationUtil.getRandom(chunk);
|
||||
|
||||
int iter = 0;
|
||||
boolean finished = false;
|
||||
while(!finished) {
|
||||
finished = true;
|
||||
for(Map.Entry<Vector2, List<FloraLayer>> entry : layers.entrySet()) {
|
||||
if(entry.getValue().size() <= iter) continue;
|
||||
finished = false;
|
||||
FloraLayer layer = entry.getValue().get(iter);
|
||||
if(layer.getDensity() >= random.nextDouble() * 100D) layer.place(chunk, entry.getKey());
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package com.dfsek.terra.addons.generation.flora;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.vector.Vector2;
|
||||
import com.dfsek.terra.api.world.Chunk;
|
||||
import com.dfsek.terra.api.world.Flora;
|
||||
|
||||
|
||||
public class FloraLayer {
|
||||
protected final double density;
|
||||
protected final Range level;
|
||||
protected final ProbabilityCollection<Flora> layer;
|
||||
protected final NoiseSampler noise;
|
||||
|
||||
public FloraLayer(double density, Range level, ProbabilityCollection<Flora> layer, NoiseSampler noise) {
|
||||
this.density = density;
|
||||
this.level = level;
|
||||
this.layer = layer;
|
||||
this.noise = noise;
|
||||
}
|
||||
|
||||
public void place(Chunk chunk, Vector2 coords) {
|
||||
int cx = (chunk.getX() << 4);
|
||||
int cz = (chunk.getZ() << 4);
|
||||
Flora item = layer.get(noise, cx + coords.getX(), cz + coords.getZ(), chunk.getWorld().getSeed());
|
||||
item.getValidSpawnsAt(chunk, (int) coords.getX(), (int) coords.getZ(), level).forEach(
|
||||
block -> item.plant(block.add(cx, 0, cz), chunk.getWorld()));
|
||||
}
|
||||
|
||||
public NoiseSampler getNoise() {
|
||||
return noise;
|
||||
}
|
||||
|
||||
public double getDensity() {
|
||||
return density;
|
||||
}
|
||||
|
||||
public Range getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public ProbabilityCollection<Flora> getLayer() {
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
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;
|
||||
import com.dfsek.terra.api.world.Flora;
|
||||
|
||||
|
||||
public class FloraLayerLoader implements ObjectTemplate<FloraLayer> {
|
||||
@Value("density")
|
||||
private @Meta double density;
|
||||
|
||||
@Value("y")
|
||||
private @Meta Range y;
|
||||
|
||||
@Value("items")
|
||||
private @Meta ProbabilityCollection<@Meta Flora> items;
|
||||
|
||||
@Value("distribution")
|
||||
private @Meta NoiseSampler distribution;
|
||||
|
||||
|
||||
@Override
|
||||
public FloraLayer get() {
|
||||
return new FloraLayer(density, y, items, distribution);
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+4
@@ -0,0 +1,4 @@
|
||||
package com.dfsek.terra.addons.manifest;
|
||||
|
||||
public class ManifestLoaderEntry {
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Entry-Point: com.dfsek.terra.addons.manifest.ManifestLoaderEntry
|
||||
@@ -1,5 +1,7 @@
|
||||
dependencies {
|
||||
"shadedApi"("com.dfsek:Paralithic:0.4.0")
|
||||
"shadedApi"(project(":common:api:util"))
|
||||
|
||||
"shadedApi"("com.dfsek:Paralithic:0.5.0")
|
||||
|
||||
"shadedApi"("com.dfsek.tectonic:common:2.1.2")
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,4 @@
|
||||
package com.dfsek.terra.api.addon;
|
||||
|
||||
public interface Addon {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.dfsek.terra.api.addon;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
|
||||
|
||||
public interface AddonLoader {
|
||||
/**
|
||||
* Load all addons.
|
||||
* @param main TerraPlugin instance.
|
||||
*/
|
||||
void load(TerraPlugin main, CheckedRegistry<Addon> addons);
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 271 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user