mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-03 00:15:35 +00:00
Reformat code
This commit is contained in:
parent
d696e4fd24
commit
81a96d6b76
2
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
2
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
@ -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) -->
|
||||||
|
@ -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")
|
||||||
|
@ -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()
|
||||||
|
@ -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"
|
||||||
|
@ -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();
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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() {
|
||||||
|
@ -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() {
|
||||||
|
@ -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;
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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<>();
|
||||||
|
|
||||||
|
@ -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() :
|
||||||
|
@ -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");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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());
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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()));
|
||||||
|
@ -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,
|
||||||
|
@ -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))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -4,5 +4,4 @@ dependencies {
|
|||||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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())));
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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); }
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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) {
|
||||||
|
@ -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")
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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<>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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")
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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")
|
||||||
|
@ -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) {
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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")
|
||||||
|
@ -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) {
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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")
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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")
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"))
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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));
|
||||||
|
@ -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()));
|
||||||
|
@ -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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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<>();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user