Reformat code

This commit is contained in:
Zoë Gidiere 2023-11-02 18:47:36 -06:00
parent d696e4fd24
commit 81a96d6b76
224 changed files with 1156 additions and 1075 deletions

View File

@ -52,7 +52,7 @@ assignees: ""
<!-- You can fill out the different items by putting the correct value beside each cell. --> <!-- You can fill out the different items by putting the correct value beside each cell. -->
| Name | Value | | Name | Value |
|------------------------------|-------| |------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Terra Version | <!-- Put your Terra version here. (remove the comment) --> | Terra Version | <!-- Put your Terra version here. (remove the comment) -->
| Platform / Platform Version | <!-- Put your platform and platform version here. (remove the comment) (eg. Spigot, Fabric, Paper, etc.) (If you are using the Region generator, put that here instead) --> | Platform / Platform Version | <!-- Put your platform and platform version here. (remove the comment) (eg. Spigot, Fabric, Paper, etc.) (If you are using the Region generator, put that here instead) -->
| Any External Plugins or Mods | <!-- Put a list of all the plugins or mods you have installed here. (remove the comment) (Make sure to NOT include any new lines) --> | Any External Plugins or Mods | <!-- Put a list of all the plugins or mods you have installed here. (remove the comment) (Make sure to NOT include any new lines) -->

View File

@ -17,7 +17,7 @@ repositories {
dependencies { dependencies {
//TODO Allow pulling from Versions.kt //TODO Allow pulling from Versions.kt
implementation("com.github.johnrengelman", "shadow", "8.1.1") implementation("com.github.johnrengelman", "shadow", "8.1.1")
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin","1.5.6") implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.5.6")
implementation("org.ow2.asm", "asm", "9.5") implementation("org.ow2.asm", "asm", "9.5")
implementation("org.ow2.asm", "asm-tree", "9.5") implementation("org.ow2.asm", "asm-tree", "9.5")

View File

@ -88,7 +88,8 @@ fun Project.configureDistribution() {
val jar = getJarTask().archiveFileName.get() val jar = getJarTask().archiveFileName.get()
resources.computeIfAbsent( resources.computeIfAbsent(
if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "addons/bootstrap" if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "addons/bootstrap"
else "addons") { ArrayList() }.add(jar) else "addons"
) { ArrayList() }.add(jar)
} }
val options = DumperOptions() val options = DumperOptions()

View File

@ -56,7 +56,8 @@ object Versions {
const val runPaper = "2.2.0" const val runPaper = "2.2.0"
const val paperWeight = "1.5.6" const val paperWeight = "1.5.6"
} }
//
//
// object Sponge { // object Sponge {
// const val sponge = "9.0.0-SNAPSHOT" // const val sponge = "9.0.0-SNAPSHOT"
// const val mixin = "0.8.2" // const val mixin = "0.8.2"

View File

@ -58,15 +58,19 @@ public class ImageBiomeProviderAddon implements AddonInitializer {
providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new); providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry =
event.getPack().getOrCreateRegistry(
BIOME_COLOR_CONVERTER_REGISTRY_KEY); BIOME_COLOR_CONVERTER_REGISTRY_KEY);
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new); biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new);
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new); biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry =
event.getPack().getOrCreateRegistry(
BIOME_COLOR_MAPPING_REGISTRY_KEY); BIOME_COLOR_MAPPING_REGISTRY_KEY);
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"), () -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class), b -> b)); biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"),
() -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class),
b -> b));
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new); biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new);
}) })
.failThrough(); .failThrough();

View File

@ -27,11 +27,9 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ImageBiomeProviderAddon implements AddonInitializer { public class ImageBiomeProviderAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
}; };
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
@Inject @Inject
private Platform platform; private Platform platform;
@ -51,6 +49,8 @@ public class ImageBiomeProviderAddon implements AddonInitializer {
}) })
.failThrough(); .failThrough();
if(platform.getTerraConfig().isDebugLog()) if(platform.getTerraConfig().isDebugLog())
logger.warn("The biome-provider-image addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the biome-provider-image-v2 addon for future pack development instead."); logger.warn(
"The biome-provider-image addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the " +
"biome-provider-image-v2 addon for future pack development instead.");
} }
} }

View File

@ -60,7 +60,8 @@ public class PipelineBiomeProvider implements BiomeProvider {
.append(delegate.getClass().getCanonicalName()) .append(delegate.getClass().getCanonicalName())
.append('\n')); .append('\n'));
throw new IllegalArgumentException("Biome Pipeline leaks placeholder biome \"" + pipelineBiome.getID() + throw new IllegalArgumentException("Biome Pipeline leaks placeholder biome \"" + pipelineBiome.getID() +
"\". Ensure there is a stage to guarantee replacement of the placeholder biome. Biomes: " + "\". Ensure there is a stage to guarantee replacement of the placeholder biome. " +
"Biomes: " +
biomeList); biomeList);
} }
this.biomes.add(pipelineBiome.getBiome()); this.biomes.add(pipelineBiome.getBiome());

View File

@ -7,8 +7,6 @@ import com.dfsek.terra.api.world.biome.Biome;
public interface PipelineBiome extends StringIdentifiable { public interface PipelineBiome extends StringIdentifiable {
Biome getBiome();
static PipelineBiome placeholder(String id) { static PipelineBiome placeholder(String id) {
return new PlaceholderPipelineBiome(id); return new PlaceholderPipelineBiome(id);
} }
@ -21,6 +19,8 @@ public interface PipelineBiome extends StringIdentifiable {
return SelfPipelineBiome.INSTANCE; return SelfPipelineBiome.INSTANCE;
} }
Biome getBiome();
Set<String> getTags(); Set<String> getTags();
default boolean isPlaceholder() { default boolean isPlaceholder() {

View File

@ -33,24 +33,20 @@ public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
Larger values are quadratically faster, but produce lower quality results. Larger values are quadratically faster, but produce lower quality results.
For example, a value of 3 would sample every 3 blocks.""") For example, a value of 3 would sample every 3 blocks.""")
protected @Meta int resolution = 1; protected @Meta int resolution = 1;
@Value("pipeline.source")
@Description("The Biome Source to use for initial population of biomes.")
private @Meta Source source;
@Value("pipeline.stages")
@Description("A list of pipeline stages to apply to the result of #source")
private @Meta List<@Meta Stage> stages;
@Value("blend.sampler") @Value("blend.sampler")
@Default @Default
@Description("A sampler to use for blending the edges of biomes via domain warping.") @Description("A sampler to use for blending the edges of biomes via domain warping.")
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero(); protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
@Value("blend.amplitude") @Value("blend.amplitude")
@Default @Default
@Description("The amplitude at which to perform blending.") @Description("The amplitude at which to perform blending.")
protected @Meta double blendAmplitude = 0d; protected @Meta double blendAmplitude = 0d;
@Value("pipeline.source")
@Description("The Biome Source to use for initial population of biomes.")
private @Meta Source source;
@Value("pipeline.stages")
@Description("A list of pipeline stages to apply to the result of #source")
private @Meta List<@Meta Stage> stages;
@Override @Override
public BiomeProvider get() { public BiomeProvider get() {

View File

@ -11,10 +11,10 @@ import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
public class BiomeChunkImpl implements BiomeChunk { public class BiomeChunkImpl implements BiomeChunk {
private PipelineBiome[][] biomes;
private final SeededVector worldOrigin; private final SeededVector worldOrigin;
private final int chunkOriginArrayIndex; private final int chunkOriginArrayIndex;
private final int worldCoordinateScale; private final int worldCoordinateScale;
private PipelineBiome[][] biomes;
public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) { public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) {
@ -43,7 +43,8 @@ public class BiomeChunkImpl implements BiomeChunk {
for(int gridZ = 0; gridZ < gridSize; gridZ++) { for(int gridZ = 0; gridZ < gridSize; gridZ++) {
int xIndex = gridOrigin + gridX * gridInterval; int xIndex = gridOrigin + gridX * gridInterval;
int zIndex = gridOrigin + gridZ * gridInterval; int zIndex = gridOrigin + gridZ * gridInterval;
biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex), zIndexToWorldCoordinate(zIndex)); biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex),
zIndexToWorldCoordinate(zIndex));
} }
} }
@ -79,21 +80,6 @@ public class BiomeChunkImpl implements BiomeChunk {
} }
} }
@Override
public PipelineBiome get(int xInChunk, int zInChunk) {
int xIndex = xInChunk + chunkOriginArrayIndex;
int zIndex = zInChunk + chunkOriginArrayIndex;
return biomes[xIndex][zIndex];
}
private int xIndexToWorldCoordinate(int xIndex) {
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
private int zIndexToWorldCoordinate(int zIndex) {
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
protected static int initialSizeToArraySize(int expanderCount, int initialSize) { protected static int initialSizeToArraySize(int expanderCount, int initialSize) {
int size = initialSize; int size = initialSize;
for(int i = 0; i < expanderCount; i++) { for(int i = 0; i < expanderCount; i++) {
@ -117,8 +103,8 @@ public class BiomeChunkImpl implements BiomeChunk {
int gridOrigin = 0; int gridOrigin = 0;
int expansionsApplied = 0; int expansionsApplied = 0;
int gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied); int gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
for (Stage stage : stages) { for(Stage stage : stages) {
if (stage instanceof Expander) { if(stage instanceof Expander) {
expansionsApplied++; expansionsApplied++;
gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied); gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
} }
@ -143,6 +129,21 @@ public class BiomeChunkImpl implements BiomeChunk {
return 1 << (totalExpansions - expansionsApplied); return 1 << (totalExpansions - expansionsApplied);
} }
@Override
public PipelineBiome get(int xInChunk, int zInChunk) {
int xIndex = xInChunk + chunkOriginArrayIndex;
int zIndex = zInChunk + chunkOriginArrayIndex;
return biomes[xIndex][zIndex];
}
private int xIndexToWorldCoordinate(int xIndex) {
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
private int zIndexToWorldCoordinate(int zIndex) {
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
private SeededVector getOrigin() { private SeededVector getOrigin() {
return worldOrigin; return worldOrigin;
} }
@ -160,7 +161,8 @@ public class BiomeChunkImpl implements BiomeChunk {
private final int zIndex; private final int zIndex;
private final PipelineBiome[][] lookupArray; private final PipelineBiome[][] lookupArray;
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex, PipelineBiome[][] lookupArray) { private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex,
PipelineBiome[][] lookupArray) {
this.chunk = chunk; this.chunk = chunk;
this.gridInterval = gridInterval; this.gridInterval = gridInterval;
this.gridX = gridX; this.gridX = gridX;

View File

@ -36,11 +36,11 @@ public class PipelineImpl implements Pipeline {
int chunkOriginArrayIndex; int chunkOriginArrayIndex;
int chunkSize; int chunkSize;
int initialSize = 1; int initialSize = 1;
while (true) { while(true) {
arraySize = BiomeChunkImpl.initialSizeToArraySize(expanderCount, initialSize); arraySize = BiomeChunkImpl.initialSizeToArraySize(expanderCount, initialSize);
chunkOriginArrayIndex = BiomeChunkImpl.calculateChunkOriginArrayIndex(expanderCount, stages); chunkOriginArrayIndex = BiomeChunkImpl.calculateChunkOriginArrayIndex(expanderCount, stages);
chunkSize = BiomeChunkImpl.calculateChunkSize(arraySize, chunkOriginArrayIndex, expanderCount); chunkSize = BiomeChunkImpl.calculateChunkSize(arraySize, chunkOriginArrayIndex, expanderCount);
if (chunkSize > 1 && arraySize >= idealChunkArraySize) break; if(chunkSize > 1 && arraySize >= idealChunkArraySize) break;
initialSize++; initialSize++;
} }

View File

@ -22,10 +22,10 @@ public class FractalExpander implements Expander {
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ()); double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
if (xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly if(xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly
return roll > 0 ? viewPoint.getRelativeBiome(-1, 0) : viewPoint.getRelativeBiome(1, 0); return roll > 0 ? viewPoint.getRelativeBiome(-1, 0) : viewPoint.getRelativeBiome(1, 0);
} else if (xMod2 == 0 && zMod2 == 1) { // Pick one of 2 neighbors on Z axis randomly } else if(xMod2 == 0 && zMod2 == 1) { // Pick one of 2 neighbors on Z axis randomly
return roll > 0 ? viewPoint.getRelativeBiome(0, -1) : viewPoint.getRelativeBiome(0, 1); return roll > 0 ? viewPoint.getRelativeBiome(0, -1) : viewPoint.getRelativeBiome(0, 1);
} else { // Pick one of 4 corners randomly } else { // Pick one of 4 corners randomly

View File

@ -71,7 +71,8 @@ public class BorderListStage implements Stage {
viewPoint.worldSeed()); viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement; return replacement.isSelf() ? center : replacement;
} }
PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed()); PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement; return replacement.isSelf() ? center : replacement;
} }
} }

View File

@ -41,15 +41,13 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineAddon implements AddonInitializer { public class BiomePipelineAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
}; };
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
}; };
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
}; };
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
@Inject @Inject
private Platform platform; private Platform platform;
@ -91,6 +89,8 @@ public class BiomePipelineAddon implements AddonInitializer {
}); });
if(platform.getTerraConfig().isDebugLog()) if(platform.getTerraConfig().isDebugLog())
logger.warn("The biome-provider-pipeline addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the biome-provider-pipeline-v2 addon for future pack development instead."); logger.warn(
"The biome-provider-pipeline addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the" +
" biome-provider-pipeline-v2 addon for future pack development instead.");
} }
} }

View File

@ -68,10 +68,13 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
.register(addon, ConfigurationLoadEvent.class) .register(addon, ConfigurationLoadEvent.class)
.then(event -> { .then(event -> {
if(event.is(Biome.class)) { if(event.is(Biome.class)) {
NoiseChunkGeneratorPackConfigTemplate config = event.getPack().getContext().get(NoiseChunkGeneratorPackConfigTemplate.class); NoiseChunkGeneratorPackConfigTemplate config = event.getPack().getContext().get(
NoiseChunkGeneratorPackConfigTemplate.class);
event.getLoadedObject(Biome.class).getContext().put(paletteInfoPropertyKey, event.getLoadedObject(Biome.class).getContext().put(paletteInfoPropertyKey,
event.load(new BiomePaletteTemplate(platform, config.getSlantCalculationMethod())).get()); event.load(new BiomePaletteTemplate(platform,
config.getSlantCalculationMethod()))
.get());
event.getLoadedObject(Biome.class).getContext().put(noisePropertiesPropertyKey, event.getLoadedObject(Biome.class).getContext().put(noisePropertiesPropertyKey,
event.load(new BiomeNoiseConfigTemplate()).get()); event.load(new BiomeNoiseConfigTemplate()).get());
} }

View File

@ -27,26 +27,22 @@ import com.dfsek.terra.api.world.chunk.generation.util.Palette;
public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> { public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> {
private final Platform platform; private final Platform platform;
private final SlantHolder.CalculationMethod slantCalculationMethod;
@Value("slant") @Value("slant")
@Default @Default
@Description("The slant palettes to use in this biome.") @Description("The slant palettes to use in this biome.")
private @Meta List<SlantHolder.@Meta Layer> slantLayers = Collections.emptyList(); private @Meta List<SlantHolder.@Meta Layer> slantLayers = Collections.emptyList();
@Value("slant-depth") @Value("slant-depth")
@Default @Default
@Description("The maximum depth at which to apply a slant palette.") @Description("The maximum depth at which to apply a slant palette.")
private @Meta int slantDepth = Integer.MAX_VALUE; private @Meta int slantDepth = Integer.MAX_VALUE;
@Value("palette") @Value("palette")
@Description("The palettes to use in this biome.") @Description("The palettes to use in this biome.")
private @Meta List<@Meta Map<@Meta Palette, @Meta Integer>> palettes; private @Meta List<@Meta Map<@Meta Palette, @Meta Integer>> palettes;
@Value("ocean.level") @Value("ocean.level")
@Description("Sea level in this biome. Defaults to zero") @Description("Sea level in this biome. Defaults to zero")
@Default @Default
private @Meta int seaLevel = 0; private @Meta int seaLevel = 0;
@Value("ocean.palette") @Value("ocean.palette")
@Description("The palette to use for the ocean in this biome. Defaults to a blank palette.") @Description("The palette to use for the ocean in this biome. Defaults to a blank palette.")
@Default @Default
@ -56,13 +52,10 @@ public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> {
return platform.getWorldHandle().air(); return platform.getWorldHandle().air();
} }
}; };
@Value("carving.update-palette") @Value("carving.update-palette")
@Default @Default
private @Meta boolean updatePalette = false; private @Meta boolean updatePalette = false;
private final SlantHolder.CalculationMethod slantCalculationMethod;
public BiomePaletteTemplate(Platform platform, SlantHolder.CalculationMethod slantCalculationMethod) { public BiomePaletteTemplate(Platform platform, SlantHolder.CalculationMethod slantCalculationMethod) {
this.platform = platform; this.platform = platform;
this.slantCalculationMethod = slantCalculationMethod; this.slantCalculationMethod = slantCalculationMethod;

View File

@ -24,15 +24,6 @@ public class PaletteHolder {
this.offset = offset; this.offset = offset;
} }
public Palette getPalette(int y) {
int index = y + offset;
return index >= 0
? index < palettes.length
? palettes[index]
: palettes[palettes.length - 1]
: palettes[0];
}
public static PaletteHolder of(List<Map<Palette, Integer>> palettes) { public static PaletteHolder of(List<Map<Palette, Integer>> palettes) {
PaletteHolderBuilder builder = new PaletteHolderBuilder(); PaletteHolderBuilder builder = new PaletteHolderBuilder();
for(Map<Palette, Integer> layer : palettes) { for(Map<Palette, Integer> layer : palettes) {
@ -43,6 +34,16 @@ public class PaletteHolder {
return builder.build(); return builder.build();
} }
public Palette getPalette(int y) {
int index = y + offset;
return index >= 0
? index < palettes.length
? palettes[index]
: palettes[palettes.length - 1]
: palettes[0];
}
private static class PaletteHolderBuilder { private static class PaletteHolderBuilder {
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>(); private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();

View File

@ -23,7 +23,8 @@ public class MultipleSlantHolder extends SlantHolderImpl {
MultipleSlantHolder(List<SlantHolder.Layer> slant, int slantDepth, CalculationMethod calculationMethod) { MultipleSlantHolder(List<SlantHolder.Layer> slant, int slantDepth, CalculationMethod calculationMethod) {
super(slantDepth, calculationMethod); super(slantDepth, calculationMethod);
NavigableMap<Double, PaletteHolder> layers = new TreeMap<>(slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette))); NavigableMap<Double, PaletteHolder> layers = new TreeMap<>(
slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette)));
Stream<Double> thresholds = layers.keySet().stream(); Stream<Double> thresholds = layers.keySet().stream();
double slantThreshold = floorToThreshold ? double slantThreshold = floorToThreshold ?
thresholds.min(Double::compare).orElseThrow() : thresholds.min(Double::compare).orElseThrow() :

View File

@ -9,6 +9,28 @@ import com.dfsek.terra.api.util.vector.Vector3;
public interface SlantHolder { public interface SlantHolder {
SlantHolder EMPTY = new SlantHolder() {
@Override
public double calculateSlant(Sampler3D sampler, double x, double y, double z) {
throw new UnsupportedOperationException("Empty holder should not calculate slant");
}
@Override
public boolean isAboveDepth(int depth) {
return false;
}
@Override
public boolean isInSlantThreshold(double slant) {
return false;
}
@Override
public PaletteHolder getPalette(double slant) {
throw new UnsupportedOperationException("Empty holder cannot return a palette");
}
};
static SlantHolder of(List<SlantHolder.Layer> layers, int slantDepth, CalculationMethod calculationMethod) { static SlantHolder of(List<SlantHolder.Layer> layers, int slantDepth, CalculationMethod calculationMethod) {
if(layers.isEmpty()) { if(layers.isEmpty()) {
return EMPTY; return EMPTY;
@ -26,8 +48,6 @@ public interface SlantHolder {
PaletteHolder getPalette(double slant); PaletteHolder getPalette(double slant);
record Layer(PaletteHolder palette, double threshold) {
}
enum CalculationMethod { enum CalculationMethod {
DotProduct { DotProduct {
@ -46,7 +66,7 @@ public interface SlantHolder {
public double slant(Sampler3D sampler, double x, double y, double z) { public double slant(Sampler3D sampler, double x, double y, double z) {
Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0); Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0);
for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) { for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) {
var scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ()); var scalar = -sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ());
normalApproximation.add(point.mutable().multiply(scalar)); normalApproximation.add(point.mutable().multiply(scalar));
} }
return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize()); return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize());
@ -70,7 +90,8 @@ public interface SlantHolder {
double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST; double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST; double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1))); return Math.sqrt(
((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
} }
@Override @Override
@ -92,25 +113,7 @@ public interface SlantHolder {
public abstract boolean floorToThreshold(); public abstract boolean floorToThreshold();
} }
SlantHolder EMPTY = new SlantHolder() {
@Override
public double calculateSlant(Sampler3D sampler, double x, double y, double z) {
throw new UnsupportedOperationException("Empty holder should not calculate slant");
}
@Override record Layer(PaletteHolder palette, double threshold) {
public boolean isAboveDepth(int depth) {
return false;
} }
@Override
public boolean isInSlantThreshold(double slant) {
return false;
}
@Override
public PaletteHolder getPalette(double slant) {
throw new UnsupportedOperationException("Empty holder cannot return a palette");
}
};
} }

View File

@ -4,11 +4,9 @@ import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
public abstract class SlantHolderImpl implements SlantHolder { public abstract class SlantHolderImpl implements SlantHolder {
private final SlantHolder.CalculationMethod calculationMethod;
private final int slantDepth;
protected final boolean floorToThreshold; protected final boolean floorToThreshold;
private final SlantHolder.CalculationMethod calculationMethod;
private final int slantDepth;
protected SlantHolderImpl(int slantDepth, CalculationMethod calculationMethod) { protected SlantHolderImpl(int slantDepth, CalculationMethod calculationMethod) {
this.floorToThreshold = calculationMethod.floorToThreshold(); this.floorToThreshold = calculationMethod.floorToThreshold();

View File

@ -148,7 +148,8 @@ public class NoiseAddon implements AddonInitializer {
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>(); Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>(); Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions)); noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"), () -> new ExpressionNormalizerTemplate(packSamplers, packFunctions)); noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"),
() -> new ExpressionNormalizerTemplate(packSamplers, packFunctions));
NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate()); NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate());
packSamplers.putAll(template.getSamplers()); packSamplers.putAll(template.getSamplers());

View File

@ -27,6 +27,6 @@ public class TranslateSamplerTemplate extends SamplerTemplate<TranslateSampler>
@Override @Override
public NoiseSampler get() { public NoiseSampler get() {
return new TranslateSampler(sampler, x, y ,z); return new TranslateSampler(sampler, x, y, z);
} }
} }

View File

@ -41,15 +41,18 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
@Default @Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>(); private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) { public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers,
Map<String, FunctionTemplate> globalFunctions) {
this.globalSamplers = globalSamplers; this.globalSamplers = globalSamplers;
this.globalFunctions = globalFunctions; this.globalFunctions = globalFunctions;
} }
@Override @Override
public NoiseSampler get() { public NoiseSampler get() {
var mergedFunctions = new HashMap<>(globalFunctions); mergedFunctions.putAll(functions); var mergedFunctions = new HashMap<>(globalFunctions);
var mergedSamplers = new HashMap<>(globalSamplers); mergedSamplers.putAll(samplers); mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers);
mergedSamplers.putAll(samplers);
try { try {
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars); return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
} catch(ParseException e) { } catch(ParseException e) {

View File

@ -45,15 +45,18 @@ public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionN
@Default @Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>(); private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionNormalizerTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) { public ExpressionNormalizerTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers,
Map<String, FunctionTemplate> globalFunctions) {
this.globalSamplers = globalSamplers; this.globalSamplers = globalSamplers;
this.globalFunctions = globalFunctions; this.globalFunctions = globalFunctions;
} }
@Override @Override
public NoiseSampler get() { public NoiseSampler get() {
var mergedFunctions = new HashMap<>(globalFunctions); mergedFunctions.putAll(functions); var mergedFunctions = new HashMap<>(globalFunctions);
var mergedSamplers = new HashMap<>(globalSamplers); mergedSamplers.putAll(samplers); mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers);
mergedSamplers.putAll(samplers);
try { try {
return new ExpressionNormalizer(function, convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars); return new ExpressionNormalizer(function, convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
} catch(ParseException e) { } catch(ParseException e) {

View File

@ -28,18 +28,14 @@ public class CubicSpline {
} }
} }
public double apply(double in) {
return calculate(in, fromValues, toValues, gradients);
}
public static double calculate(double in, double[] fromValues, double[] toValues, double[] gradients) { public static double calculate(double in, double[] fromValues, double[] toValues, double[] gradients) {
int pointIdx = floorBinarySearch(in, fromValues) - 1; int pointIdx = floorBinarySearch(in, fromValues) - 1;
int pointIdxLast = fromValues.length - 1; int pointIdxLast = fromValues.length - 1;
if (pointIdx < 0) { // If to left of first point return linear function intersecting said point using point's gradient if(pointIdx < 0) { // If to left of first point return linear function intersecting said point using point's gradient
return gradients[0] * (in - fromValues[0]) + toValues[0]; return gradients[0] * (in - fromValues[0]) + toValues[0];
} else if (pointIdx == pointIdxLast) { // Do same if to right of last point } else if(pointIdx == pointIdxLast) { // Do same if to right of last point
return gradients[pointIdxLast] * (in - fromValues[pointIdxLast]) + toValues[pointIdxLast]; return gradients[pointIdxLast] * (in - fromValues[pointIdxLast]) + toValues[pointIdxLast];
} else { } else {
double fromLeft = fromValues[pointIdx]; double fromLeft = fromValues[pointIdx];
@ -56,7 +52,8 @@ public class CubicSpline {
double t = (in - fromLeft) / fromDelta; double t = (in - fromLeft) / fromDelta;
return lerp(t, toLeft, toRight) + t * (1.0F - t) * lerp(t, gradientLeft * fromDelta - toDelta, -gradientRight * fromDelta + toDelta); return lerp(t, toLeft, toRight) + t * (1.0F - t) * lerp(t, gradientLeft * fromDelta - toDelta,
-gradientRight * fromDelta + toDelta);
} }
} }
@ -64,10 +61,10 @@ public class CubicSpline {
int left = 0; int left = 0;
int right = values.length; int right = values.length;
int idx = right - left; int idx = right - left;
while (idx > 0) { while(idx > 0) {
int halfDelta = idx / 2; int halfDelta = idx / 2;
int mid = left + halfDelta; int mid = left + halfDelta;
if (targetValue < values[mid]) { if(targetValue < values[mid]) {
idx = halfDelta; idx = halfDelta;
} else { } else {
left = mid + 1; left = mid + 1;
@ -77,6 +74,11 @@ public class CubicSpline {
return left; return left;
} }
public double apply(double in) {
return calculate(in, fromValues, toValues, gradients);
}
public record Point(double from, double to, double gradient) implements Comparable<Point> { public record Point(double from, double to, double gradient) implements Comparable<Point> {
@Override @Override

View File

@ -14,10 +14,11 @@ import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
public class FunctionUtil { public class FunctionUtil {
private FunctionUtil() {} private FunctionUtil() { }
public static Map<String, Function> convertFunctionsAndSamplers(Map<String, FunctionTemplate> functions, public static Map<String, Function> convertFunctionsAndSamplers(Map<String, FunctionTemplate> functions,
Map<String, DimensionApplicableNoiseSampler> samplers) throws ParseException { Map<String, DimensionApplicableNoiseSampler> samplers)
throws ParseException {
Map<String, Function> functionMap = new HashMap<>(); Map<String, Function> functionMap = new HashMap<>();
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) { for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
functionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue())); functionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));

View File

@ -21,13 +21,29 @@ public class DistanceSampler extends NoiseFunction {
this.distanceAtRadius = distance2d(distanceFunction, radius, 0); // distance2d and distance3d should return the same value this.distanceAtRadius = distance2d(distanceFunction, radius, 0); // distance2d and distance3d should return the same value
} }
private static double distance2d(DistanceFunction distanceFunction, double x, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x * x + z * z);
case EuclideanSq -> x * x + z * z;
case Manhattan -> Math.abs(x) + Math.abs(z);
};
}
private static double distance3d(DistanceFunction distanceFunction, double x, double y, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x * x + y * y + z * z);
case EuclideanSq -> x * x + y * y + z * z;
case Manhattan -> Math.abs(x) + Math.abs(y) + Math.abs(z);
};
}
@Override @Override
public double getNoiseRaw(long seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
double dx = x - ox; double dx = x - ox;
double dy = y - oz; double dy = y - oz;
if (normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius)) return 1; if(normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius)) return 1;
double dist = distance2d(distanceFunction, dx, dy); double dist = distance2d(distanceFunction, dx, dy);
if (normalize) return Math.min(((2*dist)/distanceAtRadius)-1, 1); if(normalize) return Math.min(((2 * dist) / distanceAtRadius) - 1, 1);
return dist; return dist;
} }
@ -38,26 +54,10 @@ public class DistanceSampler extends NoiseFunction {
double dz = z - oz; double dz = z - oz;
if(normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius || Math.abs(dz) > radius)) return 1; if(normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius || Math.abs(dz) > radius)) return 1;
double dist = distance3d(distanceFunction, dx, dy, dz); double dist = distance3d(distanceFunction, dx, dy, dz);
if (normalize) return Math.min(((2*dist)/distanceAtRadius)-1, 1); if(normalize) return Math.min(((2 * dist) / distanceAtRadius) - 1, 1);
return dist; return dist;
} }
private static double distance2d(DistanceFunction distanceFunction, double x, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x*x + z*z);
case EuclideanSq -> x*x + z*z;
case Manhattan -> Math.abs(x) + Math.abs(z);
};
}
private static double distance3d(DistanceFunction distanceFunction, double x, double y, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x*x + y*y + z*z);
case EuclideanSq -> x*x + y*y + z*z;
case Manhattan -> Math.abs(x) + Math.abs(y) + Math.abs(z);
};
}
public enum DistanceFunction { public enum DistanceFunction {
Euclidean, Euclidean,
EuclideanSq, EuclideanSq,

View File

@ -17,11 +17,10 @@ public class GaborNoiseSampler extends NoiseFunction {
private double a = 0.1; private double a = 0.1;
private double f0 = 0.625; private double f0 = 0.625;
private double kernelRadius = (Math.sqrt(-Math.log(0.05) / Math.PI) / a); private double kernelRadius = (Math.sqrt(-Math.log(0.05) / Math.PI) / a);
private double impulsesPerKernel = 64d;
private double impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius)); private double impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
private double impulsesPerCell = impulseDensity * kernelRadius * kernelRadius; private double impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
private double g = Math.exp(-impulsesPerCell); private double g = Math.exp(-impulsesPerCell);
private double impulsesPerKernel = 64d;
private double omega0 = Math.PI * 0.25; private double omega0 = Math.PI * 0.25;
private boolean isotropic = true; private boolean isotropic = true;
@ -72,7 +71,8 @@ public class GaborNoiseSampler extends NoiseFunction {
} }
private double gabor(double omega_0, double x, double y) { private double gabor(double omega_0, double x, double y) {
return k * (Math.exp(-Math.PI * (a * a) * (x * x + y * y)) * MathUtil.cos(2 * Math.PI * f0 * (x * MathUtil.cos(omega_0) + y * MathUtil.sin( return k * (Math.exp(-Math.PI * (a * a) * (x * x + y * y)) * MathUtil.cos(2 * Math.PI * f0 * (x * MathUtil.cos(omega_0) +
y * MathUtil.sin(
omega_0)))); omega_0))));
} }

View File

@ -18,7 +18,7 @@ public class DoublePredicateLoader implements TypeLoader<DoublePredicate> {
@Override @Override
public DoublePredicate load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, public DoublePredicate load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException { DepthTracker depthTracker) throws LoadException {
if (o instanceof String expressionString) { if(o instanceof String expressionString) {
Scope scope = new Scope(); Scope scope = new Scope();
scope.addInvocationVariable("value"); scope.addInvocationVariable("value");
try { try {

View File

@ -16,6 +16,7 @@ import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler; import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject; import com.dfsek.terra.api.inject.annotations.Inject;
public class NumberPredicateAddon implements AddonInitializer { public class NumberPredicateAddon implements AddonInitializer {
@Inject @Inject

View File

@ -167,6 +167,7 @@ public class VanillaOre implements Structure {
return blockCount > 0; return blockCount > 0;
} }
public BlockState getMaterial(BlockType replace) { public BlockState getMaterial(BlockType replace) {
return materials.getOrDefault(replace, material); return materials.getOrDefault(replace, material);
} }

View File

@ -15,6 +15,7 @@ import static com.dfsek.terra.addons.ore.utils.VanillaOreUtils.shouldPlace;
public class VanillaScatteredOre extends VanillaOre { public class VanillaScatteredOre extends VanillaOre {
protected final int spread; protected final int spread;
public VanillaScatteredOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity, double exposed, public VanillaScatteredOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity, double exposed,
Map<BlockType, BlockState> materials, int spread) { Map<BlockType, BlockState> materials, int spread) {
super(material, size, replaceable, applyGravity, exposed, materials); super(material, size, replaceable, applyGravity, exposed, materials);
@ -30,7 +31,7 @@ public class VanillaScatteredOre extends VanillaOre {
for(int j = 0; j < i; ++j) { for(int j = 0; j < i; ++j) {
this.setPos(mutable, random, location, Math.min(j, spread)); this.setPos(mutable, random, location, Math.min(j, spread));
BlockType block = world.getBlockState(mutable).getBlockType(); BlockType block = world.getBlockState(mutable).getBlockType();
if (shouldPlace(getReplaceable(), block, exposed, random, world, mutable.getX(), mutable.getY(), mutable.getZ())) { if(shouldPlace(getReplaceable(), block, exposed, random, world, mutable.getX(), mutable.getY(), mutable.getZ())) {
world.setBlockState(mutable, getMaterial(block), isApplyGravity()); world.setBlockState(mutable, getMaterial(block), isApplyGravity());
} }
} }
@ -48,6 +49,6 @@ public class VanillaScatteredOre extends VanillaOre {
} }
private int getSpread(Random random, int spread) { private int getSpread(Random random, int spread) {
return Math.round((random.nextFloat() - random.nextFloat()) * (float)spread); return Math.round((random.nextFloat() - random.nextFloat()) * (float) spread);
} }
} }

View File

@ -18,7 +18,8 @@ public class VanillaOreUtils {
} }
} }
public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposed, Random random, WritableWorld world, int x, int y, int z) { public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposed, Random random, WritableWorld world, int x,
int y, int z) {
if(!replaceable.contains(type)) { if(!replaceable.contains(type)) {
return false; return false;
} else if(shouldNotDiscard(random, exposed)) { } else if(shouldNotDiscard(random, exposed)) {

View File

@ -4,5 +4,4 @@ dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader")) compileOnlyApi(project(":common:addons:manifest-addon-loader"))
} }

View File

@ -6,6 +6,7 @@ public interface ColorSampler {
/** /**
* @param x World x coordinate * @param x World x coordinate
* @param z World z coordinate * @param z World z coordinate
*
* @return Integer representing a web color * @return Integer representing a web color
*/ */
int apply(int x, int z); int apply(int x, int z);

View File

@ -3,6 +3,7 @@ package com.dfsek.terra.addons.image.colorsampler.mutate;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler; import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.api.util.MathUtil; import com.dfsek.terra.api.util.MathUtil;
public class RotateColorSampler implements ColorSampler { public class RotateColorSampler implements ColorSampler {
private final ColorSampler sampler; private final ColorSampler sampler;
@ -15,15 +16,15 @@ public class RotateColorSampler implements ColorSampler {
this.sampler = sampler; this.sampler = sampler;
double normalizedDegrees = degrees % 360.0; double normalizedDegrees = degrees % 360.0;
if (normalizedDegrees < 0) normalizedDegrees += 360.0; if(normalizedDegrees < 0) normalizedDegrees += 360.0;
if (normalizedDegrees == 0.0) if(normalizedDegrees == 0.0)
rotationMethod = RotationMethod.DEG_0; rotationMethod = RotationMethod.DEG_0;
else if (normalizedDegrees == 90.0) else if(normalizedDegrees == 90.0)
rotationMethod = RotationMethod.DEG_90; rotationMethod = RotationMethod.DEG_90;
else if (normalizedDegrees == 180.0) else if(normalizedDegrees == 180.0)
rotationMethod = RotationMethod.DEG_180; rotationMethod = RotationMethod.DEG_180;
else if (normalizedDegrees == 270.0) else if(normalizedDegrees == 270.0)
rotationMethod = RotationMethod.DEG_270; rotationMethod = RotationMethod.DEG_270;
else else
rotationMethod = RotationMethod.RAD_ANY; rotationMethod = RotationMethod.RAD_ANY;

View File

@ -28,28 +28,24 @@ public class ColorLoader implements TypeLoader<ColorString> {
this.argb = parse(string); this.argb = parse(string);
} }
public int getColor() {
return argb;
}
private static int parse(String string) throws IllegalArgumentException { private static int parse(String string) throws IllegalArgumentException {
if (string.length() == 0) if(string.length() == 0)
throw new IllegalArgumentException("Empty string cannot be parsed as a valid color"); throw new IllegalArgumentException("Empty string cannot be parsed as a valid color");
String[] split = string.split(","); String[] split = string.split(",");
if (split.length == 1) if(split.length == 1)
return parseHex(string); return parseHex(string);
else if (split.length == 3) else if(split.length == 3)
return parseChannels("255", split[0], split[1], split[2]); return parseChannels("255", split[0], split[1], split[2]);
else if (split.length == 4) else if(split.length == 4)
return parseChannels(split[0], split[1], split[2], split[3]); return parseChannels(split[0], split[1], split[2], split[3]);
else else
throw new IllegalArgumentException("Invalid channels provided, required format RED,GREEN,BLUE or ALPHA,RED,GREEN,BLUE"); throw new IllegalArgumentException("Invalid channels provided, required format RED,GREEN,BLUE or ALPHA,RED,GREEN,BLUE");
} }
private static int parseHex(String hex) throws IllegalArgumentException { private static int parseHex(String hex) throws IllegalArgumentException {
if (hex.startsWith("#")) if(hex.startsWith("#"))
hex = hex.substring(1); hex = hex.substring(1);
int alpha = 255; int alpha = 255;
@ -71,7 +67,7 @@ public class ColorLoader implements TypeLoader<ColorString> {
blue = Integer.parseInt(hex.substring(4, 6), 16); blue = Integer.parseInt(hex.substring(4, 6), 16);
return ColorUtil.argbValidated(alpha, red, green, blue); return ColorUtil.argbValidated(alpha, red, green, blue);
} catch (NumberFormatException e) { } catch(NumberFormatException e) {
throw new IllegalArgumentException("Failed to parse hex color", e); throw new IllegalArgumentException("Failed to parse hex color", e);
} }
} }
@ -84,9 +80,13 @@ public class ColorLoader implements TypeLoader<ColorString> {
int b = Integer.decode(blue); int b = Integer.decode(blue);
return ColorUtil.argbValidated(a, r, g, b); return ColorUtil.argbValidated(a, r, g, b);
} catch (NumberFormatException e) { } catch(NumberFormatException e) {
throw new IllegalArgumentException("Invalid channel value", e); throw new IllegalArgumentException("Invalid channel value", e);
} }
} }
public int getColor() {
return argb;
}
} }
} }

View File

@ -7,6 +7,7 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.api.properties.Properties; import com.dfsek.terra.api.properties.Properties;
public class ImageLibraryPackConfigTemplate implements ConfigTemplate, Properties { public class ImageLibraryPackConfigTemplate implements ConfigTemplate, Properties {
// TODO - These would be better as plugin wide config parameters in config.yml // TODO - These would be better as plugin wide config parameters in config.yml
@ -17,8 +18,10 @@ public class ImageLibraryPackConfigTemplate implements ConfigTemplate, Propertie
@Value("images.cache.timeout") @Value("images.cache.timeout")
@Description("How many seconds to keep images loaded in the image cache for. " + @Description("How many seconds to keep images loaded in the image cache for. " +
"If set to a number greater than 0, images will be removed from memory if not used after the timeout, otherwise images will stay loaded in memory. " + "If set to a number greater than 0, images will be removed from memory if not used after the timeout, otherwise images " +
"Setting the timeout to greater than 0 will trade decreased memory consumption when not performing any image reads for a period of time for extra processing time required to perform cache lookups.") "will stay loaded in memory. " +
"Setting the timeout to greater than 0 will trade decreased memory consumption when not performing any image reads for a" +
" period of time for extra processing time required to perform cache lookups.")
@Default @Default
private int cacheTimeout = 0; private int cacheTimeout = 0;

View File

@ -27,12 +27,12 @@ record ImageCache(LoadingCache<String, Image> cache) implements Properties {
ImageCache images; ImageCache images;
if(!pack.getContext().has(ImageCache.class)) { if(!pack.getContext().has(ImageCache.class)) {
var cacheBuilder = Caffeine.newBuilder(); var cacheBuilder = Caffeine.newBuilder();
if (config.unloadOnTimeout()) cacheBuilder.expireAfterAccess(config.getCacheTimeout(), TimeUnit.SECONDS); if(config.unloadOnTimeout()) cacheBuilder.expireAfterAccess(config.getCacheTimeout(), TimeUnit.SECONDS);
images = new ImageCache(cacheBuilder.build(s -> loadImage(s, files))); images = new ImageCache(cacheBuilder.build(s -> loadImage(s, files)));
pack.getContext().put(images); pack.getContext().put(images);
} else images = pack.getContext().get(ImageCache.class); } else images = pack.getContext().get(ImageCache.class);
if (config.loadOnUse()) { if(config.loadOnUse()) {
if(config.unloadOnTimeout()) { // Grab directly from cache if images are to unload on timeout if(config.unloadOnTimeout()) { // Grab directly from cache if images are to unload on timeout
return new SuppliedImage(() -> images.cache.get(path)); return new SuppliedImage(() -> images.cache.get(path));
} else { } else {

View File

@ -12,13 +12,11 @@ import com.dfsek.terra.api.config.Loader;
public class ImageTemplate implements ObjectTemplate<Image> { public class ImageTemplate implements ObjectTemplate<Image> {
private final Loader files;
private final ConfigPack pack;
@Value("path") @Value("path")
private String path; private String path;
private final Loader files;
private final ConfigPack pack;
public ImageTemplate(Loader files, ConfigPack pack) { public ImageTemplate(Loader files, ConfigPack pack) {
this.files = files; this.files = files;
this.pack = pack; this.pack = pack;

View File

@ -16,23 +16,18 @@ import com.dfsek.terra.api.config.Loader;
public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedConfigTemplate { public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedConfigTemplate {
private final Loader files;
private final ConfigPack pack;
@Value("path-format") @Value("path-format")
private String path; private String path;
@Value("rows") @Value("rows")
private int rows; private int rows;
@Value("columns") @Value("columns")
private int cols; private int cols;
@Value("zero-indexed") @Value("zero-indexed")
@Default @Default
private boolean zeroIndexed = false; private boolean zeroIndexed = false;
private final Loader files;
private final ConfigPack pack;
public StitchedImageTemplate(Loader files, ConfigPack pack) { public StitchedImageTemplate(Loader files, ConfigPack pack) {
this.files = files; this.files = files;
this.pack = pack; this.pack = pack;
@ -54,7 +49,7 @@ public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedCo
} }
private String getFormattedPath(int row, int column) { private String getFormattedPath(int row, int column) {
if (!zeroIndexed) { if(!zeroIndexed) {
row++; row++;
column++; column++;
} }

View File

@ -69,6 +69,7 @@ public class DistanceTransformNoiseSamplerTemplate implements ObjectTemplate<Noi
@Override @Override
public NoiseSampler get() { public NoiseSampler get() {
return new DistanceTransform.Noise(new DistanceTransform(image, channel, threshold, clampToEdge, costFunction, invertThreshold), normalization); return new DistanceTransform.Noise(new DistanceTransform(image, channel, threshold, clampToEdge, costFunction, invertThreshold),
normalization);
} }
} }

View File

@ -4,6 +4,7 @@ import java.util.Map;
import com.dfsek.terra.addons.image.util.ColorUtil; import com.dfsek.terra.addons.image.util.ColorUtil;
public class ClosestMatchColorConverter<T> implements ColorConverter<T> { public class ClosestMatchColorConverter<T> implements ColorConverter<T> {
private final Map<Integer, T> map; private final Map<Integer, T> map;

View File

@ -16,7 +16,7 @@ public class ExactColorConverter<T> implements ColorConverter<T> {
private final boolean ignoreAlpha; private final boolean ignoreAlpha;
public ExactColorConverter(Map<Integer, T> map, T fallback, boolean ignoreAlpha) { public ExactColorConverter(Map<Integer, T> map, T fallback, boolean ignoreAlpha) {
if (ignoreAlpha) { if(ignoreAlpha) {
map = MapUtil.mapKeys(map, ColorUtil::zeroAlpha); map = MapUtil.mapKeys(map, ColorUtil::zeroAlpha);
} }
this.map = map; this.map = map;
@ -26,7 +26,7 @@ public class ExactColorConverter<T> implements ColorConverter<T> {
@Override @Override
public T apply(int color) { public T apply(int color) {
if (ignoreAlpha) { if(ignoreAlpha) {
color = ColorUtil.zeroAlpha(color); color = ColorUtil.zeroAlpha(color);
} }
T lookup = map.get(color); T lookup = map.get(color);

View File

@ -30,7 +30,8 @@ public class BiomeDefinedColorMapping<T> implements ColorMapping<T> {
if(!output.containsKey(color)) { if(!output.containsKey(color)) {
output.put(color, biome); output.put(color, biome);
} else { } else {
throw new IllegalArgumentException(String.format("Biome %s has same color as %s: %x", biome.getID(), output.get(color).getID(), color)); throw new IllegalArgumentException(
String.format("Biome %s has same color as %s: %x", biome.getID(), output.get(color).getID(), color));
} }
})); }));
return output.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> converter.apply(e.getValue()))); return output.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> converter.apply(e.getValue())));

View File

@ -40,7 +40,7 @@ public class StitchedImage implements Image {
} }
private int getColumn(int x) { private int getColumn(int x) {
for(int i = columnOffsets.length-1; i > 0; i--) { for(int i = columnOffsets.length - 1; i > 0; i--) {
if(x >= columnOffsets[i]) if(x >= columnOffsets[i])
return i; return i;
} }
@ -48,7 +48,7 @@ public class StitchedImage implements Image {
} }
private int getRow(int y) { private int getRow(int y) {
for(int i = rowOffsets.length-1; i > 0; i--) { for(int i = rowOffsets.length - 1; i > 0; i--) {
if(y >= rowOffsets[i]) if(y >= rowOffsets[i])
return i; return i;
} }
@ -59,7 +59,7 @@ public class StitchedImage implements Image {
public int getRGB(int x, int y) { public int getRGB(int x, int y) {
int row = getRow(y); int row = getRow(y);
int column = getColumn(x); int column = getColumn(x);
return images[row][column].getRGB(x-columnOffsets[column], y-rowOffsets[row]); return images[row][column].getRGB(x - columnOffsets[column], y - rowOffsets[row]);
} }
@Override @Override

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.addons.image.image;
import java.util.function.Supplier; import java.util.function.Supplier;
public class SuppliedImage implements Image { public class SuppliedImage implements Image {
private final Supplier<Image> imageSupplier; private final Supplier<Image> imageSupplier;

View File

@ -16,21 +16,20 @@ import static com.dfsek.terra.addons.image.util.MathUtil.lerp;
*/ */
public class DistanceTransform { public class DistanceTransform {
private static final double MAX_DISTANCE_CAP = 10_000_000; // Arbitrarily large value, doubtful someone would
private final double[][] distances; private final double[][] distances;
/** /**
* Size bounds matching the provided image. * Size bounds matching the provided image.
*/ */
private final int width, height; private final int width, height;
/** /**
* Min and max distances of the distance computation. These may change after {@link #normalize(Normalization)} calls. * Min and max distances of the distance computation. These may change after {@link #normalize(Normalization)} calls.
*/ */
private double minDistance, maxDistance; private double minDistance, maxDistance;
private static final double MAX_DISTANCE_CAP = 10_000_000; // Arbitrarily large value, doubtful someone would
// ever use an image large enough to exceed this. // ever use an image large enough to exceed this.
public DistanceTransform(Image image, Channel channel, int threshold, boolean clampToMaxEdgeDistance, CostFunction costFunction, boolean invertThreshold) { public DistanceTransform(Image image, Channel channel, int threshold, boolean clampToMaxEdgeDistance, CostFunction costFunction,
boolean invertThreshold) {
// Construct binary image based on threshold value // Construct binary image based on threshold value
boolean[][] binaryImage = new boolean[image.getWidth()][image.getHeight()]; boolean[][] binaryImage = new boolean[image.getWidth()][image.getHeight()];
for(int x = 0; x < image.getWidth(); x++) { for(int x = 0; x < image.getWidth(); x++) {
@ -47,17 +46,17 @@ public class DistanceTransform {
binaryImageEdge[x][y] = false; binaryImageEdge[x][y] = false;
else else
// If cell borders any false cell // If cell borders any false cell
binaryImageEdge[x][y] = x > 0 && !binaryImage[x-1][y] || binaryImageEdge[x][y] = x > 0 && !binaryImage[x - 1][y] ||
y > 0 && !binaryImage[x][y-1] || y > 0 && !binaryImage[x][y - 1] ||
x < image.getWidth ()-1 && !binaryImage[x+1][y] || x < image.getWidth() - 1 && !binaryImage[x + 1][y] ||
y < image.getHeight()-1 && !binaryImage[x][y+1]; y < image.getHeight() - 1 && !binaryImage[x][y + 1];
} }
} }
double[][] function = new double[image.getWidth()][image.getHeight()]; double[][] function = new double[image.getWidth()][image.getHeight()];
for(int x = 0; x < image.getWidth(); x++) { for(int x = 0; x < image.getWidth(); x++) {
for(int y = 0; y < image.getHeight(); y++) { for(int y = 0; y < image.getHeight(); y++) {
function[x][y] = switch (costFunction) { function[x][y] = switch(costFunction) {
case Channel -> ColorUtil.getChannel(image.getRGB(x, y), channel); case Channel -> ColorUtil.getChannel(image.getRGB(x, y), channel);
case Threshold -> binaryImage[x][y] ? MAX_DISTANCE_CAP : 0; case Threshold -> binaryImage[x][y] ? MAX_DISTANCE_CAP : 0;
case ThresholdEdge, ThresholdEdgeSigned -> binaryImageEdge[x][y] ? 0 : MAX_DISTANCE_CAP; case ThresholdEdge, ThresholdEdgeSigned -> binaryImageEdge[x][y] ? 0 : MAX_DISTANCE_CAP;
@ -80,11 +79,11 @@ public class DistanceTransform {
double max = Double.NEGATIVE_INFINITY; double max = Double.NEGATIVE_INFINITY;
for(int x = 0; x < image.getWidth(); x++) { for(int x = 0; x < image.getWidth(); x++) {
max = Math.max(max, distances[x][0]); max = Math.max(max, distances[x][0]);
max = Math.max(max, distances[x][image.getHeight()-1]); max = Math.max(max, distances[x][image.getHeight() - 1]);
} }
for(int y = 0; y < image.getHeight(); y++) { for(int y = 0; y < image.getHeight(); y++) {
max = Math.max(max, distances[0][y]); max = Math.max(max, distances[0][y]);
max = Math.max(max, distances[image.getWidth()-1][y]); max = Math.max(max, distances[image.getWidth() - 1][y]);
} }
// Clamp to that largest value // Clamp to that largest value
for(int x = 0; x < image.getWidth(); x++) { for(int x = 0; x < image.getWidth(); x++) {
@ -122,28 +121,28 @@ public class DistanceTransform {
private double[] calculateDistance1D(double[] f) { private double[] calculateDistance1D(double[] f) {
double[] d = new double[f.length]; double[] d = new double[f.length];
int[] v = new int[f.length]; int[] v = new int[f.length];
double[] z = new double[f.length+1]; double[] z = new double[f.length + 1];
int k = 0; int k = 0;
v[0] = 0; v[0] = 0;
z[0] = Integer.MIN_VALUE; z[0] = Integer.MIN_VALUE;
z[1] = Integer.MAX_VALUE; z[1] = Integer.MAX_VALUE;
for(int q = 1; q <= f.length-1; q++) { for(int q = 1; q <= f.length - 1; q++) {
double s = ((f[q]+Math.pow(q, 2))-(f[v[k]]+Math.pow(v[k], 2)))/(2*q-2*v[k]); double s = ((f[q] + Math.pow(q, 2)) - (f[v[k]] + Math.pow(v[k], 2))) / (2 * q - 2 * v[k]);
while (s <= z[k]) { while(s <= z[k]) {
k--; k--;
s = ((f[q]+Math.pow(q, 2))-(f[v[k]]+Math.pow(v[k], 2)))/(2*q-2*v[k]); s = ((f[q] + Math.pow(q, 2)) - (f[v[k]] + Math.pow(v[k], 2))) / (2 * q - 2 * v[k]);
} }
k++; k++;
v[k] = q; v[k] = q;
z[k] = s; z[k] = s;
z[k+1] = Integer.MAX_VALUE; z[k + 1] = Integer.MAX_VALUE;
} }
k = 0; k = 0;
for(int q = 0; q <= f.length-1; q++) { for(int q = 0; q <= f.length - 1; q++) {
while(z[k+1] < q) while(z[k + 1] < q)
k++; k++;
d[q] = Math.pow(q-v[k], 2) + f[v[k]]; d[q] = Math.pow(q - v[k], 2) + f[v[k]];
} }
return d; return d;
} }
@ -164,9 +163,9 @@ public class DistanceTransform {
yield lerp(distances[x][y], minDistance, -1, maxDistance, 1); yield lerp(distances[x][y], minDistance, -1, maxDistance, 1);
} else { } else {
if(d > 0) { if(d > 0) {
yield Math.pow(d/maxDistance, 2); yield Math.pow(d / maxDistance, 2);
} else if(d < 0) { } else if(d < 0) {
yield -Math.pow(d/minDistance, 2); yield -Math.pow(d / minDistance, 2);
} else { } else {
yield 0; yield 0;
} }
@ -198,6 +197,7 @@ public class DistanceTransform {
ThresholdEdgeSigned, ThresholdEdgeSigned,
} }
public enum Normalization { public enum Normalization {
/** /**
* Return the raw calculated distances. * Return the raw calculated distances.
@ -217,6 +217,7 @@ public class DistanceTransform {
SmoothPreserveZero, SmoothPreserveZero,
} }
public static class Noise implements NoiseSampler { public static class Noise implements NoiseSampler {
private final DistanceTransform transform; private final DistanceTransform transform;
@ -228,7 +229,7 @@ public class DistanceTransform {
@Override @Override
public double noise(long seed, double x, double y) { public double noise(long seed, double x, double y) {
if(x<0 || y<0 || x>=transform.width || y>=transform.height) return transform.minDistance; if(x < 0 || y < 0 || x >= transform.width || y >= transform.height) return transform.minDistance;
return transform.distances[(int) Math.floor(x)][(int) Math.floor(y)]; return transform.distances[(int) Math.floor(x)][(int) Math.floor(y)];
} }

View File

@ -5,7 +5,7 @@ package com.dfsek.terra.addons.image.util;
*/ */
public class ColorUtil { public class ColorUtil {
private ColorUtil() {} private ColorUtil() { }
public static int distance(int a, int b) { public static int distance(int a, int b) {
return Math.abs(getRed(a) - getRed(b)) + return Math.abs(getRed(a) - getRed(b)) +
@ -17,6 +17,7 @@ public class ColorUtil {
* Returns the red channel value of a given ARGB color value. * Returns the red channel value of a given ARGB color value.
* *
* @param argb the ARGB color value to extract the red channel value from * @param argb the ARGB color value to extract the red channel value from
*
* @return the red channel value of the given ARGB color value, in the range 0-255 * @return the red channel value of the given ARGB color value, in the range 0-255
*/ */
public static int getRed(int argb) { public static int getRed(int argb) {
@ -27,6 +28,7 @@ public class ColorUtil {
* Returns the green channel value of a given ARGB color value. * Returns the green channel value of a given ARGB color value.
* *
* @param argb the ARGB color value to extract the green channel value from * @param argb the ARGB color value to extract the green channel value from
*
* @return the green channel value of the given ARGB color value, in the range 0-255 * @return the green channel value of the given ARGB color value, in the range 0-255
*/ */
public static int getGreen(int argb) { public static int getGreen(int argb) {
@ -37,6 +39,7 @@ public class ColorUtil {
* Returns the blue channel value of a given ARGB color value. * Returns the blue channel value of a given ARGB color value.
* *
* @param argb the ARGB color value to extract the blue channel value from * @param argb the ARGB color value to extract the blue channel value from
*
* @return the blue channel value of the given ARGB color value, in the range 0-255 * @return the blue channel value of the given ARGB color value, in the range 0-255
*/ */
public static int getBlue(int argb) { public static int getBlue(int argb) {
@ -47,6 +50,7 @@ public class ColorUtil {
* Returns the alpha channel value of a given ARGB color value. * Returns the alpha channel value of a given ARGB color value.
* *
* @param argb the ARGB color value to extract the blue channel value from * @param argb the ARGB color value to extract the blue channel value from
*
* @return the alpha channel value of the given ARGB color value, in the range 0-255 * @return the alpha channel value of the given ARGB color value, in the range 0-255
*/ */
public static int getAlpha(int argb) { public static int getAlpha(int argb) {
@ -57,6 +61,7 @@ public class ColorUtil {
* Returns the grayscale value of a given ARGB color value. * Returns the grayscale value of a given ARGB color value.
* *
* @param argb the ARGB color value to convert to grayscale * @param argb the ARGB color value to convert to grayscale
*
* @return the grayscale value of the given ARGB color value, in the range 0-255 * @return the grayscale value of the given ARGB color value, in the range 0-255
*/ */
public static int getGrayscale(int argb) { public static int getGrayscale(int argb) {
@ -68,6 +73,7 @@ public class ColorUtil {
* *
* @param argb the ARGB color value to extract the channel value from * @param argb the ARGB color value to extract the channel value from
* @param channel the channel to extract the value from * @param channel the channel to extract the value from
*
* @return the value of the specified channel for the given ARGB color value, in the range 0-255 * @return the value of the specified channel for the given ARGB color value, in the range 0-255
*/ */
public static int getChannel(int argb, Channel channel) { public static int getChannel(int argb, Channel channel) {
@ -78,6 +84,7 @@ public class ColorUtil {
* Sets the red channel value of a given ARGB color value to zero. * Sets the red channel value of a given ARGB color value to zero.
* *
* @param argb the ARGB color value to zero the red channel of * @param argb the ARGB color value to zero the red channel of
*
* @return the resulting ARGB color value with the red channel set to zero * @return the resulting ARGB color value with the red channel set to zero
*/ */
public static int zeroRed(int argb) { public static int zeroRed(int argb) {
@ -88,6 +95,7 @@ public class ColorUtil {
* Sets the green channel value of a given ARGB color value to zero. * Sets the green channel value of a given ARGB color value to zero.
* *
* @param argb the ARGB color value to zero the green channel of * @param argb the ARGB color value to zero the green channel of
*
* @return the resulting ARGB color value with the green channel set to zero * @return the resulting ARGB color value with the green channel set to zero
*/ */
public static int zeroGreen(int argb) { public static int zeroGreen(int argb) {
@ -98,6 +106,7 @@ public class ColorUtil {
* Sets the blue channel value of a given ARGB color value to zero. * Sets the blue channel value of a given ARGB color value to zero.
* *
* @param argb the ARGB color value to zero the blue channel of * @param argb the ARGB color value to zero the blue channel of
*
* @return the resulting ARGB color value with the blue channel set to zero * @return the resulting ARGB color value with the blue channel set to zero
*/ */
public static int zeroBlue(int argb) { public static int zeroBlue(int argb) {
@ -109,6 +118,7 @@ public class ColorUtil {
* This is the same as setting the color to fully transparent. * This is the same as setting the color to fully transparent.
* *
* @param argb the ARGB color value to zero the alpha channel of * @param argb the ARGB color value to zero the alpha channel of
*
* @return the resulting ARGB color value with the alpha channel set to zero * @return the resulting ARGB color value with the alpha channel set to zero
*/ */
public static int zeroAlpha(int argb) { public static int zeroAlpha(int argb) {
@ -120,6 +130,7 @@ public class ColorUtil {
* This is the same as setting the color to black, while preserving the alpha. * This is the same as setting the color to black, while preserving the alpha.
* *
* @param argb the ARGB color value to zero the color channel of * @param argb the ARGB color value to zero the color channel of
*
* @return the resulting ARGB color value with the color channels set to zero * @return the resulting ARGB color value with the color channels set to zero
*/ */
public static int zeroGrayscale(int argb) { public static int zeroGrayscale(int argb) {
@ -131,6 +142,7 @@ public class ColorUtil {
* *
* @param argb the ARGB color value to zero the specified channel of * @param argb the ARGB color value to zero the specified channel of
* @param channel the channel to zero the value of * @param channel the channel to zero the value of
*
* @return the resulting ARGB color value with the specified channel value set to zero * @return the resulting ARGB color value with the specified channel value set to zero
*/ */
public static int zeroChannel(int argb, Channel channel) { public static int zeroChannel(int argb, Channel channel) {
@ -141,6 +153,7 @@ public class ColorUtil {
* Multiply the RGB channels of a given ARGB color value by its alpha channel value. * Multiply the RGB channels of a given ARGB color value by its alpha channel value.
* *
* @param argb the ARGB color value to premultiply the RGB channels of * @param argb the ARGB color value to premultiply the RGB channels of
*
* @return the resulting premultiplied ARGB color value * @return the resulting premultiplied ARGB color value
*/ */
public static int premultiply(int argb) { public static int premultiply(int argb) {
@ -158,6 +171,7 @@ public class ColorUtil {
* @param red the red value, between 0 and 255, to set in the ARGB color value * @param red the red value, between 0 and 255, to set in the ARGB color value
* @param green the green value, between 0 and 255, to set in the ARGB color value * @param green the green value, between 0 and 255, to set in the ARGB color value
* @param blue the blue value, between 0 and 255, to set in the ARGB color value * @param blue the blue value, between 0 and 255, to set in the ARGB color value
*
* @return the resulting ARGB color value with the specified values for alpha, red, green, and blue channels * @return the resulting ARGB color value with the specified values for alpha, red, green, and blue channels
*/ */
public static int argb(int alpha, int red, int green, int blue) { public static int argb(int alpha, int red, int green, int blue) {
@ -172,11 +186,13 @@ public class ColorUtil {
* @param red the red value, between 0 and 255, to set in the ARGB color value * @param red the red value, between 0 and 255, to set in the ARGB color value
* @param green the green value, between 0 and 255, to set in the ARGB color value * @param green the green value, between 0 and 255, to set in the ARGB color value
* @param blue the blue value, between 0 and 255, to set in the ARGB color value * @param blue the blue value, between 0 and 255, to set in the ARGB color value
*
* @return the resulting ARGB color value with the specified values for alpha, red, green, and blue channels * @return the resulting ARGB color value with the specified values for alpha, red, green, and blue channels
*
* @throws IllegalArgumentException if any channel value is outside the range 0-255 * @throws IllegalArgumentException if any channel value is outside the range 0-255
*/ */
public static int argbValidated(int alpha, int red, int green, int blue) throws IllegalArgumentException { public static int argbValidated(int alpha, int red, int green, int blue) throws IllegalArgumentException {
if (alpha < 0 || alpha > 255 || if(alpha < 0 || alpha > 255 ||
red < 0 || red > 255 || red < 0 || red > 255 ||
green < 0 || green > 255 || green < 0 || green > 255 ||
blue < 0 || blue > 255 blue < 0 || blue > 255
@ -189,6 +205,7 @@ public class ColorUtil {
* for the red, green, and blue channels. * for the red, green, and blue channels.
* *
* @param alpha the alpha channel value to set in the ARGB color value * @param alpha the alpha channel value to set in the ARGB color value
*
* @return the resulting ARGB color value * @return the resulting ARGB color value
*/ */
public static int argbAlpha(int alpha) { return alpha << 24; } public static int argbAlpha(int alpha) { return alpha << 24; }
@ -198,6 +215,7 @@ public class ColorUtil {
* for the alpha, green, and blue channels. * for the alpha, green, and blue channels.
* *
* @param red the red channel value to set in the ARGB color value * @param red the red channel value to set in the ARGB color value
*
* @return the resulting ARGB color value * @return the resulting ARGB color value
*/ */
public static int argbRed(int red) { return red << 16; } public static int argbRed(int red) { return red << 16; }
@ -207,6 +225,7 @@ public class ColorUtil {
* for the alpha, red, and blue channels. * for the alpha, red, and blue channels.
* *
* @param green the green channel value to set in the ARGB color value * @param green the green channel value to set in the ARGB color value
*
* @return the resulting ARGB color value * @return the resulting ARGB color value
*/ */
public static int argbGreen(int green) { return green << 8; } public static int argbGreen(int green) { return green << 8; }
@ -216,6 +235,7 @@ public class ColorUtil {
* for the alpha, red, and green channels. * for the alpha, red, and green channels.
* *
* @param blue the blue channel value to set in the ARGB color value * @param blue the blue channel value to set in the ARGB color value
*
* @return the resulting ARGB color value * @return the resulting ARGB color value
*/ */
public static int argbBlue(int blue) { return blue; } public static int argbBlue(int blue) { return blue; }
@ -224,6 +244,7 @@ public class ColorUtil {
* Returns an ARGB color value with the specified grayscale value for all four channels. * Returns an ARGB color value with the specified grayscale value for all four channels.
* *
* @param value the grayscale value to set in all four channels of the ARGB color value * @param value the grayscale value to set in all four channels of the ARGB color value
*
* @return the resulting ARGB color value with the specified grayscale value for all four channels * @return the resulting ARGB color value with the specified grayscale value for all four channels
*/ */
public static int argbGrayscale(int value) { return argb(value, value, value, value); } public static int argbGrayscale(int value) { return argb(value, value, value, value); }

View File

@ -8,7 +8,7 @@ import java.util.stream.Collectors;
public class MapUtil { public class MapUtil {
private MapUtil() {} private MapUtil() { }
/** /**
* Utility method for applying transformations on a map's keys. * Utility method for applying transformations on a map's keys.

View File

@ -1,9 +1,9 @@
package com.dfsek.terra.addons.image.util; package com.dfsek.terra.addons.image.util;
public class MathUtil { public class MathUtil {
private MathUtil() {} private MathUtil() { }
public static double lerp(double x, double x1, double y1, double x2, double y2) { public static double lerp(double x, double x1, double y1, double x2, double y2) {
return (((y1-y2)*(x-x1))/(x1-x2))+y1; return (((y1 - y2) * (x - x1)) / (x1 - x2)) + y1;
} }
} }

View File

@ -28,10 +28,12 @@ import com.dfsek.terra.api.world.biome.Biome;
public class PipelineImageAddon implements AddonInitializer { public class PipelineImageAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<ColorConverter<PipelineBiome>>>> PIPELINE_BIOME_COLOR_CONVERTER_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<ColorConverter<PipelineBiome>>>> PIPELINE_BIOME_COLOR_CONVERTER_REGISTRY_KEY =
new TypeKey<>() {
}; };
public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<PipelineBiome>>>> PIPELINE_BIOME_COLOR_MAPPING_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<PipelineBiome>>>> PIPELINE_BIOME_COLOR_MAPPING_REGISTRY_KEY =
new TypeKey<>() {
}; };
@Inject @Inject
@ -48,19 +50,24 @@ public class PipelineImageAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
.priority(500) .priority(500)
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<PipelineBiome>>>> biomeColorConverterRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<PipelineBiome>>>> biomeColorConverterRegistry =
event.getPack().getOrCreateRegistry(
PIPELINE_BIOME_COLOR_CONVERTER_REGISTRY_KEY); PIPELINE_BIOME_COLOR_CONVERTER_REGISTRY_KEY);
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactPipelineBiomeColorConverterTemplate::new); biomeColorConverterRegistry.register(addon.key("EXACT"), ExactPipelineBiomeColorConverterTemplate::new);
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestPipelineBiomeColorConverterTemplate::new); biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestPipelineBiomeColorConverterTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry(BiomePipelineAddon.SOURCE_REGISTRY_KEY); CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry(
BiomePipelineAddon.SOURCE_REGISTRY_KEY);
sourceRegistry.register(addon.key("IMAGE"), ImageSourceTemplate::new); sourceRegistry.register(addon.key("IMAGE"), ImageSourceTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<PipelineBiome>>>> biomeColorMappingRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<PipelineBiome>>>> biomeColorMappingRegistry =
event.getPack().getOrCreateRegistry(
PIPELINE_BIOME_COLOR_MAPPING_REGISTRY_KEY); PIPELINE_BIOME_COLOR_MAPPING_REGISTRY_KEY);
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"), () -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class), DelegatedPipelineBiome::new)); biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"),
() -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class),
DelegatedPipelineBiome::new));
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedPipelineBiomeColorMappingTemplate::new); biomeColorMappingRegistry.register(addon.key("MAP"), DefinedPipelineBiomeColorMappingTemplate::new);
}) })
.failThrough(); .failThrough();

View File

@ -7,36 +7,11 @@
package com.dfsek.terra.addons.terrascript.script; package com.dfsek.terra.addons.terrascript.script;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Random;
import com.dfsek.terra.addons.terrascript.parser.Parser; import com.dfsek.terra.addons.terrascript.parser.Parser;
import com.dfsek.terra.addons.terrascript.parser.lang.Executable; import com.dfsek.terra.addons.terrascript.parser.lang.Executable;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.functions.FunctionBuilder; import com.dfsek.terra.addons.terrascript.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.BinaryNumberFunctionBuilder; import com.dfsek.terra.addons.terrascript.script.builders.*;
import com.dfsek.terra.addons.terrascript.script.builders.BiomeFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.BlockFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.CheckBlockFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.EntityFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.GetMarkFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.LootFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.PullFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.RandomFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.RecursionsFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.SetMarkFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.StateFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.StructureFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.UnaryBooleanFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.UnaryNumberFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.UnaryStringFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.ZeroArgFunctionBuilder;
import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.registry.key.Keyed; import com.dfsek.terra.api.registry.key.Keyed;
@ -48,6 +23,15 @@ import com.dfsek.terra.api.util.Rotation;
import com.dfsek.terra.api.util.vector.Vector3Int; import com.dfsek.terra.api.util.vector.Vector3Int;
import com.dfsek.terra.api.world.WritableWorld; import com.dfsek.terra.api.world.WritableWorld;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Random;
public class StructureScript implements Structure, Keyed<StructureScript> { public class StructureScript implements Structure, Keyed<StructureScript> {
private static final Logger LOGGER = LoggerFactory.getLogger(StructureScript.class); private static final Logger LOGGER = LoggerFactory.getLogger(StructureScript.class);

View File

@ -7,9 +7,6 @@
package com.dfsek.terra.addons.terrascript.script.functions; package com.dfsek.terra.addons.terrascript.script.functions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.Scope; import com.dfsek.terra.addons.terrascript.parser.lang.Scope;
@ -21,6 +18,9 @@ import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.util.vector.Vector2; import com.dfsek.terra.api.util.vector.Vector2;
import com.dfsek.terra.api.util.vector.Vector3; import com.dfsek.terra.api.util.vector.Vector3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StateFunction implements Function<Void> { public class StateFunction implements Function<Void> {
private static final Logger LOGGER = LoggerFactory.getLogger(StateFunction.class); private static final Logger LOGGER = LoggerFactory.getLogger(StateFunction.class);

View File

@ -7,11 +7,6 @@
package com.dfsek.terra.api; package com.dfsek.terra.api;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import com.dfsek.terra.api.addon.BaseAddon; import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.config.PluginConfig; import com.dfsek.terra.api.config.PluginConfig;
@ -23,6 +18,11 @@ import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.tectonic.LoaderRegistrar; import com.dfsek.terra.api.tectonic.LoaderRegistrar;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/** /**
* Represents a Terra mod/plugin instance. * Represents a Terra mod/plugin instance.

View File

@ -14,11 +14,14 @@ import java.util.List;
* Utility class for mathematical functions. * Utility class for mathematical functions.
*/ */
public final class MathUtil { public final class MathUtil {
/**
* Epsilon for fuzzy floating point comparisons.
*/
public static final double EPSILON = 1.0E-5;
private static final int SIN_BITS, SIN_MASK, SIN_COUNT; private static final int SIN_BITS, SIN_MASK, SIN_COUNT;
private static final double radFull, radToIndex; private static final double radFull, radToIndex;
private static final double degFull, degToIndex; private static final double degFull, degToIndex;
private static final double[] sin, cos; private static final double[] sin, cos;
static { static {
SIN_BITS = 12; SIN_BITS = 12;
SIN_MASK = ~(-1 << SIN_BITS); SIN_MASK = ~(-1 << SIN_BITS);
@ -32,23 +35,18 @@ public final class MathUtil {
sin = new double[SIN_COUNT]; sin = new double[SIN_COUNT];
cos = new double[SIN_COUNT]; cos = new double[SIN_COUNT];
for (int i = 0; i < SIN_COUNT; i++) { for(int i = 0; i < SIN_COUNT; i++) {
sin[i] = Math.sin((i + 0.5f) / SIN_COUNT * radFull); sin[i] = Math.sin((i + 0.5f) / SIN_COUNT * radFull);
cos[i] = Math.cos((i + 0.5f) / SIN_COUNT * radFull); cos[i] = Math.cos((i + 0.5f) / SIN_COUNT * radFull);
} }
// Four cardinal directions (credits: Nate) // Four cardinal directions (credits: Nate)
for (int i = 0; i < 360; i += 90) { for(int i = 0; i < 360; i += 90) {
sin[(int) (i * degToIndex) & SIN_MASK] = Math.sin(i * Math.PI / 180.0); sin[(int) (i * degToIndex) & SIN_MASK] = Math.sin(i * Math.PI / 180.0);
cos[(int) (i * degToIndex) & SIN_MASK] = Math.cos(i * Math.PI / 180.0); cos[(int) (i * degToIndex) & SIN_MASK] = Math.cos(i * Math.PI / 180.0);
} }
} }
/**
* Epsilon for fuzzy floating point comparisons.
*/
public static final double EPSILON = 1.0E-5;
public static double sin(double rad) { public static double sin(double rad) {
return sin[(int) (rad * radToIndex) & SIN_MASK]; return sin[(int) (rad * radToIndex) & SIN_MASK];
} }
@ -114,7 +112,7 @@ public final class MathUtil {
} }
public static int normalizeIndex(double val, int size) { public static int normalizeIndex(double val, int size) {
return Math.max(Math.min((int)Math.floor(((val + 1D) / 2D) * size), size - 1), 0); return Math.max(Math.min((int) Math.floor(((val + 1D) / 2D) * size), size - 1), 0);
} }
public static long squash(int first, int last) { public static long squash(int first, int last) {

View File

@ -57,13 +57,15 @@ public class ProbabilityCollection<E> implements Collection<E> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public E get(NoiseSampler n, Vector3Int vector3Int, long seed) { public E get(NoiseSampler n, Vector3Int vector3Int, long seed) {
if(array.length == 0) return null; if(array.length == 0) return null;
return (E) array[(int) MathUtil.normalizeIndex(n.noise(seed, vector3Int.getX(), vector3Int.getY(), vector3Int.getZ()), array.length)]; return (E) array[(int) MathUtil.normalizeIndex(n.noise(seed, vector3Int.getX(), vector3Int.getY(), vector3Int.getZ()),
array.length)];
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public E get(NoiseSampler n, Vector3 vector3Int, long seed) { public E get(NoiseSampler n, Vector3 vector3Int, long seed) {
if(array.length == 0) return null; if(array.length == 0) return null;
return (E) array[(int) MathUtil.normalizeIndex(n.noise(seed, vector3Int.getX(), vector3Int.getY(), vector3Int.getZ()), array.length)]; return (E) array[(int) MathUtil.normalizeIndex(n.noise(seed, vector3Int.getX(), vector3Int.getY(), vector3Int.getZ()),
array.length)];
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -28,6 +28,7 @@ public class Vector2 {
this.x = x; this.x = x;
this.z = z; this.z = z;
} }
public static Vector2 zero() { public static Vector2 zero() {
return ZERO; return ZERO;
} }

View File

@ -22,6 +22,7 @@ public class Vector3 {
this.y = y; this.y = y;
this.z = z; this.z = z;
} }
public static Vector3 zero() { public static Vector3 zero() {
return ZERO; return ZERO;
} }

View File

@ -33,6 +33,7 @@ import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.config.Loader; import com.dfsek.terra.api.config.Loader;
import com.dfsek.terra.api.properties.Properties; import com.dfsek.terra.api.properties.Properties;
/* /*
* @deprecated Use the Image and ImageLoader class provided by the library-image addon instead. This is subject to removal in v7. * @deprecated Use the Image and ImageLoader class provided by the library-image addon instead. This is subject to removal in v7.
*/ */
@ -45,7 +46,7 @@ public class BufferedImageLoader implements TypeLoader<BufferedImage> {
public BufferedImageLoader(Loader files, ConfigPack pack) { public BufferedImageLoader(Loader files, ConfigPack pack) {
this.files = files; this.files = files;
this.pack = pack; this.pack = pack;
if (!pack.getContext().has(ImageCache.class)) if(!pack.getContext().has(ImageCache.class))
pack.getContext().put(new ImageCache(new ConcurrentHashMap<>())); pack.getContext().put(new ImageCache(new ConcurrentHashMap<>()));
} }

View File

@ -68,7 +68,8 @@ public class MetaListLikePreprocessor extends MetaPreprocessor<Meta> {
if(!(metaValue instanceof List)) { if(!(metaValue instanceof List)) {
throw new LoadException( throw new LoadException(
"Meta list / set injection (via <<) must point to a list. '" + meta + "' points to type " + metaValue.getClass().getCanonicalName(), "Meta list / set injection (via <<) must point to a list. '" + meta + "' points to type " +
metaValue.getClass().getCanonicalName(),
depthTracker); depthTracker);
} }

View File

@ -4,7 +4,6 @@ terra.source=https://github.com/PolyhedralDev/Terra
terra.issues=https://github.com/PolyhedralDev/Terra/issues terra.issues=https://github.com/PolyhedralDev/Terra/issues
terra.wiki=https://github.com/PolyhedralDev/Terra/wiki terra.wiki=https://github.com/PolyhedralDev/Terra/wiki
terra.license=MIT terra.license=MIT
# Gradle options # Gradle options
org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC
org.gradle.warning.mode=all org.gradle.warning.mode=all

View File

@ -8,7 +8,7 @@ dependencies {
compileOnly("io.papermc.paper", "paper-api", Versions.Bukkit.paper) compileOnly("io.papermc.paper", "paper-api", Versions.Bukkit.paper)
shadedApi("io.papermc", "paperlib", Versions.Bukkit.paperLib) shadedApi("io.papermc", "paperlib", Versions.Bukkit.paperLib)
shadedApi("com.tcoded", "FoliaLib" , Versions.Bukkit.foliaLib) shadedApi("com.tcoded", "FoliaLib", Versions.Bukkit.foliaLib)
shadedApi("com.google.guava", "guava", Versions.Libraries.Internal.guava) shadedApi("com.google.guava", "guava", Versions.Libraries.Internal.guava)
shadedApi("cloud.commandframework", "cloud-paper", Versions.Libraries.cloud) shadedApi("cloud.commandframework", "cloud-paper", Versions.Libraries.cloud)

View File

@ -13,8 +13,8 @@ import com.dfsek.terra.bukkit.world.BukkitProtoWorld;
public class BukkitBlockPopulator extends BlockPopulator { public class BukkitBlockPopulator extends BlockPopulator {
private ConfigPack pack;
private final BlockState air; private final BlockState air;
private ConfigPack pack;
public BukkitBlockPopulator(ConfigPack pack, BlockState air) { public BukkitBlockPopulator(ConfigPack pack, BlockState air) {
this.pack = pack; this.pack = pack;
@ -28,6 +28,7 @@ public class BukkitBlockPopulator extends BlockPopulator {
@Override @Override
public void populate(@NotNull WorldInfo worldInfo, @NotNull Random random, int chunkX, int chunkZ, public void populate(@NotNull WorldInfo worldInfo, @NotNull Random random, int chunkX, int chunkZ,
@NotNull LimitedRegion limitedRegion) { @NotNull LimitedRegion limitedRegion) {
pack.getStages().forEach(generationStage -> generationStage.populate(new BukkitProtoWorld(limitedRegion, air, pack.getBiomeProvider()))); pack.getStages().forEach(
generationStage -> generationStage.populate(new BukkitProtoWorld(limitedRegion, air, pack.getBiomeProvider())));
} }
} }

View File

@ -40,9 +40,9 @@ import com.dfsek.terra.bukkit.world.BukkitWorldProperties;
public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGenerator implements GeneratorWrapper { public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGenerator implements GeneratorWrapper {
private static final Logger LOGGER = LoggerFactory.getLogger(BukkitChunkGeneratorWrapper.class); private static final Logger LOGGER = LoggerFactory.getLogger(BukkitChunkGeneratorWrapper.class);
private final BlockState air; private final BlockState air;
private final BukkitBlockPopulator blockPopulator;
private ChunkGenerator delegate; private ChunkGenerator delegate;
private ConfigPack pack; private ConfigPack pack;
private final BukkitBlockPopulator blockPopulator;
public BukkitChunkGeneratorWrapper(ChunkGenerator delegate, ConfigPack pack, BlockState air) { public BukkitChunkGeneratorWrapper(ChunkGenerator delegate, ConfigPack pack, BlockState air) {

View File

@ -56,7 +56,8 @@ public class BukkitWorldHandle implements WorldHandle {
return new BukkitEntityType(switch(entityID) { return new BukkitEntityType(switch(entityID) {
case "END_CRYSTAL" -> org.bukkit.entity.EntityType.ENDER_CRYSTAL; case "END_CRYSTAL" -> org.bukkit.entity.EntityType.ENDER_CRYSTAL;
case "ENDER_CRYSTAL" -> throw new IllegalArgumentException("Invalid entity identifier " + id); // make sure this issue can't happen the other way around. case "ENDER_CRYSTAL" -> throw new IllegalArgumentException(
"Invalid entity identifier " + id); // make sure this issue can't happen the other way around.
default -> org.bukkit.entity.EntityType.valueOf(entityID); default -> org.bukkit.entity.EntityType.valueOf(entityID);
}); });
} }

View File

@ -52,7 +52,7 @@ public class BukkitProtoWorld implements ProtoWorld {
BlockData bukkitData = BukkitAdapter.adapt(data); BlockData bukkitData = BukkitAdapter.adapt(data);
delegate.setBlockData(x, y, z, bukkitData); delegate.setBlockData(x, y, z, bukkitData);
if(physics) { if(physics) {
if (BukkitUtils.isLiquid(bukkitData)) { if(BukkitUtils.isLiquid(bukkitData)) {
delegate.scheduleFluidUpdate(x, y, z); delegate.scheduleFluidUpdate(x, y, z);
} else { } else {
delegate.scheduleBlockUpdate(x, y, z); delegate.scheduleBlockUpdate(x, y, z);

View File

@ -117,7 +117,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider(); BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) { if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), biomeProvider, compatibilityOptions); beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
} }
return c; return c;
}); });

View File

@ -30,6 +30,7 @@ public class Reflection {
void setFrozen(MappedRegistry<?> instance, boolean frozen); void setFrozen(MappedRegistry<?> instance, boolean frozen);
} }
@Proxies(StructureManager.class) @Proxies(StructureManager.class)
public interface StructureManagerProxy { public interface StructureManagerProxy {
@FieldGetter("level") @FieldGetter("level")

View File

@ -95,7 +95,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider(); BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) { if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), biomeProvider, compatibilityOptions); beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
} }
return c; return c;
}); });

View File

@ -36,12 +36,14 @@ public class Reflection {
void setFrozen(MappedRegistry<?> instance, boolean frozen); void setFrozen(MappedRegistry<?> instance, boolean frozen);
} }
@Proxies(StructureManager.class) @Proxies(StructureManager.class)
public interface StructureManagerProxy { public interface StructureManagerProxy {
@FieldGetter("level") @FieldGetter("level")
LevelAccessor getLevel(StructureManager instance); LevelAccessor getLevel(StructureManager instance);
} }
@Proxies(Holder.Reference.class) @Proxies(Holder.Reference.class)
public interface ReferenceProxy { public interface ReferenceProxy {
@MethodName("bindValue") @MethodName("bindValue")

View File

@ -13,6 +13,7 @@ import java.util.Optional;
import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
public class NMSBiomeInjector { public class NMSBiomeInjector {
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) { public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {

View File

@ -24,6 +24,7 @@ public class NMSBiomeProvider extends BiomeSource {
this.delegate = delegate; this.delegate = delegate;
this.seed = seed; this.seed = seed;
} }
@Override @Override
protected Stream<Holder<Biome>> collectPossibleBiomes() { protected Stream<Holder<Biome>> collectPossibleBiomes() {
return delegate.stream() return delegate.stream()

View File

@ -96,7 +96,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider(); BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) { if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), biomeProvider, compatibilityOptions); beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
} }
return c; return c;
}); });

View File

@ -36,12 +36,14 @@ public class Reflection {
void setFrozen(MappedRegistry<?> instance, boolean frozen); void setFrozen(MappedRegistry<?> instance, boolean frozen);
} }
@Proxies(StructureManager.class) @Proxies(StructureManager.class)
public interface StructureManagerProxy { public interface StructureManagerProxy {
@FieldGetter("level") @FieldGetter("level")
LevelAccessor getLevel(StructureManager instance); LevelAccessor getLevel(StructureManager instance);
} }
@Proxies(Holder.Reference.class) @Proxies(Holder.Reference.class)
public interface ReferenceProxy { public interface ReferenceProxy {
@MethodName("bindValue") @MethodName("bindValue")

View File

@ -13,6 +13,7 @@ import java.util.Optional;
import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
public class NMSBiomeInjector { public class NMSBiomeInjector {
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) { public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {

View File

@ -24,6 +24,7 @@ public class NMSBiomeProvider extends BiomeSource {
this.delegate = delegate; this.delegate = delegate;
this.seed = seed; this.seed = seed;
} }
@Override @Override
protected Stream<Holder<Biome>> collectPossibleBiomes() { protected Stream<Holder<Biome>> collectPossibleBiomes() {
return delegate.stream() return delegate.stream()

View File

@ -96,7 +96,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider(); BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) { if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), biomeProvider, compatibilityOptions); beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
} }
return c; return c;
}); });

View File

@ -36,12 +36,14 @@ public class Reflection {
void setFrozen(MappedRegistry<?> instance, boolean frozen); void setFrozen(MappedRegistry<?> instance, boolean frozen);
} }
@Proxies(StructureManager.class) @Proxies(StructureManager.class)
public interface StructureManagerProxy { public interface StructureManagerProxy {
@FieldGetter("level") @FieldGetter("level")
LevelAccessor getLevel(StructureManager instance); LevelAccessor getLevel(StructureManager instance);
} }
@Proxies(Holder.Reference.class) @Proxies(Holder.Reference.class)
public interface ReferenceProxy { public interface ReferenceProxy {
@MethodName("bindValue") @MethodName("bindValue")

View File

@ -24,6 +24,7 @@ public class NMSBiomeProvider extends BiomeSource {
this.delegate = delegate; this.delegate = delegate;
this.seed = seed; this.seed = seed;
} }
@Override @Override
protected Stream<Holder<Biome>> collectPossibleBiomes() { protected Stream<Holder<Biome>> collectPossibleBiomes() {
return delegate.stream() return delegate.stream()

View File

@ -96,7 +96,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider(); BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) { if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), biomeProvider, compatibilityOptions); beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
} }
return c; return c;
}); });

View File

@ -36,12 +36,14 @@ public class Reflection {
void setFrozen(MappedRegistry<?> instance, boolean frozen); void setFrozen(MappedRegistry<?> instance, boolean frozen);
} }
@Proxies(StructureManager.class) @Proxies(StructureManager.class)
public interface StructureManagerProxy { public interface StructureManagerProxy {
@FieldGetter("level") @FieldGetter("level")
LevelAccessor getLevel(StructureManager instance); LevelAccessor getLevel(StructureManager instance);
} }
@Proxies(Holder.Reference.class) @Proxies(Holder.Reference.class)
public interface ReferenceProxy { public interface ReferenceProxy {
@MethodName("bindValue") @MethodName("bindValue")

View File

@ -26,7 +26,8 @@ public class NoiseConfigMixin {
@Inject(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/registry/RegistryEntryLookup;J)V", @Inject(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/registry/RegistryEntryLookup;J)V",
at = @At("TAIL")) at = @At("TAIL"))
private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup<NoiseParameters> noiseParametersLookup, long seed, private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup<NoiseParameters> noiseParametersLookup,
long seed,
CallbackInfo ci) { CallbackInfo ci) {
SeedHack.register(multiNoiseSampler, seed); SeedHack.register(multiNoiseSampler, seed);
} }

View File

@ -61,7 +61,8 @@ public final class BiomeUtil {
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome, net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome,
ForgeRegistries.BIOMES.getDelegateOrThrow(vanilla.getKey().orElseThrow()) ForgeRegistries.BIOMES.getDelegateOrThrow(
vanilla.getKey().orElseThrow())
.value(), .value(),
vanillaBiomeProperties); vanillaBiomeProperties);
@ -82,7 +83,8 @@ public final class BiomeUtil {
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(), Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
villagerMap.getOrDefault(vanilla.getKey().orElseThrow(), VillagerType.PLAINS))); villagerMap.getOrDefault(vanilla.getKey().orElseThrow(), VillagerType.PLAINS)));
MinecraftUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getKey().orElseThrow().getValue(), i -> new ArrayList<>()).add(identifier); MinecraftUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getKey().orElseThrow().getValue(), i -> new ArrayList<>()).add(
identifier);
} }
} }
} }

View File

@ -1,6 +1,6 @@
val platformOverrides = mapOf( val platformOverrides = mapOf(
"fabric" to "remapJar" "fabric" to "remapJar"
) )
dependencies { dependencies {
api(project(":common:implementation:base")) api(project(":common:implementation:base"))

View File

@ -110,8 +110,11 @@ public abstract class ModPlatform extends AbstractPlatform {
protected abstract BaseAddon getPlatformAddon(); protected abstract BaseAddon getPlatformAddon();
public abstract Registry<DimensionType> dimensionTypeRegistry(); public abstract Registry<DimensionType> dimensionTypeRegistry();
public abstract Registry<Biome> biomeRegistry(); public abstract Registry<Biome> biomeRegistry();
public abstract Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry(); public abstract Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry();
public abstract Registry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterListRegistry(); public abstract Registry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterListRegistry();
@Override @Override

View File

@ -26,7 +26,9 @@ public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeParticle
} }
try { try {
return new BiomeParticleConfig(ParticleEffectArgumentType.readParameters(new StringReader(particle), Registries.PARTICLE_TYPE.getReadOnlyWrapper()), probability); return new BiomeParticleConfig(
ParticleEffectArgumentType.readParameters(new StringReader(particle), Registries.PARTICLE_TYPE.getReadOnlyWrapper()),
probability);
} catch(CommandSyntaxException e) { } catch(CommandSyntaxException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -129,7 +129,8 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
private void beard(StructureAccessor structureAccessor, Chunk chunk, WorldProperties world, BiomeProvider biomeProvider, private void beard(StructureAccessor structureAccessor, Chunk chunk, WorldProperties world, BiomeProvider biomeProvider,
PreLoadCompatibilityOptions compatibilityOptions) { PreLoadCompatibilityOptions compatibilityOptions) {
StructureWeightSampler structureWeightSampler = StructureWeightSampler.createStructureWeightSampler(structureAccessor, chunk.getPos()); StructureWeightSampler structureWeightSampler = StructureWeightSampler.createStructureWeightSampler(structureAccessor,
chunk.getPos());
double threshold = compatibilityOptions.getBeardThreshold(); double threshold = compatibilityOptions.getBeardThreshold();
double airThreshold = compatibilityOptions.getAirThreshold(); double airThreshold = compatibilityOptions.getAirThreshold();
int xi = chunk.getPos().x << 4; int xi = chunk.getPos().x << 4;

View File

@ -36,7 +36,8 @@ public class MinecraftWorldHandle implements WorldHandle {
@Override @Override
public @NotNull BlockState createBlockState(@NotNull String data) { public @NotNull BlockState createBlockState(@NotNull String data) {
try { try {
net.minecraft.block.BlockState state = BlockArgumentParser.block(Registries.BLOCK.getReadOnlyWrapper(), data, true).blockState(); net.minecraft.block.BlockState state = BlockArgumentParser.block(Registries.BLOCK.getReadOnlyWrapper(), data, true)
.blockState();
if(state == null) throw new IllegalArgumentException("Invalid data: " + data); if(state == null) throw new IllegalArgumentException("Invalid data: " + data);
return (BlockState) state; return (BlockState) state;
} catch(CommandSyntaxException e) { } catch(CommandSyntaxException e) {

View File

@ -55,9 +55,9 @@ public abstract class WorldChunkMixin {
public void terra$setBlock(int x, int y, int z, BlockState data, boolean physics) { public void terra$setBlock(int x, int y, int z, BlockState data, boolean physics) {
BlockPos blockPos = new BlockPos(x, y, z); BlockPos blockPos = new BlockPos(x, y, z);
setBlockState(blockPos, (net.minecraft.block.BlockState) data, false); setBlockState(blockPos, (net.minecraft.block.BlockState) data, false);
if (physics) { if(physics) {
net.minecraft.block.BlockState state = ((net.minecraft.block.BlockState) data); net.minecraft.block.BlockState state = ((net.minecraft.block.BlockState) data);
if (state.isLiquid()) { if(state.isLiquid()) {
world.getFluidTickScheduler().scheduleTick(OrderedTick.create(state.getFluidState().getFluid(), blockPos)); world.getFluidTickScheduler().scheduleTick(OrderedTick.create(state.getFluidState().getFluid(), blockPos));
} else { } else {
world.getBlockTickScheduler().scheduleTick(OrderedTick.create(state.getBlock(), blockPos)); world.getBlockTickScheduler().scheduleTick(OrderedTick.create(state.getBlock(), blockPos));

View File

@ -158,7 +158,8 @@ public final class MinecraftUtil {
builder.temperature(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperature(), vanilla.getTemperature())); builder.temperature(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperature(), vanilla.getTemperature()));
builder.downfall(Objects.requireNonNullElse(vanillaBiomeProperties.getDownfall(), ((BiomeAccessor) ((Object) vanilla)).getWeather().downfall())); builder.downfall(Objects.requireNonNullElse(vanillaBiomeProperties.getDownfall(),
((BiomeAccessor) ((Object) vanilla)).getWeather().downfall()));
builder.temperatureModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperatureModifier(), builder.temperatureModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperatureModifier(),
((BiomeAccessor) ((Object) vanilla)).getWeather().temperatureModifier())); ((BiomeAccessor) ((Object) vanilla)).getWeather().temperatureModifier()));

View File

@ -51,27 +51,35 @@ public class PresetUtil {
PRESETS.add(generatorID); PRESETS.add(generatorID);
RegistryEntry<DimensionType> registryEntry = dimensionTypeRegistry.getEntry(DimensionTypes.THE_NETHER).orElseThrow(); RegistryEntry<DimensionType> registryEntry = dimensionTypeRegistry.getEntry(DimensionTypes.THE_NETHER).orElseThrow();
RegistryEntry.Reference<MultiNoiseBiomeSourceParameterList> reference = multiNoiseBiomeSourceParameterLists.getEntry(MultiNoiseBiomeSourceParameterLists.NETHER).orElseThrow(); RegistryEntry.Reference<MultiNoiseBiomeSourceParameterList> reference = multiNoiseBiomeSourceParameterLists.getEntry(
RegistryEntry<ChunkGeneratorSettings> registryEntry2 = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.NETHER).orElseThrow(); MultiNoiseBiomeSourceParameterLists.NETHER).orElseThrow();
RegistryEntry<ChunkGeneratorSettings> registryEntry2 = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.NETHER)
.orElseThrow();
RegistryEntry<DimensionType> registryEntry3 = dimensionTypeRegistry.getEntry(DimensionTypes.THE_END).orElseThrow(); RegistryEntry<DimensionType> registryEntry3 = dimensionTypeRegistry.getEntry(DimensionTypes.THE_END).orElseThrow();
RegistryEntry<ChunkGeneratorSettings> registryEntry4 = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.END).orElseThrow(); RegistryEntry<ChunkGeneratorSettings> registryEntry4 = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.END)
.orElseThrow();
TerraBiomeSource biomeSource = new TerraBiomeSource(pack); TerraBiomeSource biomeSource = new TerraBiomeSource(pack);
ChunkGenerator generator = new MinecraftChunkGeneratorWrapper(biomeSource, pack, overworld); ChunkGenerator generator = new MinecraftChunkGeneratorWrapper(biomeSource, pack, overworld);
DimensionOptions dimensionOptions = new DimensionOptions(overworldDimensionType, generator); DimensionOptions dimensionOptions = new DimensionOptions(overworldDimensionType, generator);
DimensionOptions netherDimensionOptions = new DimensionOptions(registryEntry, new NoiseChunkGenerator(MultiNoiseBiomeSource.create(reference), registryEntry2)); DimensionOptions netherDimensionOptions = new DimensionOptions(registryEntry,
DimensionOptions endDimensionOptions = new DimensionOptions(registryEntry3, new NoiseChunkGenerator(TheEndBiomeSource.createVanilla(platform.biomeRegistry().getReadOnlyWrapper()), registryEntry4)); new NoiseChunkGenerator(MultiNoiseBiomeSource.create(reference),
registryEntry2));
DimensionOptions endDimensionOptions = new DimensionOptions(registryEntry3, new NoiseChunkGenerator(
TheEndBiomeSource.createVanilla(platform.biomeRegistry().getReadOnlyWrapper()), registryEntry4));
WorldPreset preset = createPreset(dimensionOptions, netherDimensionOptions, endDimensionOptions); WorldPreset preset = createPreset(dimensionOptions, netherDimensionOptions, endDimensionOptions);
LOGGER.info("Created world type \"{}\"", generatorID); LOGGER.info("Created world type \"{}\"", generatorID);
return Pair.of(generatorID, preset); return Pair.of(generatorID, preset);
} }
private static WorldPreset createPreset(DimensionOptions dimensionOptions, DimensionOptions netherDimensionOptions, DimensionOptions endDimensionOptions) { private static WorldPreset createPreset(DimensionOptions dimensionOptions, DimensionOptions netherDimensionOptions,
DimensionOptions endDimensionOptions) {
return new WorldPreset( return new WorldPreset(
Map.of(DimensionOptions.OVERWORLD, dimensionOptions, DimensionOptions.NETHER, netherDimensionOptions, DimensionOptions.END, endDimensionOptions) Map.of(DimensionOptions.OVERWORLD, dimensionOptions, DimensionOptions.NETHER, netherDimensionOptions, DimensionOptions.END,
endDimensionOptions)
); );
} }

View File

@ -30,18 +30,27 @@ import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
public abstract class LifecyclePlatform extends ModPlatform { public abstract class LifecyclePlatform extends ModPlatform {
private static final Logger LOGGER = LoggerFactory.getLogger(LifecyclePlatform.class); private static final Logger LOGGER = LoggerFactory.getLogger(LifecyclePlatform.class);
private static MinecraftServer server;
private static final AtomicReference<Registry<Biome>> BIOMES = new AtomicReference<>(); private static final AtomicReference<Registry<Biome>> BIOMES = new AtomicReference<>();
private static final AtomicReference<Registry<DimensionType>> DIMENSIONS = new AtomicReference<>(); private static final AtomicReference<Registry<DimensionType>> DIMENSIONS = new AtomicReference<>();
private static final AtomicReference<Registry<ChunkGeneratorSettings>> SETTINGS = new AtomicReference<>(); private static final AtomicReference<Registry<ChunkGeneratorSettings>> SETTINGS = new AtomicReference<>();
private static final AtomicReference<Registry<MultiNoiseBiomeSourceParameterList>> NOISE = new AtomicReference<>(); private static final AtomicReference<Registry<MultiNoiseBiomeSourceParameterList>> NOISE = new AtomicReference<>();
private static MinecraftServer server;
public LifecyclePlatform() { public LifecyclePlatform() {
CommonPlatform.initialize(this); CommonPlatform.initialize(this);
load(); load();
} }
public static void setRegistries(Registry<Biome> biomeRegistry,
Registry<DimensionType> dimensionTypeRegistry,
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry,
Registry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterListRegistry) {
BIOMES.set(biomeRegistry);
DIMENSIONS.set(dimensionTypeRegistry);
SETTINGS.set(chunkGeneratorSettingsRegistry);
NOISE.set(multiNoiseBiomeSourceParameterListRegistry);
}
@Override @Override
public MinecraftServer getServer() { public MinecraftServer getServer() {
return server; return server;
@ -76,16 +85,6 @@ public abstract class LifecyclePlatform extends ModPlatform {
return succeed; return succeed;
} }
public static void setRegistries(Registry<Biome> biomeRegistry,
Registry<DimensionType> dimensionTypeRegistry,
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry,
Registry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterListRegistry) {
BIOMES.set(biomeRegistry);
DIMENSIONS.set(dimensionTypeRegistry);
SETTINGS.set(chunkGeneratorSettingsRegistry);
NOISE.set(multiNoiseBiomeSourceParameterListRegistry);
}
@Override @Override
protected Iterable<BaseAddon> platformAddon() { protected Iterable<BaseAddon> platformAddon() {
List<BaseAddon> addons = new ArrayList<>(); List<BaseAddon> addons = new ArrayList<>();

View File

@ -26,7 +26,8 @@ public class NoiseConfigMixin {
@Inject(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/registry/RegistryEntryLookup;J)V", @Inject(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/registry/RegistryEntryLookup;J)V",
at = @At("TAIL")) at = @At("TAIL"))
private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup<DoublePerlinNoiseSampler.NoiseParameters> noiseParametersLookup, long seed, private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings,
RegistryEntryLookup<DoublePerlinNoiseSampler.NoiseParameters> noiseParametersLookup, long seed,
CallbackInfo ci) { CallbackInfo ci) {
SeedHack.register(multiNoiseSampler, seed); SeedHack.register(multiNoiseSampler, seed);
} }

View File

@ -52,7 +52,8 @@ public class RegistryLoaderMixin {
MutableRegistry<WorldPreset> worldPresets = extractRegistry(instance, RegistryKeys.WORLD_PRESET).orElseThrow(); MutableRegistry<WorldPreset> worldPresets = extractRegistry(instance, RegistryKeys.WORLD_PRESET).orElseThrow();
MutableRegistry<ChunkGeneratorSettings> chunkGeneratorSettings = extractRegistry(instance, MutableRegistry<ChunkGeneratorSettings> chunkGeneratorSettings = extractRegistry(instance,
RegistryKeys.CHUNK_GENERATOR_SETTINGS).orElseThrow(); RegistryKeys.CHUNK_GENERATOR_SETTINGS).orElseThrow();
MutableRegistry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterLists = extractRegistry(instance, RegistryKeys.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST).orElseThrow(); MutableRegistry<MultiNoiseBiomeSourceParameterList> multiNoiseBiomeSourceParameterLists = extractRegistry(instance,
RegistryKeys.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST).orElseThrow();
LifecyclePlatform.setRegistries(biomes, dimensionTypes, chunkGeneratorSettings, multiNoiseBiomeSourceParameterLists); LifecyclePlatform.setRegistries(biomes, dimensionTypes, chunkGeneratorSettings, multiNoiseBiomeSourceParameterLists);
LifecycleUtil.initialize(biomes, worldPresets); LifecycleUtil.initialize(biomes, worldPresets);

View File

@ -19,6 +19,7 @@ public final class LifecycleUtil {
public static void initialize(MutableRegistry<Biome> biomeMutableRegistry, MutableRegistry<WorldPreset> worldPresetMutableRegistry) { public static void initialize(MutableRegistry<Biome> biomeMutableRegistry, MutableRegistry<WorldPreset> worldPresetMutableRegistry) {
CommonPlatform.get().getEventManager().callEvent(new PlatformInitializationEvent()); CommonPlatform.get().getEventManager().callEvent(new PlatformInitializationEvent());
BiomeUtil.registerBiomes(biomeMutableRegistry); BiomeUtil.registerBiomes(biomeMutableRegistry);
CommonPlatform.get().registerWorldTypes((id, preset) -> Registry.register(worldPresetMutableRegistry, RegistryKey.of(RegistryKeys.WORLD_PRESET, id), preset)); CommonPlatform.get().registerWorldTypes(
(id, preset) -> Registry.register(worldPresetMutableRegistry, RegistryKey.of(RegistryKeys.WORLD_PRESET, id), preset));
} }
} }

View File

@ -32,7 +32,10 @@ public class QuiltPlatform extends LifecyclePlatform {
@Override @Override
protected Collection<BaseAddon> getPlatformMods() { protected Collection<BaseAddon> getPlatformMods() {
return QuiltLoader.getAllMods().stream().flatMap(mod -> parseModData(mod.metadata().id(), mod.metadata().version().raw(), "quilt")).collect( return QuiltLoader.getAllMods()
.stream()
.flatMap(mod -> parseModData(mod.metadata().id(), mod.metadata().version().raw(), "quilt"))
.collect(
Collectors.toList()); Collectors.toList());
} }