mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-04 00:45:57 +00:00
Merge branch 'ver/6.3.0' into dev/img-lib
fogor import
This commit is contained in:
commit
e6c51bcfd0
@ -1,8 +1,8 @@
|
|||||||
preRelease(true)
|
preRelease(true)
|
||||||
|
|
||||||
versionProjects(":common:api", version("6.2.1"))
|
versionProjects(":common:api", version("6.3.0"))
|
||||||
versionProjects(":common:implementation", version("6.2.1"))
|
versionProjects(":common:implementation", version("6.3.0"))
|
||||||
versionProjects(":platforms", version("6.2.1"))
|
versionProjects(":platforms", version("6.3.0"))
|
||||||
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
@ -4,7 +4,7 @@ object Versions {
|
|||||||
const val paralithic = "0.7.0"
|
const val paralithic = "0.7.0"
|
||||||
const val strata = "1.1.1"
|
const val strata = "1.1.1"
|
||||||
|
|
||||||
const val cloud = "1.7.0"
|
const val cloud = "1.8.0"
|
||||||
|
|
||||||
const val slf4j = "1.7.36"
|
const val slf4j = "1.7.36"
|
||||||
const val log4j_slf4j_impl = "2.14.1"
|
const val log4j_slf4j_impl = "2.14.1"
|
||||||
@ -19,19 +19,19 @@ object Versions {
|
|||||||
|
|
||||||
object Fabric {
|
object Fabric {
|
||||||
const val fabricLoader = "0.14.8"
|
const val fabricLoader = "0.14.8"
|
||||||
const val fabricAPI = "0.57.0+1.19"
|
const val fabricAPI = "0.69.1+1.19.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Quilt {
|
object Quilt {
|
||||||
const val quiltLoader = "0.17.0"
|
const val quiltLoader = "0.17.8"
|
||||||
const val fabricApi = "2.0.0-beta.4+0.57.0-1.19"
|
const val fabricApi = "5.0.0-alpha.5+0.68.1-1.19.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Mod {
|
object Mod {
|
||||||
const val mixin = "0.11.2+mixin.0.8.5"
|
const val mixin = "0.11.2+mixin.0.8.5"
|
||||||
|
|
||||||
const val minecraft = "1.19"
|
const val minecraft = "1.19.3"
|
||||||
const val yarn = "$minecraft+build.1"
|
const val yarn = "$minecraft+build.3"
|
||||||
const val fabricLoader = "0.14.2"
|
const val fabricLoader = "0.14.2"
|
||||||
|
|
||||||
const val architecuryLoom = "0.12.0.290"
|
const val architecuryLoom = "0.12.0.290"
|
||||||
@ -43,16 +43,16 @@ object Versions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object Forge {
|
object Forge {
|
||||||
const val forge = "${Mod.minecraft}-41.0.63"
|
const val forge = "${Mod.minecraft}-44.0.18"
|
||||||
const val burningwave = "12.53.0"
|
const val burningwave = "12.53.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Bukkit {
|
object Bukkit {
|
||||||
const val paper = "1.18.2-R0.1-SNAPSHOT"
|
const val paper = "1.18.2-R0.1-SNAPSHOT"
|
||||||
const val paperLib = "1.0.5"
|
const val paperLib = "1.0.5"
|
||||||
const val minecraft = "1.19.2"
|
const val minecraft = "1.19.3"
|
||||||
const val reflectionRemapper = "0.1.0-SNAPSHOT"
|
const val reflectionRemapper = "0.1.0-SNAPSHOT"
|
||||||
const val paperDevBundle = "1.19.2-R0.1-SNAPSHOT"
|
const val paperDevBundle = "1.19.3-R0.1-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Sponge {
|
object Sponge {
|
||||||
|
@ -11,6 +11,7 @@ import net.jafama.FastMath;
|
|||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@ -97,6 +98,11 @@ public class PipelineBiomeProvider implements BiomeProvider {
|
|||||||
return biomes;
|
return biomes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||||
|
return Optional.of(getBiome(x, z, seed));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
|
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
|
||||||
return new BiomePipelineColumn(this, min, max, x, z, seed);
|
return new BiomePipelineColumn(this, min, max, x, z, seed);
|
||||||
|
@ -11,9 +11,10 @@ import com.dfsek.terra.addons.chunkgenerator.config.NoiseChunkGeneratorPackConfi
|
|||||||
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseConfigTemplate;
|
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseConfigTemplate;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomePaletteTemplate;
|
import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomePaletteTemplate;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.palette.PaletteInfo;
|
import com.dfsek.terra.addons.chunkgenerator.config.palette.slant.SlantLayerTemplate;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.palette.SlantLayer;
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D;
|
import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||||
import com.dfsek.terra.api.Platform;
|
import com.dfsek.terra.api.Platform;
|
||||||
import com.dfsek.terra.api.addon.BaseAddon;
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
@ -36,14 +37,19 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
PropertyKey<PaletteInfo> paletteInfoPropertyKey = Context.create(PaletteInfo.class);
|
PropertyKey<BiomePaletteInfo> paletteInfoPropertyKey = Context.create(BiomePaletteInfo.class);
|
||||||
PropertyKey<BiomeNoiseProperties> noisePropertiesPropertyKey = Context.create(BiomeNoiseProperties.class);
|
PropertyKey<BiomeNoiseProperties> noisePropertiesPropertyKey = Context.create(BiomeNoiseProperties.class);
|
||||||
platform.getEventManager()
|
platform.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(addon, ConfigPackPreLoadEvent.class)
|
.register(addon, ConfigPackPreLoadEvent.class)
|
||||||
.priority(1000)
|
.priority(1000)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
|
|
||||||
|
event.getPack().applyLoader(SlantHolder.CalculationMethod.class,
|
||||||
|
(type, o, loader, depthTracker) -> SlantHolder.CalculationMethod.valueOf((String) o));
|
||||||
|
|
||||||
NoiseChunkGeneratorPackConfigTemplate config = event.loadTemplate(new NoiseChunkGeneratorPackConfigTemplate());
|
NoiseChunkGeneratorPackConfigTemplate config = event.loadTemplate(new NoiseChunkGeneratorPackConfigTemplate());
|
||||||
|
event.getPack().getContext().put(config);
|
||||||
|
|
||||||
event.getPack()
|
event.getPack()
|
||||||
.getOrCreateRegistry(ChunkGeneratorProvider.class)
|
.getOrCreateRegistry(ChunkGeneratorProvider.class)
|
||||||
@ -53,7 +59,7 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
|
|||||||
config.getVerticalRes(), noisePropertiesPropertyKey,
|
config.getVerticalRes(), noisePropertiesPropertyKey,
|
||||||
paletteInfoPropertyKey));
|
paletteInfoPropertyKey));
|
||||||
event.getPack()
|
event.getPack()
|
||||||
.applyLoader(SlantLayer.class, SlantLayer::new);
|
.applyLoader(SlantHolder.Layer.class, SlantLayerTemplate::new);
|
||||||
})
|
})
|
||||||
.failThrough();
|
.failThrough();
|
||||||
|
|
||||||
@ -62,8 +68,10 @@ 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);
|
||||||
|
|
||||||
event.getLoadedObject(Biome.class).getContext().put(paletteInfoPropertyKey,
|
event.getLoadedObject(Biome.class).getContext().put(paletteInfoPropertyKey,
|
||||||
event.load(new BiomePaletteTemplate(platform)).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());
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,12 @@ import com.dfsek.tectonic.api.config.template.ConfigTemplate;
|
|||||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.properties.Properties;
|
||||||
|
|
||||||
|
|
||||||
public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate {
|
public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate, Properties {
|
||||||
@Value("blend.terrain.elevation")
|
@Value("blend.terrain.elevation")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int elevationBlend = 4;
|
private @Meta int elevationBlend = 4;
|
||||||
@ -20,6 +22,10 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate {
|
|||||||
@Default
|
@Default
|
||||||
private @Meta int verticalRes = 2;
|
private @Meta int verticalRes = 2;
|
||||||
|
|
||||||
|
@Value("slant.calculation-method")
|
||||||
|
@Default
|
||||||
|
private SlantHolder.@Meta CalculationMethod slantCalculationMethod = SlantHolder.CalculationMethod.Derivative;
|
||||||
|
|
||||||
public int getElevationBlend() {
|
public int getElevationBlend() {
|
||||||
return elevationBlend;
|
return elevationBlend;
|
||||||
}
|
}
|
||||||
@ -31,4 +37,8 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate {
|
|||||||
public int getVerticalRes() {
|
public int getVerticalRes() {
|
||||||
return verticalRes;
|
return verticalRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SlantHolder.CalculationMethod getSlantCalculationMethod() {
|
||||||
|
return slantCalculationMethod;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,25 +15,23 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolderBuilder;
|
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||||
import com.dfsek.terra.api.Platform;
|
import com.dfsek.terra.api.Platform;
|
||||||
import com.dfsek.terra.api.block.state.BlockState;
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class BiomePaletteTemplate implements ObjectTemplate<PaletteInfo> {
|
public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> {
|
||||||
private final Platform platform;
|
private final Platform platform;
|
||||||
|
|
||||||
@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<@Meta SlantLayer> slant = Collections.emptyList();
|
private @Meta List<SlantHolder.@Meta Layer> slantLayers = Collections.emptyList();
|
||||||
|
|
||||||
@Value("slant-depth")
|
@Value("slant-depth")
|
||||||
@Default
|
@Default
|
||||||
@ -63,27 +61,16 @@ public class BiomePaletteTemplate implements ObjectTemplate<PaletteInfo> {
|
|||||||
@Default
|
@Default
|
||||||
private @Meta boolean updatePalette = false;
|
private @Meta boolean updatePalette = false;
|
||||||
|
|
||||||
public BiomePaletteTemplate(Platform platform) { this.platform = platform; }
|
private final SlantHolder.CalculationMethod slantCalculationMethod;
|
||||||
|
|
||||||
|
public BiomePaletteTemplate(Platform platform, SlantHolder.CalculationMethod slantCalculationMethod) {
|
||||||
|
this.platform = platform;
|
||||||
|
this.slantCalculationMethod = slantCalculationMethod;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaletteInfo get() {
|
public BiomePaletteInfo get() {
|
||||||
PaletteHolderBuilder builder = new PaletteHolderBuilder();
|
return new BiomePaletteInfo(PaletteHolder.of(palettes), SlantHolder.of(slantLayers, slantDepth, slantCalculationMethod),
|
||||||
for(Map<Palette, Integer> layer : palettes) {
|
oceanPalette, seaLevel, updatePalette);
|
||||||
for(Entry<Palette, Integer> entry : layer.entrySet()) {
|
|
||||||
builder.add(entry.getValue(), entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeMap<Double, PaletteHolder> slantLayers = new TreeMap<>();
|
|
||||||
double minThreshold = Double.MAX_VALUE;
|
|
||||||
|
|
||||||
for(SlantLayer layer : slant) {
|
|
||||||
double threshold = layer.getThreshold();
|
|
||||||
if(threshold < minThreshold) minThreshold = threshold;
|
|
||||||
slantLayers.put(threshold, layer.getPalette());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PaletteInfo(builder.build(), SlantHolder.of(slantLayers, minThreshold), oceanPalette, seaLevel, slantDepth,
|
|
||||||
updatePalette);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020-2021 Polyhedral Development
|
|
||||||
*
|
|
||||||
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
|
||||||
* reference the LICENSE file in this module's root directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dfsek.terra.addons.chunkgenerator.config.palette;
|
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
|
||||||
import com.dfsek.terra.api.properties.Properties;
|
|
||||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
|
||||||
|
|
||||||
|
|
||||||
public record PaletteInfo(PaletteHolder paletteHolder,
|
|
||||||
SlantHolder slantHolder,
|
|
||||||
Palette ocean,
|
|
||||||
int seaLevel,
|
|
||||||
int maxSlantDepth,
|
|
||||||
boolean updatePaletteWhenCarving) implements Properties {
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package com.dfsek.terra.addons.chunkgenerator.config.palette;
|
|
||||||
|
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
|
||||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolderBuilder;
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
|
||||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
|
||||||
|
|
||||||
|
|
||||||
public class SlantLayer implements ObjectTemplate<SlantLayer> {
|
|
||||||
@Value("threshold")
|
|
||||||
private @Meta double threshold;
|
|
||||||
|
|
||||||
@Value("palette")
|
|
||||||
private @Meta List<@Meta Map<@Meta Palette, @Meta Integer>> palettes;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SlantLayer get() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getThreshold() {
|
|
||||||
return threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PaletteHolder getPalette() {
|
|
||||||
PaletteHolderBuilder builder = new PaletteHolderBuilder();
|
|
||||||
for(Map<Palette, Integer> layer : palettes) {
|
|
||||||
for(Entry<Palette, Integer> entry : layer.entrySet()) {
|
|
||||||
builder.add(entry.getValue(), entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.config.palette.slant;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||||
|
|
||||||
|
|
||||||
|
public class SlantLayerTemplate implements ObjectTemplate<SlantHolder.Layer> {
|
||||||
|
|
||||||
|
@Value("threshold")
|
||||||
|
private @Meta double threshold;
|
||||||
|
|
||||||
|
@Value("palette")
|
||||||
|
private @Meta List<@Meta Map<@Meta Palette, @Meta Integer>> palettes;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SlantHolder.Layer get() {
|
||||||
|
return new SlantHolder.Layer(PaletteHolder.of(palettes), threshold);
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ import net.jafama.FastMath;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.palette.PaletteInfo;
|
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.PaletteUtil;
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.PaletteUtil;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.LazilyEvaluatedInterpolator;
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.LazilyEvaluatedInterpolator;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||||
@ -40,13 +40,13 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
|||||||
private final int carverHorizontalResolution;
|
private final int carverHorizontalResolution;
|
||||||
private final int carverVerticalResolution;
|
private final int carverVerticalResolution;
|
||||||
|
|
||||||
private final PropertyKey<PaletteInfo> paletteInfoPropertyKey;
|
private final PropertyKey<BiomePaletteInfo> paletteInfoPropertyKey;
|
||||||
private final PropertyKey<BiomeNoiseProperties> noisePropertiesKey;
|
private final PropertyKey<BiomeNoiseProperties> noisePropertiesKey;
|
||||||
|
|
||||||
public NoiseChunkGenerator3D(ConfigPack pack, Platform platform, int elevationBlend, int carverHorizontalResolution,
|
public NoiseChunkGenerator3D(ConfigPack pack, Platform platform, int elevationBlend, int carverHorizontalResolution,
|
||||||
int carverVerticalResolution,
|
int carverVerticalResolution,
|
||||||
PropertyKey<BiomeNoiseProperties> noisePropertiesKey,
|
PropertyKey<BiomeNoiseProperties> noisePropertiesKey,
|
||||||
PropertyKey<PaletteInfo> paletteInfoPropertyKey) {
|
PropertyKey<BiomePaletteInfo> paletteInfoPropertyKey) {
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
this.air = platform.getWorldHandle().air();
|
this.air = platform.getWorldHandle().air();
|
||||||
this.carverHorizontalResolution = carverHorizontalResolution;
|
this.carverHorizontalResolution = carverHorizontalResolution;
|
||||||
@ -97,7 +97,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
|||||||
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
|
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
|
||||||
Biome biome = biomeColumn.get(y);
|
Biome biome = biomeColumn.get(y);
|
||||||
|
|
||||||
PaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey);
|
BiomePaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey);
|
||||||
|
|
||||||
int sea = paletteInfo.seaLevel();
|
int sea = paletteInfo.seaLevel();
|
||||||
Palette seaPalette = paletteInfo.ocean();
|
Palette seaPalette = paletteInfo.ocean();
|
||||||
@ -131,7 +131,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
|||||||
Biome biome = biomeProvider.getBiome(x, y, z, world.getSeed());
|
Biome biome = biomeProvider.getBiome(x, y, z, world.getSeed());
|
||||||
Sampler3D sampler = samplerCache.get(x, z, world, biomeProvider);
|
Sampler3D sampler = samplerCache.get(x, z, world, biomeProvider);
|
||||||
|
|
||||||
PaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey);
|
BiomePaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey);
|
||||||
|
|
||||||
int fdX = FastMath.floorMod(x, 16);
|
int fdX = FastMath.floorMod(x, 16);
|
||||||
int fdZ = FastMath.floorMod(z, 16);
|
int fdZ = FastMath.floorMod(z, 16);
|
||||||
|
@ -7,40 +7,23 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.chunkgenerator.generation.math;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.palette.PaletteInfo;
|
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||||
|
|
||||||
|
|
||||||
public final class PaletteUtil {
|
public final class PaletteUtil {
|
||||||
/**
|
|
||||||
* Derivative constant.
|
|
||||||
*/
|
|
||||||
private static final double DERIVATIVE_DIST = 0.55;
|
|
||||||
|
|
||||||
public static Palette getPalette(int x, int y, int z, Sampler3D sampler, PaletteInfo paletteInfo, int depth) {
|
public static Palette getPalette(int x, int y, int z, Sampler3D sampler, BiomePaletteInfo paletteInfo, int depth) {
|
||||||
SlantHolder slant = paletteInfo.slantHolder();
|
SlantHolder slantHolder = paletteInfo.slantHolder();
|
||||||
if(!slant.isEmpty() && depth <= paletteInfo.maxSlantDepth()) {
|
if(slantHolder.isAboveDepth(depth)) {
|
||||||
double slope = derivative(sampler, x, y, z);
|
double slant = slantHolder.calculateSlant(sampler, x, y, z);
|
||||||
if(slope > slant.getMinSlope()) {
|
if(slantHolder.isInSlantThreshold(slant)) {
|
||||||
return slant.getPalette(slope).getPalette(y);
|
return slantHolder.getPalette(slant).getPalette(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return paletteInfo.paletteHolder().getPalette(y);
|
return paletteInfo.paletteHolder().getPalette(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double derivative(Sampler3D sampler, double x, double y, double z) {
|
|
||||||
double baseSample = sampler.sample(x, y, z);
|
|
||||||
|
|
||||||
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
|
||||||
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
|
||||||
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
|
|
||||||
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - 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;
|
|
||||||
|
|
||||||
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||||
|
import com.dfsek.terra.api.properties.Properties;
|
||||||
|
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||||
|
|
||||||
|
|
||||||
|
public record BiomePaletteInfo(PaletteHolder paletteHolder,
|
||||||
|
SlantHolder slantHolder,
|
||||||
|
Palette ocean,
|
||||||
|
int seaLevel,
|
||||||
|
boolean updatePaletteWhenCarving) implements Properties {
|
||||||
|
}
|
@ -7,6 +7,13 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.chunkgenerator.palette;
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||||
|
|
||||||
|
|
||||||
@ -27,4 +34,43 @@ public class PaletteHolder {
|
|||||||
: palettes[palettes.length - 1]
|
: palettes[palettes.length - 1]
|
||||||
: palettes[0];
|
: palettes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PaletteHolder of(List<Map<Palette, Integer>> palettes) {
|
||||||
|
PaletteHolderBuilder builder = new PaletteHolderBuilder();
|
||||||
|
for(Map<Palette, Integer> layer : palettes) {
|
||||||
|
for(Entry<Palette, Integer> entry : layer.entrySet()) {
|
||||||
|
builder.add(entry.getValue(), entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PaletteHolderBuilder {
|
||||||
|
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
||||||
|
|
||||||
|
public PaletteHolderBuilder add(int y, Palette palette) {
|
||||||
|
paletteMap.put(y, palette);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaletteHolder build() {
|
||||||
|
|
||||||
|
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
||||||
|
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
||||||
|
|
||||||
|
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
|
||||||
|
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
|
||||||
|
Palette d = null;
|
||||||
|
for(Entry<Integer, Palette> e : paletteMap.entrySet()) {
|
||||||
|
if(e.getKey() >= y) {
|
||||||
|
d = e.getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(d == null) throw new IllegalArgumentException("No palette for Y=" + y);
|
||||||
|
palettes[y - min] = d;
|
||||||
|
}
|
||||||
|
return new PaletteHolder(palettes, -min);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020-2021 Polyhedral Development
|
|
||||||
*
|
|
||||||
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
|
||||||
* reference the LICENSE file in this module's root directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dfsek.terra.addons.chunkgenerator.palette;
|
|
||||||
|
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
|
||||||
|
|
||||||
|
|
||||||
public class PaletteHolderBuilder {
|
|
||||||
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
|
||||||
|
|
||||||
public PaletteHolderBuilder add(int y, Palette palette) {
|
|
||||||
paletteMap.put(y, palette);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PaletteHolder build() {
|
|
||||||
|
|
||||||
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
|
||||||
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
|
||||||
|
|
||||||
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
|
|
||||||
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
|
|
||||||
Palette d = null;
|
|
||||||
for(Map.Entry<Integer, Palette> e : paletteMap.entrySet()) {
|
|
||||||
if(e.getKey() >= y) {
|
|
||||||
d = e.getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(d == null) throw new IllegalArgumentException("No palette for Y=" + y);
|
|
||||||
palettes[y - min] = d;
|
|
||||||
}
|
|
||||||
return new PaletteHolder(palettes, -min);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020-2021 Polyhedral Development
|
|
||||||
*
|
|
||||||
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
|
||||||
* reference the LICENSE file in this module's root directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dfsek.terra.addons.chunkgenerator.palette;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
|
|
||||||
public class SlantHolder {
|
|
||||||
private final TreeMap<Double, PaletteHolder> layers;
|
|
||||||
private final double minSlope;
|
|
||||||
|
|
||||||
private SlantHolder(TreeMap<Double, PaletteHolder> layers, double minSlope) {
|
|
||||||
this.layers = layers;
|
|
||||||
this.minSlope = minSlope;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SlantHolder of(TreeMap<Double, PaletteHolder> layers, double minSlope) {
|
|
||||||
if(layers.size() == 1) {
|
|
||||||
Entry<Double, PaletteHolder> firstEntry = layers.firstEntry();
|
|
||||||
return new Single(firstEntry.getValue(), minSlope);
|
|
||||||
}
|
|
||||||
return new SlantHolder(layers, minSlope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return layers.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PaletteHolder getPalette(double slope) {
|
|
||||||
return layers.floorEntry(slope).getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getMinSlope() {
|
|
||||||
return minSlope;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class Single extends SlantHolder {
|
|
||||||
|
|
||||||
private final PaletteHolder layers;
|
|
||||||
|
|
||||||
public Single(PaletteHolder layers, double minSlope) {
|
|
||||||
super(of(minSlope, layers), minSlope);
|
|
||||||
this.layers = layers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TreeMap<Double, PaletteHolder> of(double v, PaletteHolder layer) {
|
|
||||||
TreeMap<Double, PaletteHolder> map = new TreeMap<>();
|
|
||||||
map.put(v, layer);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PaletteHolder getPalette(double slope) {
|
|
||||||
return layers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette.slant;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
|
|
||||||
|
|
||||||
|
public class MultipleSlantHolder extends SlantHolderImpl {
|
||||||
|
private final NavigableMap<Double, PaletteHolder> layers;
|
||||||
|
private final double slantThreshold;
|
||||||
|
|
||||||
|
MultipleSlantHolder(List<SlantHolder.Layer> slant, int slantDepth, CalculationMethod calculationMethod) {
|
||||||
|
super(slantDepth, calculationMethod);
|
||||||
|
NavigableMap<Double, PaletteHolder> layers = new TreeMap<>(slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette)));
|
||||||
|
Stream<Double> thresholds = layers.keySet().stream();
|
||||||
|
double slantThreshold = floorToThreshold ?
|
||||||
|
thresholds.min(Double::compare).orElseThrow() :
|
||||||
|
thresholds.max(Double::compare).orElseThrow();
|
||||||
|
this.layers = layers;
|
||||||
|
this.slantThreshold = slantThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double getSlantThreshold() {
|
||||||
|
return slantThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaletteHolder getPalette(double slant) {
|
||||||
|
return (floorToThreshold ?
|
||||||
|
layers.floorEntry(slant) :
|
||||||
|
layers.ceilingEntry(slant)
|
||||||
|
).getValue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette.slant;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
|
|
||||||
|
|
||||||
|
final class SingleSlantHolder extends SlantHolderImpl {
|
||||||
|
|
||||||
|
private final SlantHolder.Layer layer;
|
||||||
|
|
||||||
|
public SingleSlantHolder(SlantHolder.Layer layer, int slantDepth, CalculationMethod calculationMethod) {
|
||||||
|
super(slantDepth, calculationMethod);
|
||||||
|
this.layer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaletteHolder getPalette(double slant) {
|
||||||
|
return layer.palette();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double getSlantThreshold() {
|
||||||
|
return layer.threshold();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette.slant;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
|
import com.dfsek.terra.api.util.vector.Vector3;
|
||||||
|
|
||||||
|
|
||||||
|
public interface SlantHolder {
|
||||||
|
|
||||||
|
static SlantHolder of(List<SlantHolder.Layer> layers, int slantDepth, CalculationMethod calculationMethod) {
|
||||||
|
if(layers.isEmpty()) {
|
||||||
|
return EMPTY;
|
||||||
|
} else if(layers.size() == 1) {
|
||||||
|
return new SingleSlantHolder(layers.get(0), slantDepth, calculationMethod);
|
||||||
|
}
|
||||||
|
return new MultipleSlantHolder(layers, slantDepth, calculationMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
double calculateSlant(Sampler3D sampler, double x, double y, double z);
|
||||||
|
|
||||||
|
boolean isAboveDepth(int depth);
|
||||||
|
|
||||||
|
boolean isInSlantThreshold(double slant);
|
||||||
|
|
||||||
|
PaletteHolder getPalette(double slant);
|
||||||
|
|
||||||
|
record Layer(PaletteHolder palette, double threshold) {
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CalculationMethod {
|
||||||
|
DotProduct {
|
||||||
|
private static final Vector3 DOT_PRODUCT_DIRECTION = Vector3.of(0, 1, 0);
|
||||||
|
|
||||||
|
private static final Vector3[] DOT_PRODUCT_SAMPLE_POINTS = {
|
||||||
|
Vector3.of(0, 0, -DERIVATIVE_DIST),
|
||||||
|
Vector3.of(0, 0, DERIVATIVE_DIST),
|
||||||
|
Vector3.of(0, -DERIVATIVE_DIST, 0),
|
||||||
|
Vector3.of(0, DERIVATIVE_DIST, 0),
|
||||||
|
Vector3.of(-DERIVATIVE_DIST, 0, 0),
|
||||||
|
Vector3.of(DERIVATIVE_DIST, 0, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double slant(Sampler3D sampler, double x, double y, double z) {
|
||||||
|
Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0);
|
||||||
|
for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) {
|
||||||
|
var scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ());
|
||||||
|
normalApproximation.add(point.mutable().multiply(scalar));
|
||||||
|
}
|
||||||
|
return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean floorToThreshold() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Derivative {
|
||||||
|
@Override
|
||||||
|
public double slant(Sampler3D sampler, double x, double y, double z) {
|
||||||
|
double baseSample = sampler.sample(x, y, z);
|
||||||
|
|
||||||
|
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
||||||
|
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
||||||
|
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
|
||||||
|
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - 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;
|
||||||
|
|
||||||
|
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean floorToThreshold() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final double DERIVATIVE_DIST = 0.55;
|
||||||
|
|
||||||
|
public abstract double slant(Sampler3D sampler, double x, double y, double z);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Controls whether palettes should be applied before or after their respective thresholds.
|
||||||
|
*
|
||||||
|
* If true, slant values will map to the palette of the next floor threshold, otherwise they
|
||||||
|
* will map to the ceiling.
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.dfsek.terra.addons.chunkgenerator.palette.slant;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class SlantHolderImpl implements SlantHolder {
|
||||||
|
private final SlantHolder.CalculationMethod calculationMethod;
|
||||||
|
|
||||||
|
private final int slantDepth;
|
||||||
|
|
||||||
|
protected final boolean floorToThreshold;
|
||||||
|
|
||||||
|
protected SlantHolderImpl(int slantDepth, CalculationMethod calculationMethod) {
|
||||||
|
this.floorToThreshold = calculationMethod.floorToThreshold();
|
||||||
|
this.calculationMethod = calculationMethod;
|
||||||
|
this.slantDepth = slantDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract double getSlantThreshold();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final double calculateSlant(Sampler3D sampler, double x, double y, double z) {
|
||||||
|
return calculationMethod.slant(sampler, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isAboveDepth(int depth) {
|
||||||
|
return depth <= slantDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isInSlantThreshold(double slant) {
|
||||||
|
return (floorToThreshold ?
|
||||||
|
slant > getSlantThreshold() :
|
||||||
|
slant < getSlantThreshold()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Terra.
|
||||||
|
*
|
||||||
|
* Terra is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Terra is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Terra. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.config.loaders.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||||
|
import com.dfsek.tectonic.api.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.api.loader.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.config.Loader;
|
||||||
|
import com.dfsek.terra.api.properties.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
public class BufferedImageLoader implements TypeLoader<BufferedImage> {
|
||||||
|
private final Loader files;
|
||||||
|
|
||||||
|
private final ConfigPack pack;
|
||||||
|
|
||||||
|
public BufferedImageLoader(Loader files, ConfigPack pack) {
|
||||||
|
this.files = files;
|
||||||
|
this.pack = pack;
|
||||||
|
if (!pack.getContext().has(ImageCache.class))
|
||||||
|
pack.getContext().put(new ImageCache(new ConcurrentHashMap<>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
|
||||||
|
throws LoadException {
|
||||||
|
return pack.getContext().get(ImageCache.class).map.computeIfAbsent((String) c, s -> {
|
||||||
|
try {
|
||||||
|
return ImageIO.read(files.get(s));
|
||||||
|
} catch(IOException e) {
|
||||||
|
throw new LoadException("Unable to load image", e, depthTracker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache prevents configs from loading the same image multiple times into memory
|
||||||
|
*/
|
||||||
|
private record ImageCache(ConcurrentHashMap<String, BufferedImage> map) implements Properties {
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -81,6 +82,7 @@ import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorPr
|
|||||||
import com.dfsek.terra.config.fileloaders.FolderLoader;
|
import com.dfsek.terra.config.fileloaders.FolderLoader;
|
||||||
import com.dfsek.terra.config.fileloaders.ZIPLoader;
|
import com.dfsek.terra.config.fileloaders.ZIPLoader;
|
||||||
import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader;
|
import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader;
|
||||||
|
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
|
||||||
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
|
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
|
||||||
import com.dfsek.terra.config.preprocessor.MetaMapPreprocessor;
|
import com.dfsek.terra.config.preprocessor.MetaMapPreprocessor;
|
||||||
import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor;
|
import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor;
|
||||||
@ -280,7 +282,8 @@ public class ConfigPackImpl implements ConfigPack {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(TypeRegistry registry) {
|
public void register(TypeRegistry registry) {
|
||||||
registry.registerLoader(ConfigType.class, configTypeRegistry);
|
registry.registerLoader(ConfigType.class, configTypeRegistry)
|
||||||
|
.registerLoader(BufferedImage.class, new BufferedImageLoader(loader, this));
|
||||||
registryMap.forEach(registry::registerLoader);
|
registryMap.forEach(registry::registerLoader);
|
||||||
shortcuts.forEach(registry::registerLoader); // overwrite with delegated shortcuts if present
|
shortcuts.forEach(registry::registerLoader); // overwrite with delegated shortcuts if present
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ dependencies {
|
|||||||
shaded(project(":platforms:bukkit:common"))
|
shaded(project(":platforms:bukkit:common"))
|
||||||
shaded(project(":platforms:bukkit:nms:v1_18_R2", configuration = "reobf"))
|
shaded(project(":platforms:bukkit:nms:v1_18_R2", configuration = "reobf"))
|
||||||
shaded(project(":platforms:bukkit:nms:v1_19_R1", configuration = "reobf"))
|
shaded(project(":platforms:bukkit:nms:v1_19_R1", configuration = "reobf"))
|
||||||
|
shaded(project(":platforms:bukkit:nms:v1_19_R2", configuration = "reobf"))
|
||||||
shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
|
shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":platforms:bukkit:common"))
|
api(project(":platforms:bukkit:common"))
|
||||||
paperDevBundle(Versions.Bukkit.paperDevBundle)
|
paperDevBundle("1.19.2-R0.1-SNAPSHOT")
|
||||||
implementation("xyz.jpenilla", "reflection-remapper", "0.1.0-SNAPSHOT")
|
implementation("xyz.jpenilla", "reflection-remapper", "0.1.0-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
platforms/bukkit/nms/v1_19_R2/build.gradle.kts
Normal file
17
platforms/bukkit/nms/v1_19_R2/build.gradle.kts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
apply(plugin = "io.papermc.paperweight.userdev")
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":platforms:bukkit:common"))
|
||||||
|
paperDevBundle(Versions.Bukkit.paperDevBundle)
|
||||||
|
implementation("xyz.jpenilla", "reflection-remapper", "0.1.0-SNAPSHOT")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
assemble {
|
||||||
|
dependsOn("reobfJar")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.Holder.Reference;
|
||||||
|
import net.minecraft.core.MappedRegistry;
|
||||||
|
import net.minecraft.core.WritableRegistry;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
|
||||||
|
import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||||
|
|
||||||
|
|
||||||
|
public class AwfulBukkitHacks {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class);
|
||||||
|
|
||||||
|
private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();
|
||||||
|
|
||||||
|
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||||
|
try {
|
||||||
|
LOGGER.info("Hacking biome registry...");
|
||||||
|
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) RegistryFetcher.biomeRegistry();
|
||||||
|
|
||||||
|
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||||
|
|
||||||
|
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||||
|
try {
|
||||||
|
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
|
||||||
|
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||||
|
ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
|
||||||
|
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
|
||||||
|
|
||||||
|
ResourceKey<Biome> delegateKey = ResourceKey.create(
|
||||||
|
Registries.BIOME,
|
||||||
|
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
|
||||||
|
);
|
||||||
|
|
||||||
|
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
|
||||||
|
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.
|
||||||
|
|
||||||
|
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
|
||||||
|
|
||||||
|
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());
|
||||||
|
|
||||||
|
LOGGER.debug("Registered biome: " + delegateKey);
|
||||||
|
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||||
|
|
||||||
|
LOGGER.info("Doing tag garbage....");
|
||||||
|
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||||
|
.getTags() // streamKeysAndEntries
|
||||||
|
.collect(HashMap::new,
|
||||||
|
(map, pair) ->
|
||||||
|
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
|
||||||
|
HashMap::putAll);
|
||||||
|
|
||||||
|
terraBiomeMap
|
||||||
|
.forEach((vb, terraBiomes) ->
|
||||||
|
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
|
||||||
|
vanilla -> terraBiomes.forEach(
|
||||||
|
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
|
||||||
|
terra -> {
|
||||||
|
LOGGER.debug("{} (vanilla for {}): {}",
|
||||||
|
vanilla.unwrapKey().orElseThrow().location(),
|
||||||
|
terra.unwrapKey().orElseThrow().location(),
|
||||||
|
vanilla.tags().toList());
|
||||||
|
vanilla.tags()
|
||||||
|
.forEach(tag -> collect
|
||||||
|
.computeIfAbsent(tag, t -> new ArrayList<>())
|
||||||
|
.add(terra));
|
||||||
|
},
|
||||||
|
() -> LOGGER.error("No such biome: {}", tb))),
|
||||||
|
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||||
|
|
||||||
|
biomeRegistry.resetTags();
|
||||||
|
biomeRegistry.bindTags(ImmutableMap.copyOf(collect));
|
||||||
|
|
||||||
|
} catch(SecurityException | IllegalArgumentException exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.properties.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
public record NMSBiomeInfo(ResourceKey<Biome> biomeKey) implements Properties {
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.BiomeSpecialEffects;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||||
|
|
||||||
|
|
||||||
|
public class NMSBiomeInjector {
|
||||||
|
|
||||||
|
public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
|
||||||
|
return registry.getOptional(identifier)
|
||||||
|
.flatMap(registry::getResourceKey)
|
||||||
|
.flatMap(registry::getHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||||
|
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||||
|
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.precipitation(vanilla.getPrecipitation())
|
||||||
|
.downfall(vanilla.getDownfall())
|
||||||
|
.temperature(vanilla.getBaseTemperature())
|
||||||
|
.mobSpawnSettings(vanilla.getMobSettings())
|
||||||
|
.generationSettings(vanilla.getGenerationSettings());
|
||||||
|
|
||||||
|
|
||||||
|
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||||
|
|
||||||
|
effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());
|
||||||
|
|
||||||
|
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||||
|
|
||||||
|
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||||
|
|
||||||
|
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||||
|
|
||||||
|
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||||
|
|
||||||
|
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));
|
||||||
|
|
||||||
|
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||||
|
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
|
||||||
|
} else {
|
||||||
|
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||||
|
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
|
||||||
|
} else {
|
||||||
|
// grass
|
||||||
|
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
|
||||||
|
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
|
||||||
|
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
|
||||||
|
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
|
||||||
|
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);
|
||||||
|
|
||||||
|
builder.specialEffects(effects.build());
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||||
|
return pack.getID()
|
||||||
|
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.biome.Climate.Sampler;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
|
||||||
|
|
||||||
|
|
||||||
|
public class NMSBiomeProvider extends BiomeSource {
|
||||||
|
private final BiomeProvider delegate;
|
||||||
|
private final long seed;
|
||||||
|
private final Registry<Biome> biomeRegistry = RegistryFetcher.biomeRegistry();
|
||||||
|
|
||||||
|
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
|
||||||
|
super(delegate.stream()
|
||||||
|
.map(biome -> RegistryFetcher.biomeRegistry()
|
||||||
|
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
|
||||||
|
.get(NMSBiomeInfo.class)
|
||||||
|
.biomeKey())));
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull Codec<? extends BiomeSource> codec() {
|
||||||
|
return BiomeSource.CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
|
||||||
|
return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
|
||||||
|
.getPlatformBiome()).getContext()
|
||||||
|
.get(NMSBiomeInfo.class)
|
||||||
|
.biomeKey());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,173 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.WorldGenRegion;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
|
import net.minecraft.world.level.NoiseColumn;
|
||||||
|
import net.minecraft.world.level.StructureManager;
|
||||||
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
|
import net.minecraft.world.level.biome.BiomeManager;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.levelgen.Beardifier;
|
||||||
|
import net.minecraft.world.level.levelgen.DensityFunction.SinglePointContext;
|
||||||
|
import net.minecraft.world.level.levelgen.GenerationStep.Carving;
|
||||||
|
import net.minecraft.world.level.levelgen.Heightmap.Types;
|
||||||
|
import net.minecraft.world.level.levelgen.RandomState;
|
||||||
|
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
import com.dfsek.terra.api.world.info.WorldProperties;
|
||||||
|
import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions;
|
||||||
|
import com.dfsek.terra.bukkit.world.BukkitWorldProperties;
|
||||||
|
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
|
||||||
|
|
||||||
|
|
||||||
|
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
|
||||||
|
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
|
||||||
|
|
||||||
|
private final ChunkGenerator vanilla;
|
||||||
|
private final ConfigPack pack;
|
||||||
|
|
||||||
|
private final long seed;
|
||||||
|
|
||||||
|
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
|
||||||
|
super(biomeProvider);
|
||||||
|
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||||
|
this.vanilla = vanilla;
|
||||||
|
this.pack = pack;
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull Codec<? extends ChunkGenerator> codec() {
|
||||||
|
return ChunkGenerator.CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
|
||||||
|
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
|
||||||
|
@NotNull ChunkAccess chunk) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
|
||||||
|
@NotNull StructureManager structureAccessor) {
|
||||||
|
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
|
||||||
|
vanilla.spawnOriginalMobs(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGenDepth() {
|
||||||
|
return vanilla.getGenDepth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
|
||||||
|
@NotNull RandomState noiseConfig,
|
||||||
|
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
|
||||||
|
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
|
||||||
|
.thenApply(c -> {
|
||||||
|
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
|
||||||
|
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||||
|
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
|
||||||
|
if(compatibilityOptions.isBeard()) {
|
||||||
|
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), biomeProvider, compatibilityOptions);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
|
||||||
|
PreLoadCompatibilityOptions compatibilityOptions) {
|
||||||
|
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
|
||||||
|
double threshold = compatibilityOptions.getBeardThreshold();
|
||||||
|
double airThreshold = compatibilityOptions.getAirThreshold();
|
||||||
|
int xi = chunk.getPos().x << 4;
|
||||||
|
int zi = chunk.getPos().z << 4;
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
for(int z = 0; z < 16; z++) {
|
||||||
|
int depth = 0;
|
||||||
|
for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) {
|
||||||
|
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
|
||||||
|
if(noise > threshold) {
|
||||||
|
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
|
||||||
|
.getPalette(x + xi, y, z + zi, world, biomeProvider)
|
||||||
|
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
|
||||||
|
depth++;
|
||||||
|
} else if(noise < airThreshold) {
|
||||||
|
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
|
||||||
|
} else {
|
||||||
|
depth = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSeaLevel() {
|
||||||
|
return vanilla.getSeaLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinY() {
|
||||||
|
return vanilla.getMinY();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||||
|
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||||
|
int y = properties.getMaxHeight();
|
||||||
|
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||||
|
while(y >= getMinY() && !heightmap.isOpaque().test(
|
||||||
|
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
|
||||||
|
y--;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
|
||||||
|
/*
|
||||||
|
BlockState[] array = new BlockState[world.getHeight()];
|
||||||
|
WorldProperties properties = new NMSWorldProperties(seed, world);
|
||||||
|
BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties);
|
||||||
|
for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) {
|
||||||
|
array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider)
|
||||||
|
.getHandle()).getState();
|
||||||
|
}
|
||||||
|
return new NoiseColumn(getMinY(), array);
|
||||||
|
|
||||||
|
*/
|
||||||
|
return vanilla.getBaseColumn(x, z, world, noiseConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import com.dfsek.terra.bukkit.PlatformImpl;
|
||||||
|
import com.dfsek.terra.bukkit.nms.Initializer;
|
||||||
|
|
||||||
|
|
||||||
|
public class NMSInitializer implements Initializer {
|
||||||
|
@Override
|
||||||
|
public void initialize(PlatformImpl platform) {
|
||||||
|
AwfulBukkitHacks.registerBiomes(platform.getRawConfigRegistry());
|
||||||
|
Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
|
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
|
||||||
|
|
||||||
|
|
||||||
|
public class NMSInjectListener implements Listener {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
|
||||||
|
private static final Set<World> INJECTED = new HashSet<>();
|
||||||
|
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onWorldInit(WorldInitEvent event) {
|
||||||
|
if(!INJECTED.contains(event.getWorld()) &&
|
||||||
|
event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) {
|
||||||
|
INJECT_LOCK.lock();
|
||||||
|
INJECTED.add(event.getWorld());
|
||||||
|
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
|
||||||
|
CraftWorld craftWorld = (CraftWorld) event.getWorld();
|
||||||
|
ServerLevel serverWorld = craftWorld.getHandle();
|
||||||
|
|
||||||
|
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
|
||||||
|
|
||||||
|
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
|
||||||
|
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
|
||||||
|
|
||||||
|
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
|
||||||
|
|
||||||
|
LOGGER.info("Successfully injected into world.");
|
||||||
|
|
||||||
|
INJECT_LOCK.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.info.WorldProperties;
|
||||||
|
|
||||||
|
|
||||||
|
public class NMSWorldProperties implements WorldProperties {
|
||||||
|
private final long seed;
|
||||||
|
private final LevelHeightAccessor height;
|
||||||
|
|
||||||
|
public NMSWorldProperties(long seed, LevelHeightAccessor height) {
|
||||||
|
this.seed = seed;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getHandle() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSeed() {
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxHeight() {
|
||||||
|
return height.getMaxBuildHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight() {
|
||||||
|
return height.getMinBuildHeight();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.Holder.Reference;
|
||||||
|
import net.minecraft.core.MappedRegistry;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.StructureManager;
|
||||||
|
import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
||||||
|
import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory;
|
||||||
|
import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter;
|
||||||
|
import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter;
|
||||||
|
import xyz.jpenilla.reflectionremapper.proxy.annotation.MethodName;
|
||||||
|
import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
public class Reflection {
|
||||||
|
public static final MappedRegistryProxy MAPPED_REGISTRY;
|
||||||
|
public static final StructureManagerProxy STRUCTURE_MANAGER;
|
||||||
|
|
||||||
|
public static final ReferenceProxy REFERENCE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||||
|
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
|
||||||
|
Reflection.class.getClassLoader());
|
||||||
|
|
||||||
|
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
|
||||||
|
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||||
|
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Proxies(MappedRegistry.class)
|
||||||
|
public interface MappedRegistryProxy {
|
||||||
|
@FieldSetter("frozen")
|
||||||
|
void setFrozen(MappedRegistry<?> instance, boolean frozen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Proxies(StructureManager.class)
|
||||||
|
public interface StructureManagerProxy {
|
||||||
|
@FieldGetter("level")
|
||||||
|
LevelAccessor getLevel(StructureManager instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Proxies(Holder.Reference.class)
|
||||||
|
public interface ReferenceProxy {
|
||||||
|
@MethodName("bindValue")
|
||||||
|
<T> void invokeBindValue(Reference<T> instance, T value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.dfsek.terra.bukkit.nms.v1_19_R2;
|
||||||
|
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.CraftServer;
|
||||||
|
|
||||||
|
|
||||||
|
public class RegistryFetcher {
|
||||||
|
private static <T> Registry<T> getRegistry(ResourceKey<Registry<T>> key) {
|
||||||
|
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||||
|
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||||
|
return dedicatedserver
|
||||||
|
.registryAccess()
|
||||||
|
.registryOrThrow(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Registry<Biome> biomeRegistry() {
|
||||||
|
return getRegistry(Registries.BIOME);
|
||||||
|
}
|
||||||
|
}
|
@ -17,8 +17,9 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.forge;
|
package com.dfsek.terra.forge;
|
||||||
|
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraftforge.eventbus.api.EventPriority;
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
@ -71,12 +72,12 @@ public class ForgeEntryPoint {
|
|||||||
public void registerBiomes(RegisterEvent event) {
|
public void registerBiomes(RegisterEvent event) {
|
||||||
event.register(Keys.BLOCKS, helper -> sanityCheck.progress(RegistryStep.BLOCK, () -> logger.debug("Block registration detected.")));
|
event.register(Keys.BLOCKS, helper -> sanityCheck.progress(RegistryStep.BLOCK, () -> logger.debug("Block registration detected.")));
|
||||||
event.register(Keys.BIOMES, helper -> sanityCheck.progress(RegistryStep.BIOME, () -> initialize(helper)));
|
event.register(Keys.BIOMES, helper -> sanityCheck.progress(RegistryStep.BIOME, () -> initialize(helper)));
|
||||||
event.register(Registry.WORLD_PRESET_KEY,
|
event.register(RegistryKeys.WORLD_PRESET,
|
||||||
helper -> sanityCheck.progress(RegistryStep.WORLD_TYPE, () -> TERRA_PLUGIN.registerWorldTypes(helper::register)));
|
helper -> sanityCheck.progress(RegistryStep.WORLD_TYPE, () -> TERRA_PLUGIN.registerWorldTypes(helper::register)));
|
||||||
|
|
||||||
|
|
||||||
event.register(Registry.CHUNK_GENERATOR_KEY,
|
event.register(RegistryKeys.CHUNK_GENERATOR,
|
||||||
helper -> helper.register(new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER));
|
helper -> helper.register(new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER));
|
||||||
event.register(Registry.BIOME_SOURCE_KEY, helper -> helper.register(new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE));
|
event.register(RegistryKeys.BIOME_SOURCE, helper -> helper.register(new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,15 @@ import ca.solostudios.strata.Versions;
|
|||||||
import ca.solostudios.strata.parser.tokenizer.ParseException;
|
import ca.solostudios.strata.parser.tokenizer.ParseException;
|
||||||
import ca.solostudios.strata.version.Version;
|
import ca.solostudios.strata.version.Version;
|
||||||
import net.minecraft.MinecraftVersion;
|
import net.minecraft.MinecraftVersion;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
import net.minecraftforge.fml.loading.FMLLoader;
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
import net.minecraftforge.server.ServerLifecycleHooks;
|
import net.minecraftforge.server.ServerLifecycleHooks;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -86,7 +93,7 @@ public class ForgePlatform extends ModPlatform {
|
|||||||
|
|
||||||
super.platformAddon().forEach(addons::add);
|
super.platformAddon().forEach(addons::add);
|
||||||
|
|
||||||
String mcVersion = MinecraftVersion.CURRENT.getReleaseTarget();
|
String mcVersion = MinecraftVersion.CURRENT.getName();
|
||||||
try {
|
try {
|
||||||
addons.add(new EphemeralAddon(Versions.parseVersion(mcVersion), "minecraft"));
|
addons.add(new EphemeralAddon(Versions.parseVersion(mcVersion), "minecraft"));
|
||||||
} catch(ParseException e) {
|
} catch(ParseException e) {
|
||||||
@ -122,4 +129,19 @@ public class ForgePlatform extends ModPlatform {
|
|||||||
public BaseAddon getPlatformAddon() {
|
public BaseAddon getPlatformAddon() {
|
||||||
return new ForgeAddon(this);
|
return new ForgeAddon(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Registry<DimensionType> dimensionTypeRegistry() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Registry<Biome> biomeRegistry() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,26 @@
|
|||||||
package com.dfsek.terra.forge.mixin.lifecycle;
|
package com.dfsek.terra.forge.mixin.lifecycle;
|
||||||
|
|
||||||
|
import net.minecraft.registry.RegistryEntryLookup;
|
||||||
|
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler;
|
||||||
|
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler.NoiseParameters;
|
||||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
||||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil.NoiseHypercube;
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil.NoiseHypercube;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
import net.minecraft.world.gen.densityfunction.DensityFunction;
|
import net.minecraft.world.gen.densityfunction.DensityFunction;
|
||||||
import net.minecraft.world.gen.noise.NoiseConfig;
|
import net.minecraft.world.gen.noise.NoiseConfig;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.dfsek.terra.mod.util.SeedHack;
|
import com.dfsek.terra.mod.util.SeedHack;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hack to map noise sampler to seeds
|
* Hack to map noise sampler to seeds
|
||||||
@ -22,23 +29,12 @@ import com.dfsek.terra.mod.util.SeedHack;
|
|||||||
public class NoiseConfigMixin {
|
public class NoiseConfigMixin {
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
private long legacyWorldSeed;
|
private MultiNoiseSampler multiNoiseSampler;
|
||||||
|
|
||||||
@Redirect(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/util/registry/Registry;J)V",
|
@Inject(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/registry/RegistryEntryLookup;J)V",
|
||||||
at = @At(value = "NEW",
|
at = @At("TAIL"))
|
||||||
target = "(Lnet/minecraft/world/gen/densityfunction/DensityFunction;" +
|
private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup<NoiseParameters> noiseParametersLookup, long seed,
|
||||||
"Lnet/minecraft/world/gen/densityfunction/DensityFunction;" +
|
CallbackInfo ci) {
|
||||||
"Lnet/minecraft/world/gen/densityfunction/DensityFunction;" +
|
SeedHack.register(multiNoiseSampler, seed);
|
||||||
"Lnet/minecraft/world/gen/densityfunction/DensityFunction;" +
|
|
||||||
"Lnet/minecraft/world/gen/densityfunction/DensityFunction;" +
|
|
||||||
"Lnet/minecraft/world/gen/densityfunction/DensityFunction;Ljava/util/List;)" +
|
|
||||||
"Lnet/minecraft/world/biome/source/util/MultiNoiseUtil$MultiNoiseSampler;"))
|
|
||||||
private MultiNoiseSampler t(DensityFunction densityFunction, DensityFunction densityFunction2, DensityFunction densityFunction3,
|
|
||||||
DensityFunction densityFunction4, DensityFunction densityFunction5, DensityFunction densityFunction6,
|
|
||||||
List<NoiseHypercube> list) {
|
|
||||||
MultiNoiseSampler sampler = new MultiNoiseSampler(densityFunction, densityFunction2, densityFunction3, densityFunction4,
|
|
||||||
densityFunction5, densityFunction6, list);
|
|
||||||
SeedHack.register(sampler, legacyWorldSeed);
|
|
||||||
return sampler;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.dfsek.terra.forge.util;
|
package com.dfsek.terra.forge.util;
|
||||||
|
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.BuiltinRegistries;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
|
||||||
import net.minecraft.village.VillagerType;
|
import net.minecraft.village.VillagerType;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
import net.minecraftforge.registries.RegisterEvent.RegisterHelper;
|
import net.minecraftforge.registries.RegisterEvent.RegisterHelper;
|
||||||
@ -39,7 +39,6 @@ public final class BiomeUtil {
|
|||||||
pack.getCheckedRegistry(Biome.class)
|
pack.getCheckedRegistry(Biome.class)
|
||||||
.forEach((id, biome) -> registerBiome(biome, pack, id, helper));
|
.forEach((id, biome) -> registerBiome(biome, pack, id, helper));
|
||||||
});
|
});
|
||||||
MinecraftUtil.registerFlora(BuiltinRegistries.BIOME);
|
|
||||||
logger.info("Terra biomes registered.");
|
logger.info("Terra biomes registered.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +51,8 @@ public final class BiomeUtil {
|
|||||||
private static void registerBiome(Biome biome, ConfigPack pack,
|
private static void registerBiome(Biome biome, ConfigPack pack,
|
||||||
com.dfsek.terra.api.registry.key.RegistryKey id,
|
com.dfsek.terra.api.registry.key.RegistryKey id,
|
||||||
RegisterHelper<net.minecraft.world.biome.Biome> helper) {
|
RegisterHelper<net.minecraft.world.biome.Biome> helper) {
|
||||||
RegistryKey<net.minecraft.world.biome.Biome> vanilla = ((ProtoPlatformBiome) biome.getPlatformBiome()).get(BuiltinRegistries.BIOME);
|
RegistryEntry<net.minecraft.world.biome.Biome>
|
||||||
|
vanilla = ForgeRegistries.BIOMES.getHolder(((ProtoPlatformBiome) biome.getPlatformBiome()).getHandle()).orElseThrow();
|
||||||
|
|
||||||
|
|
||||||
if(pack.getContext().get(PreLoadCompatibilityOptions.class).useVanillaBiomes()) {
|
if(pack.getContext().get(PreLoadCompatibilityOptions.class).useVanillaBiomes()) {
|
||||||
@ -61,7 +61,7 @@ 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)
|
ForgeRegistries.BIOMES.getDelegateOrThrow(vanilla.getKey().orElseThrow())
|
||||||
.value(),
|
.value(),
|
||||||
vanillaBiomeProperties);
|
vanillaBiomeProperties);
|
||||||
|
|
||||||
@ -69,24 +69,20 @@ public final class BiomeUtil {
|
|||||||
|
|
||||||
if(ForgeRegistries.BIOMES.containsKey(identifier)) {
|
if(ForgeRegistries.BIOMES.containsKey(identifier)) {
|
||||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(ForgeRegistries.BIOMES.getHolder(identifier)
|
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(ForgeRegistries.BIOMES.getHolder(identifier)
|
||||||
.orElseThrow()
|
|
||||||
.getKey()
|
|
||||||
.orElseThrow());
|
.orElseThrow());
|
||||||
} else {
|
} else {
|
||||||
helper.register(MinecraftUtil.registerKey(identifier).getValue(), minecraftBiome);
|
helper.register(MinecraftUtil.registerKey(identifier).getValue(), minecraftBiome);
|
||||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(ForgeRegistries.BIOMES.getHolder(identifier)
|
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(ForgeRegistries.BIOMES.getHolder(identifier)
|
||||||
.orElseThrow()
|
|
||||||
.getKey()
|
|
||||||
.orElseThrow());
|
.orElseThrow());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap();
|
Map<RegistryKey<net.minecraft.world.biome.Biome>, VillagerType> villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap();
|
||||||
|
|
||||||
villagerMap.put(RegistryKey.of(Registry.BIOME_KEY, identifier),
|
villagerMap.put(RegistryKey.of(RegistryKeys.BIOME, identifier),
|
||||||
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
|
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
|
||||||
villagerMap.getOrDefault(vanilla, VillagerType.PLAINS)));
|
villagerMap.getOrDefault(vanilla.getKey().orElseThrow(), VillagerType.PLAINS)));
|
||||||
|
|
||||||
MinecraftUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getValue(), i -> new ArrayList<>()).add(identifier);
|
MinecraftUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getKey().orElseThrow().getValue(), i -> new ArrayList<>()).add(identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,26 @@ import com.dfsek.tectonic.api.depth.DepthTracker;
|
|||||||
import com.dfsek.tectonic.api.exception.LoadException;
|
import com.dfsek.tectonic.api.exception.LoadException;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.SpawnGroup;
|
import net.minecraft.entity.SpawnGroup;
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.sound.BiomeAdditionsSound;
|
import net.minecraft.sound.BiomeAdditionsSound;
|
||||||
import net.minecraft.sound.BiomeMoodSound;
|
import net.minecraft.sound.BiomeMoodSound;
|
||||||
import net.minecraft.sound.MusicSound;
|
import net.minecraft.sound.MusicSound;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.BuiltinRegistries;
|
|
||||||
import net.minecraft.village.VillagerType;
|
import net.minecraft.village.VillagerType;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.Biome.Precipitation;
|
import net.minecraft.world.biome.Biome.Precipitation;
|
||||||
import net.minecraft.world.biome.Biome.TemperatureModifier;
|
import net.minecraft.world.biome.Biome.TemperatureModifier;
|
||||||
import net.minecraft.world.biome.BiomeEffects.GrassColorModifier;
|
import net.minecraft.world.biome.BiomeEffects.GrassColorModifier;
|
||||||
import net.minecraft.world.biome.BiomeParticleConfig;
|
import net.minecraft.world.biome.BiomeParticleConfig;
|
||||||
import net.minecraft.world.biome.SpawnSettings;
|
import net.minecraft.world.biome.SpawnSettings;
|
||||||
import net.minecraft.world.biome.SpawnSettings.SpawnEntry;
|
import net.minecraft.world.biome.SpawnSettings.SpawnEntry;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.minecraft.world.gen.WorldPreset;
|
import net.minecraft.world.gen.WorldPreset;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -57,7 +62,7 @@ public abstract class ModPlatform extends AbstractPlatform {
|
|||||||
|
|
||||||
public void registerWorldTypes(BiConsumer<Identifier, WorldPreset> registerFunction) {
|
public void registerWorldTypes(BiConsumer<Identifier, WorldPreset> registerFunction) {
|
||||||
getRawConfigRegistry()
|
getRawConfigRegistry()
|
||||||
.forEach(pack -> PresetUtil.createDefault(pack).apply(registerFunction));
|
.forEach(pack -> PresetUtil.createDefault(pack, this).apply(registerFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -94,7 +99,7 @@ public abstract class ModPlatform extends AbstractPlatform {
|
|||||||
|
|
||||||
private ProtoPlatformBiome parseBiome(String id, DepthTracker tracker) throws LoadException {
|
private ProtoPlatformBiome parseBiome(String id, DepthTracker tracker) throws LoadException {
|
||||||
Identifier identifier = Identifier.tryParse(id);
|
Identifier identifier = Identifier.tryParse(id);
|
||||||
if(BuiltinRegistries.BIOME.get(identifier) == null) throw new LoadException("Invalid Biome ID: " + identifier, tracker); // failure.
|
if(!biomeRegistry().containsId(identifier)) throw new LoadException("Invalid Biome ID: " + identifier, tracker); // failure.
|
||||||
return new ProtoPlatformBiome(identifier);
|
return new ProtoPlatformBiome(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +110,10 @@ public abstract class ModPlatform extends AbstractPlatform {
|
|||||||
|
|
||||||
protected abstract BaseAddon getPlatformAddon();
|
protected abstract BaseAddon getPlatformAddon();
|
||||||
|
|
||||||
|
public abstract Registry<DimensionType> dimensionTypeRegistry();
|
||||||
|
public abstract Registry<Biome> biomeRegistry();
|
||||||
|
public abstract Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull WorldHandle getWorldHandle() {
|
public @NotNull WorldHandle getWorldHandle() {
|
||||||
return worldHandle;
|
return worldHandle;
|
||||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.mod.config;
|
|||||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.sound.BiomeAdditionsSound;
|
import net.minecraft.sound.BiomeAdditionsSound;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ public class BiomeAdditionsSoundTemplate implements ObjectTemplate<BiomeAddition
|
|||||||
if(sound == null || soundChance == null) {
|
if(sound == null || soundChance == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return new BiomeAdditionsSound(sound, soundChance);
|
return new BiomeAdditionsSound(Registries.SOUND_EVENT.getEntry(sound), soundChance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.mod.config;
|
|||||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.sound.BiomeMoodSound;
|
import net.minecraft.sound.BiomeMoodSound;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ public class BiomeMoodSoundTemplate implements ObjectTemplate<BiomeMoodSound> {
|
|||||||
if(sound == null || soundCultivationTicks == null || soundSpawnRange == null || soundExtraDistance == null) {
|
if(sound == null || soundCultivationTicks == null || soundSpawnRange == null || soundExtraDistance == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return new BiomeMoodSound(sound, soundCultivationTicks, soundSpawnRange, soundExtraDistance);
|
return new BiomeMoodSound(Registries.SOUND_EVENT.getEntry(sound), soundCultivationTicks, soundSpawnRange, soundExtraDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
|||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.command.argument.ParticleEffectArgumentType;
|
import net.minecraft.command.argument.ParticleEffectArgumentType;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.world.biome.BiomeParticleConfig;
|
import net.minecraft.world.biome.BiomeParticleConfig;
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ public class BiomeParticleConfigTemplate implements ObjectTemplate<BiomeParticle
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new BiomeParticleConfig(ParticleEffectArgumentType.readParameters(new StringReader(particle)), 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);
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,9 @@ import com.dfsek.tectonic.api.config.template.annotations.Default;
|
|||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
|
|
||||||
|
|
||||||
public class EntityTypeTemplate implements ObjectTemplate<EntityType<?>> {
|
public class EntityTypeTemplate implements ObjectTemplate<EntityType<?>> {
|
||||||
@ -15,6 +16,6 @@ public class EntityTypeTemplate implements ObjectTemplate<EntityType<?>> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityType<?> get() {
|
public EntityType<?> get() {
|
||||||
return Registry.ENTITY_TYPE.get(id);
|
return Registries.ENTITY_TYPE.get(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.dfsek.terra.mod.config;
|
|||||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.sound.MusicSound;
|
import net.minecraft.sound.MusicSound;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ public class MusicSoundTemplate implements ObjectTemplate<MusicSound> {
|
|||||||
if(sound == null || minDelay == null || maxDelay == null || replaceCurrentMusic == null) {
|
if(sound == null || minDelay == null || maxDelay == null || replaceCurrentMusic == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return new MusicSound(sound, minDelay, maxDelay, replaceCurrentMusic);
|
return new MusicSound(Registries.SOUND_EVENT.getEntry(sound), minDelay, maxDelay, replaceCurrentMusic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,10 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.mod.config;
|
package com.dfsek.terra.mod.config;
|
||||||
|
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -31,7 +32,7 @@ import com.dfsek.terra.mod.util.MinecraftUtil;
|
|||||||
public class ProtoPlatformBiome implements PlatformBiome {
|
public class ProtoPlatformBiome implements PlatformBiome {
|
||||||
private final Identifier identifier;
|
private final Identifier identifier;
|
||||||
|
|
||||||
private RegistryKey<Biome> delegate;
|
private RegistryEntry<Biome> delegate;
|
||||||
|
|
||||||
public ProtoPlatformBiome(Identifier identifier) {
|
public ProtoPlatformBiome(Identifier identifier) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
@ -42,15 +43,15 @@ public class ProtoPlatformBiome implements PlatformBiome {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getHandle() {
|
public Identifier getHandle() {
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegistryKey<Biome> getDelegate() {
|
public RegistryEntry<Biome> getDelegate() {
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDelegate(RegistryKey<Biome> delegate) {
|
public void setDelegate(RegistryEntry<Biome> delegate) {
|
||||||
this.delegate = Objects.requireNonNull(delegate);
|
this.delegate = Objects.requireNonNull(delegate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ public class SoundEventTemplate implements ObjectTemplate<SoundEvent> {
|
|||||||
if(id == null) {
|
if(id == null) {
|
||||||
return null;
|
return null;
|
||||||
} else if(distanceToTravel == null) {
|
} else if(distanceToTravel == null) {
|
||||||
return new SoundEvent(id);
|
return SoundEvent.of(id);
|
||||||
} else {
|
} else {
|
||||||
return new SoundEvent(id, distanceToTravel);
|
return SoundEvent.of(id, distanceToTravel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,9 @@ package com.dfsek.terra.mod.config;
|
|||||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.village.VillagerType;
|
import net.minecraft.village.VillagerType;
|
||||||
|
|
||||||
|
|
||||||
@ -15,6 +16,6 @@ public class VillagerTypeTemplate implements ObjectTemplate<VillagerType> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VillagerType get() {
|
public VillagerType get() {
|
||||||
return Registry.VILLAGER_TYPE.get(id);
|
return Registries.VILLAGER_TYPE.get(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package com.dfsek.terra.mod.data;
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.util.dynamic.RegistryOps;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.RegistryOps;
|
||||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
|
|
||||||
import com.dfsek.terra.api.config.ConfigPack;
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
@ -35,10 +35,7 @@ public final class Codecs {
|
|||||||
id)))));
|
id)))));
|
||||||
|
|
||||||
public static final Codec<TerraBiomeSource> TERRA_BIOME_SOURCE = RecordCodecBuilder
|
public static final Codec<TerraBiomeSource> TERRA_BIOME_SOURCE = RecordCodecBuilder
|
||||||
.create(instance -> instance.group(RegistryOps.createRegistryCodec(Registry.BIOME_KEY)
|
.create(instance -> instance.group(
|
||||||
.fieldOf("biome_registry")
|
|
||||||
.stable()
|
|
||||||
.forGetter(TerraBiomeSource::getBiomeRegistry),
|
|
||||||
CONFIG_PACK.fieldOf("pack")
|
CONFIG_PACK.fieldOf("pack")
|
||||||
.stable()
|
.stable()
|
||||||
.forGetter(TerraBiomeSource::getPack))
|
.forGetter(TerraBiomeSource::getPack))
|
||||||
@ -47,10 +44,6 @@ public final class Codecs {
|
|||||||
public static final Codec<MinecraftChunkGeneratorWrapper> MINECRAFT_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder
|
public static final Codec<MinecraftChunkGeneratorWrapper> MINECRAFT_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder
|
||||||
.create(
|
.create(
|
||||||
instance -> instance.group(
|
instance -> instance.group(
|
||||||
RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY)
|
|
||||||
.fieldOf("structure_registry")
|
|
||||||
.stable()
|
|
||||||
.forGetter(MinecraftChunkGeneratorWrapper::getNoiseRegistry),
|
|
||||||
TERRA_BIOME_SOURCE.fieldOf("biome_source")
|
TERRA_BIOME_SOURCE.fieldOf("biome_source")
|
||||||
.stable()
|
.stable()
|
||||||
.forGetter(MinecraftChunkGeneratorWrapper::getBiomeSource),
|
.forGetter(MinecraftChunkGeneratorWrapper::getBiomeSource),
|
||||||
@ -60,6 +53,7 @@ public final class Codecs {
|
|||||||
ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings")
|
ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings")
|
||||||
.stable()
|
.stable()
|
||||||
.forGetter(MinecraftChunkGeneratorWrapper::getSettings)
|
.forGetter(MinecraftChunkGeneratorWrapper::getSettings)
|
||||||
).apply(instance, instance.stable(MinecraftChunkGeneratorWrapper::new))
|
).apply(instance, instance.stable(
|
||||||
|
MinecraftChunkGeneratorWrapper::new))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,12 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.mod.generation;
|
package com.dfsek.terra.mod.generation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.mod.util.SeedHack;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.structure.StructureSet;
|
import net.minecraft.structure.StructureSet;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -27,8 +30,7 @@ import net.minecraft.util.math.ChunkPos;
|
|||||||
import net.minecraft.util.math.random.CheckedRandom;
|
import net.minecraft.util.math.random.CheckedRandom;
|
||||||
import net.minecraft.util.math.random.ChunkRandom;
|
import net.minecraft.util.math.random.ChunkRandom;
|
||||||
import net.minecraft.util.math.random.RandomSeed;
|
import net.minecraft.util.math.random.RandomSeed;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
|
||||||
import net.minecraft.world.ChunkRegion;
|
import net.minecraft.world.ChunkRegion;
|
||||||
import net.minecraft.world.HeightLimitView;
|
import net.minecraft.world.HeightLimitView;
|
||||||
import net.minecraft.world.Heightmap.Type;
|
import net.minecraft.world.Heightmap.Type;
|
||||||
@ -71,15 +73,13 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
|
|||||||
private static final Logger logger = LoggerFactory.getLogger(MinecraftChunkGeneratorWrapper.class);
|
private static final Logger logger = LoggerFactory.getLogger(MinecraftChunkGeneratorWrapper.class);
|
||||||
|
|
||||||
private final TerraBiomeSource biomeSource;
|
private final TerraBiomeSource biomeSource;
|
||||||
private final Registry<StructureSet> noiseRegistry;
|
|
||||||
private final RegistryEntry<ChunkGeneratorSettings> settings;
|
private final RegistryEntry<ChunkGeneratorSettings> settings;
|
||||||
private ChunkGenerator delegate;
|
private ChunkGenerator delegate;
|
||||||
private ConfigPack pack;
|
private ConfigPack pack;
|
||||||
|
|
||||||
public MinecraftChunkGeneratorWrapper(Registry<StructureSet> noiseRegistry, TerraBiomeSource biomeSource, ConfigPack configPack,
|
public MinecraftChunkGeneratorWrapper(TerraBiomeSource biomeSource, ConfigPack configPack,
|
||||||
RegistryEntry<ChunkGeneratorSettings> settingsSupplier) {
|
RegistryEntry<ChunkGeneratorSettings> settingsSupplier) {
|
||||||
super(noiseRegistry, Optional.empty(), biomeSource);
|
super(biomeSource);
|
||||||
this.noiseRegistry = noiseRegistry;
|
|
||||||
this.pack = configPack;
|
this.pack = configPack;
|
||||||
this.settings = settingsSupplier;
|
this.settings = settingsSupplier;
|
||||||
|
|
||||||
@ -88,10 +88,6 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
|
|||||||
this.biomeSource = biomeSource;
|
this.biomeSource = biomeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Registry<StructureSet> getNoiseRegistry() {
|
|
||||||
return noiseRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Codec<? extends net.minecraft.world.gen.chunk.ChunkGenerator> getCodec() {
|
protected Codec<? extends net.minecraft.world.gen.chunk.ChunkGenerator> getCodec() {
|
||||||
return Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER;
|
return Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER;
|
||||||
@ -137,7 +133,7 @@ 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.method_42695(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;
|
||||||
@ -185,7 +181,7 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight(int x, int z, Type heightmap, HeightLimitView height, NoiseConfig noiseConfig) {
|
public int getHeight(int x, int z, Type heightmap, HeightLimitView height, NoiseConfig noiseConfig) {
|
||||||
WorldProperties properties = MinecraftAdapter.adapt(height, noiseConfig.getLegacyWorldSeed());
|
WorldProperties properties = MinecraftAdapter.adapt(height, SeedHack.getSeed(noiseConfig.getMultiNoiseSampler()));
|
||||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||||
int min = height.getBottomY();
|
int min = height.getBottomY();
|
||||||
for(int y = height.getTopY() - 1; y >= min; y--) {
|
for(int y = height.getTopY() - 1; y >= min; y--) {
|
||||||
@ -199,7 +195,7 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun
|
|||||||
@Override
|
@Override
|
||||||
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height, NoiseConfig noiseConfig) {
|
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height, NoiseConfig noiseConfig) {
|
||||||
BlockState[] array = new BlockState[height.getHeight()];
|
BlockState[] array = new BlockState[height.getHeight()];
|
||||||
WorldProperties properties = MinecraftAdapter.adapt(height, noiseConfig.getLegacyWorldSeed());
|
WorldProperties properties = MinecraftAdapter.adapt(height, SeedHack.getSeed(noiseConfig.getMultiNoiseSampler()));
|
||||||
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
BiomeProvider biomeProvider = pack.getBiomeProvider();
|
||||||
for(int y = height.getTopY() - 1; y >= height.getBottomY(); y--) {
|
for(int y = height.getTopY() - 1; y >= height.getBottomY(); y--) {
|
||||||
array[y - height.getBottomY()] = (BlockState) delegate.getBlock(properties, x, y, z, biomeProvider);
|
array[y - height.getBottomY()] = (BlockState) delegate.getBlock(properties, x, y, z, biomeProvider);
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
package com.dfsek.terra.mod.generation;
|
package com.dfsek.terra.mod.generation;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.source.BiomeSource;
|
import net.minecraft.world.biome.source.BiomeSource;
|
||||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -37,16 +38,14 @@ import com.dfsek.terra.mod.util.SeedHack;
|
|||||||
public class TerraBiomeSource extends BiomeSource {
|
public class TerraBiomeSource extends BiomeSource {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(TerraBiomeSource.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(TerraBiomeSource.class);
|
||||||
private final Registry<net.minecraft.world.biome.Biome> biomeRegistry;
|
|
||||||
private ConfigPack pack;
|
private ConfigPack pack;
|
||||||
|
|
||||||
public TerraBiomeSource(Registry<net.minecraft.world.biome.Biome> biomes, ConfigPack pack) {
|
public TerraBiomeSource(ConfigPack pack) {
|
||||||
super(StreamSupport
|
super(StreamSupport
|
||||||
.stream(pack.getBiomeProvider()
|
.stream(pack.getBiomeProvider()
|
||||||
.getBiomes()
|
.getBiomes()
|
||||||
.spliterator(), false)
|
.spliterator(), false)
|
||||||
.map(b -> biomes.getOrCreateEntry(((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate())));
|
.map(b -> ((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate()));
|
||||||
this.biomeRegistry = biomes;
|
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
|
|
||||||
LOGGER.debug("Biomes: " + getBiomes());
|
LOGGER.debug("Biomes: " + getBiomes());
|
||||||
@ -58,23 +57,17 @@ public class TerraBiomeSource extends BiomeSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RegistryEntry<net.minecraft.world.biome.Biome> getBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseSampler noiseSampler) {
|
public RegistryEntry<Biome> getBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseSampler noiseSampler) {
|
||||||
return biomeRegistry
|
return ((ProtoPlatformBiome) pack
|
||||||
.entryOf(((ProtoPlatformBiome) pack
|
|
||||||
.getBiomeProvider()
|
.getBiomeProvider()
|
||||||
.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, SeedHack.getSeed(noiseSampler))
|
.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, SeedHack.getSeed(noiseSampler))
|
||||||
.getPlatformBiome()).getDelegate()
|
.getPlatformBiome()).getDelegate();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BiomeProvider getProvider() {
|
public BiomeProvider getProvider() {
|
||||||
return pack.getBiomeProvider();
|
return pack.getBiomeProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Registry<net.minecraft.world.biome.Biome> getBiomeRegistry() {
|
|
||||||
return biomeRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigPack getPack() {
|
public ConfigPack getPack() {
|
||||||
return pack;
|
return pack;
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,11 @@ import com.mojang.brigadier.StringReader;
|
|||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.command.CommandRegistryAccess;
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
import net.minecraft.command.argument.ItemStackArgumentType;
|
import net.minecraft.command.argument.ItemStackArgumentType;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryWrapper;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -38,8 +41,12 @@ public class MinecraftItemHandle implements ItemHandle {
|
|||||||
@Override
|
@Override
|
||||||
public Item createItem(String data) {
|
public Item createItem(String data) {
|
||||||
try {
|
try {
|
||||||
return (Item) new ItemStackArgumentType(new CommandRegistryAccess(
|
return (Item) new ItemStackArgumentType(new CommandRegistryAccess() {
|
||||||
CommonPlatform.get().getServer().getRegistryManager())).parse(new StringReader(data)).getItem();
|
@Override
|
||||||
|
public <T> RegistryWrapper<T> createWrapper(RegistryKey<? extends Registry<T>> registryRef) {
|
||||||
|
return CommonPlatform.get().getServer().getRegistryManager().getWrapperOrThrow(registryRef);
|
||||||
|
}
|
||||||
|
}).parse(new StringReader(data)).getItem();
|
||||||
} catch(CommandSyntaxException e) {
|
} catch(CommandSyntaxException e) {
|
||||||
throw new IllegalArgumentException("Invalid item data \"" + data + "\"", e);
|
throw new IllegalArgumentException("Invalid item data \"" + data + "\"", e);
|
||||||
}
|
}
|
||||||
@ -47,11 +54,11 @@ public class MinecraftItemHandle implements ItemHandle {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Enchantment getEnchantment(String id) {
|
public Enchantment getEnchantment(String id) {
|
||||||
return (Enchantment) (Registry.ENCHANTMENT.get(Identifier.tryParse(id)));
|
return (Enchantment) (Registries.ENCHANTMENT.get(Identifier.tryParse(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Enchantment> getEnchantments() {
|
public Set<Enchantment> getEnchantments() {
|
||||||
return Registry.ENCHANTMENT.stream().map(enchantment -> (Enchantment) enchantment).collect(Collectors.toSet());
|
return Registries.ENCHANTMENT.stream().map(enchantment -> (Enchantment) enchantment).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,9 @@ package com.dfsek.terra.mod.handle;
|
|||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.command.argument.BlockArgumentParser;
|
import net.minecraft.command.argument.BlockArgumentParser;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.dfsek.terra.api.block.state.BlockState;
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
@ -36,7 +37,7 @@ 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(Registry.BLOCK, 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) {
|
||||||
@ -53,6 +54,6 @@ public class MinecraftWorldHandle implements WorldHandle {
|
|||||||
public @NotNull EntityType getEntity(@NotNull String id) {
|
public @NotNull EntityType getEntity(@NotNull String id) {
|
||||||
Identifier identifier = Identifier.tryParse(id);
|
Identifier identifier = Identifier.tryParse(id);
|
||||||
if(identifier == null) identifier = Identifier.tryParse(id);
|
if(identifier == null) identifier = Identifier.tryParse(id);
|
||||||
return (EntityType) Registry.ENTITY_TYPE.get(identifier);
|
return (EntityType) Registries.ENTITY_TYPE.get(identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.dfsek.terra.mod.mixin.access;
|
package com.dfsek.terra.mod.mixin.access;
|
||||||
|
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.village.VillagerType;
|
import net.minecraft.village.VillagerType;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -21,9 +21,11 @@ import net.minecraft.block.BlockState;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.block.entity.MobSpawnerBlockEntity;
|
import net.minecraft.block.entity.MobSpawnerBlockEntity;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.util.math.random.Random;
|
||||||
import net.minecraft.world.MobSpawnerLogic;
|
import net.minecraft.world.MobSpawnerLogic;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.spongepowered.asm.mixin.Implements;
|
import org.spongepowered.asm.mixin.Implements;
|
||||||
@ -48,13 +50,16 @@ public abstract class MobSpawnerBlockEntityMixin extends BlockEntity {
|
|||||||
@Shadow
|
@Shadow
|
||||||
public abstract MobSpawnerLogic getLogic();
|
public abstract MobSpawnerLogic getLogic();
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract void setEntityType(net.minecraft.entity.EntityType<?> entityType, Random random);
|
||||||
|
|
||||||
public EntityType terra$getSpawnedType() {
|
public EntityType terra$getSpawnedType() {
|
||||||
return (EntityType) Registry.ENTITY_TYPE.get(
|
return (EntityType) Registries.ENTITY_TYPE.get(
|
||||||
Identifier.tryParse(((MobSpawnerLogicAccessor) getLogic()).getSpawnEntry().getNbt().getString("id")));
|
Identifier.tryParse(((MobSpawnerLogicAccessor) getLogic()).getSpawnEntry().getNbt().getString("id")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terra$setSpawnedType(@NotNull EntityType creatureType) {
|
public void terra$setSpawnedType(@NotNull EntityType creatureType) {
|
||||||
getLogic().setEntityId((net.minecraft.entity.EntityType<?>) creatureType);
|
setEntityType((net.minecraft.entity.EntityType<?>) creatureType, world.getRandom());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int terra$getDelay() {
|
public int terra$getDelay() {
|
||||||
|
@ -5,8 +5,9 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
import net.minecraft.block.AbstractBlock.AbstractBlockState;
|
import net.minecraft.block.AbstractBlock.AbstractBlockState;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.state.State;
|
import net.minecraft.state.State;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import org.spongepowered.asm.mixin.Implements;
|
import org.spongepowered.asm.mixin.Implements;
|
||||||
import org.spongepowered.asm.mixin.Interface;
|
import org.spongepowered.asm.mixin.Interface;
|
||||||
import org.spongepowered.asm.mixin.Intrinsic;
|
import org.spongepowered.asm.mixin.Intrinsic;
|
||||||
@ -66,7 +67,7 @@ public abstract class BlockStateMixin extends State<Block, net.minecraft.block.B
|
|||||||
|
|
||||||
@Intrinsic
|
@Intrinsic
|
||||||
public String terra$getAsString(boolean properties) {
|
public String terra$getAsString(boolean properties) {
|
||||||
StringBuilder data = new StringBuilder(Registry.BLOCK.getId(getBlock()).toString());
|
StringBuilder data = new StringBuilder(Registries.BLOCK.getId(getBlock()).toString());
|
||||||
if(properties && !getEntries().isEmpty()) {
|
if(properties && !getEntries().isEmpty()) {
|
||||||
data.append('[');
|
data.append('[');
|
||||||
data.append(
|
data.append(
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
package com.dfsek.terra.mod.mixin.implementations.terra.inventory.meta;
|
package com.dfsek.terra.mod.mixin.implementations.terra.inventory.meta;
|
||||||
|
|
||||||
import net.minecraft.enchantment.Enchantment;
|
import net.minecraft.enchantment.Enchantment;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import org.spongepowered.asm.mixin.Implements;
|
import org.spongepowered.asm.mixin.Implements;
|
||||||
import org.spongepowered.asm.mixin.Interface;
|
import org.spongepowered.asm.mixin.Interface;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@ -48,6 +50,6 @@ public abstract class EnchantmentMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String terra$getID() {
|
public String terra$getID() {
|
||||||
return Objects.requireNonNull(Registry.ENCHANTMENT.getId((Enchantment) (Object) this)).toString();
|
return Objects.requireNonNull(Registries.ENCHANTMENT.getId((Enchantment) (Object) this)).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@ package com.dfsek.terra.mod.mixin.implementations.terra.inventory.meta;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.nbt.NbtList;
|
import net.minecraft.nbt.NbtList;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
import org.spongepowered.asm.mixin.Implements;
|
import org.spongepowered.asm.mixin.Implements;
|
||||||
import org.spongepowered.asm.mixin.Interface;
|
import org.spongepowered.asm.mixin.Interface;
|
||||||
import org.spongepowered.asm.mixin.Intrinsic;
|
import org.spongepowered.asm.mixin.Intrinsic;
|
||||||
@ -58,7 +59,7 @@ public abstract class ItemStackMetaMixin {
|
|||||||
|
|
||||||
getEnchantments().forEach(enchantment -> {
|
getEnchantments().forEach(enchantment -> {
|
||||||
NbtCompound eTag = (NbtCompound) enchantment;
|
NbtCompound eTag = (NbtCompound) enchantment;
|
||||||
map.put((Enchantment) Registry.ENCHANTMENT.get(eTag.getInt("id")), eTag.getInt("lvl"));
|
map.put((Enchantment) Registries.ENCHANTMENT.get(eTag.getInt("id")), eTag.getInt("lvl"));
|
||||||
});
|
});
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.dfsek.terra.mod.mixin.lifecycle;
|
package com.dfsek.terra.mod.mixin.lifecycle;
|
||||||
|
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.server.DataPackContents;
|
import net.minecraft.server.DataPackContents;
|
||||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@ -18,11 +20,11 @@ public class DataPackContentsMixin {
|
|||||||
/*
|
/*
|
||||||
* #refresh populates all tags in the registries
|
* #refresh populates all tags in the registries
|
||||||
*/
|
*/
|
||||||
@Inject(method = "refresh(Lnet/minecraft/util/registry/DynamicRegistryManager;)V", at = @At("RETURN"))
|
@Inject(method = "refresh(Lnet/minecraft/registry/DynamicRegistryManager;)V", at = @At("RETURN"))
|
||||||
private void injectReload(DynamicRegistryManager dynamicRegistryManager, CallbackInfo ci) {
|
private void injectReload(DynamicRegistryManager dynamicRegistryManager, CallbackInfo ci) {
|
||||||
TagUtil.registerWorldPresetTags(dynamicRegistryManager.get(Registry.WORLD_PRESET_KEY));
|
TagUtil.registerWorldPresetTags(dynamicRegistryManager.get(RegistryKeys.WORLD_PRESET));
|
||||||
|
|
||||||
Registry<Biome> biomeRegistry = dynamicRegistryManager.get(Registry.BIOME_KEY);
|
Registry<Biome> biomeRegistry = dynamicRegistryManager.get(RegistryKeys.BIOME);
|
||||||
TagUtil.registerBiomeTags(biomeRegistry);
|
TagUtil.registerBiomeTags(biomeRegistry);
|
||||||
MinecraftUtil.registerFlora(biomeRegistry);
|
MinecraftUtil.registerFlora(biomeRegistry);
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,13 @@ package com.dfsek.terra.mod.util;
|
|||||||
import net.minecraft.block.entity.LootableContainerBlockEntity;
|
import net.minecraft.block.entity.LootableContainerBlockEntity;
|
||||||
import net.minecraft.block.entity.MobSpawnerBlockEntity;
|
import net.minecraft.block.entity.MobSpawnerBlockEntity;
|
||||||
import net.minecraft.block.entity.SignBlockEntity;
|
import net.minecraft.block.entity.SignBlockEntity;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
|
||||||
import net.minecraft.world.WorldAccess;
|
import net.minecraft.world.WorldAccess;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.Biome.Builder;
|
import net.minecraft.world.biome.Biome.Builder;
|
||||||
@ -23,6 +25,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.dfsek.terra.api.block.entity.BlockEntity;
|
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||||
import com.dfsek.terra.api.block.entity.Container;
|
import com.dfsek.terra.api.block.entity.Container;
|
||||||
@ -46,7 +49,7 @@ public final class MinecraftUtil {
|
|||||||
public static <T> Optional<RegistryEntry<T>> getEntry(Registry<T> registry, Identifier identifier) {
|
public static <T> Optional<RegistryEntry<T>> getEntry(Registry<T> registry, Identifier identifier) {
|
||||||
return registry.getOrEmpty(identifier)
|
return registry.getOrEmpty(identifier)
|
||||||
.flatMap(registry::getKey)
|
.flatMap(registry::getKey)
|
||||||
.map(registry::getOrCreateEntry);
|
.flatMap(registry::getEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockEntity createState(WorldAccess worldAccess, BlockPos pos) {
|
public static BlockEntity createState(WorldAccess worldAccess, BlockPos pos) {
|
||||||
@ -91,7 +94,7 @@ public final class MinecraftUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static RegistryKey<Biome> registerKey(Identifier identifier) {
|
public static RegistryKey<Biome> registerKey(Identifier identifier) {
|
||||||
return RegistryKey.of(Registry.BIOME_KEY, identifier);
|
return RegistryKey.of(RegistryKeys.BIOME, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla,
|
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla,
|
||||||
@ -131,7 +134,7 @@ public final class MinecraftUtil {
|
|||||||
if(vanillaBiomeProperties.getLoopSound() == null) {
|
if(vanillaBiomeProperties.getLoopSound() == null) {
|
||||||
vanilla.getEffects().getLoopSound().ifPresent(effects::loopSound);
|
vanilla.getEffects().getLoopSound().ifPresent(effects::loopSound);
|
||||||
} else {
|
} else {
|
||||||
effects.loopSound(vanillaBiomeProperties.getLoopSound());
|
effects.loopSound(Registries.SOUND_EVENT.getEntry(vanillaBiomeProperties.getLoopSound()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vanillaBiomeProperties.getMoodSound() == null) {
|
if(vanillaBiomeProperties.getMoodSound() == null) {
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.dfsek.terra.mod.util;
|
package com.dfsek.terra.mod.util;
|
||||||
|
|
||||||
import net.minecraft.structure.StructureSet;
|
import com.dfsek.terra.mod.ModPlatform;
|
||||||
|
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler.NoiseParameters;
|
|
||||||
import net.minecraft.util.registry.BuiltinRegistries;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.source.MultiNoiseBiomeSource;
|
import net.minecraft.world.biome.source.MultiNoiseBiomeSource;
|
||||||
import net.minecraft.world.biome.source.TheEndBiomeSource;
|
import net.minecraft.world.biome.source.TheEndBiomeSource;
|
||||||
@ -34,41 +36,39 @@ public class PresetUtil {
|
|||||||
private static final Logger LOGGER = LoggerFactory.getLogger(PresetUtil.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(PresetUtil.class);
|
||||||
private static final List<Identifier> PRESETS = new ArrayList<>();
|
private static final List<Identifier> PRESETS = new ArrayList<>();
|
||||||
|
|
||||||
public static Pair<Identifier, WorldPreset> createDefault(ConfigPack pack) {
|
public static Pair<Identifier, WorldPreset> createDefault(ConfigPack pack, ModPlatform platform) {
|
||||||
Registry<DimensionType> dimensionTypeRegistry = BuiltinRegistries.DIMENSION_TYPE;
|
Registry<DimensionType> dimensionTypeRegistry = platform.dimensionTypeRegistry();
|
||||||
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry = BuiltinRegistries.CHUNK_GENERATOR_SETTINGS;
|
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry = platform.chunkGeneratorSettingsRegistry();
|
||||||
Registry<StructureSet> structureSetRegistry = BuiltinRegistries.STRUCTURE_SET;
|
|
||||||
Registry<NoiseParameters> noiseParametersRegistry = BuiltinRegistries.NOISE_PARAMETERS;
|
|
||||||
Registry<Biome> biomeRegistry = BuiltinRegistries.BIOME;
|
|
||||||
|
|
||||||
RegistryEntry<DimensionType> theNetherDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.THE_NETHER);
|
RegistryEntry<DimensionType> theNetherDimensionType = dimensionTypeRegistry.getEntry(DimensionTypes.THE_NETHER).orElseThrow();
|
||||||
RegistryEntry<ChunkGeneratorSettings>
|
RegistryEntry<ChunkGeneratorSettings>
|
||||||
netherChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getOrCreateEntry(ChunkGeneratorSettings.NETHER);
|
netherChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.NETHER).orElseThrow();
|
||||||
DimensionOptions netherDimensionOptions = new DimensionOptions(theNetherDimensionType,
|
DimensionOptions netherDimensionOptions = new DimensionOptions(theNetherDimensionType,
|
||||||
new NoiseChunkGenerator(structureSetRegistry,
|
new NoiseChunkGenerator(
|
||||||
noiseParametersRegistry,
|
MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource(
|
||||||
MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource(
|
platform.biomeRegistry().getReadOnlyWrapper()),
|
||||||
biomeRegistry),
|
netherChunkGeneratorSettings));
|
||||||
netherChunkGeneratorSettings));
|
RegistryEntry<DimensionType> theEndDimensionType = dimensionTypeRegistry.getEntry(DimensionTypes.THE_END).orElseThrow();
|
||||||
RegistryEntry<DimensionType> theEndDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.THE_END);
|
RegistryEntry<ChunkGeneratorSettings> endChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getEntry(
|
||||||
RegistryEntry<ChunkGeneratorSettings> endChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getOrCreateEntry(
|
ChunkGeneratorSettings.END).orElseThrow();
|
||||||
ChunkGeneratorSettings.END);
|
|
||||||
DimensionOptions endDimensionOptions = new DimensionOptions(theEndDimensionType,
|
DimensionOptions endDimensionOptions = new DimensionOptions(theEndDimensionType,
|
||||||
new NoiseChunkGenerator(structureSetRegistry, noiseParametersRegistry,
|
new NoiseChunkGenerator(
|
||||||
new TheEndBiomeSource(biomeRegistry),
|
TheEndBiomeSource.createVanilla(
|
||||||
endChunkGeneratorSettings));
|
platform.biomeRegistry().getReadOnlyWrapper()),
|
||||||
|
endChunkGeneratorSettings));
|
||||||
|
|
||||||
RegistryEntry<DimensionType> overworldDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.OVERWORLD);
|
RegistryEntry<DimensionType> overworldDimensionType = dimensionTypeRegistry.getEntry(DimensionTypes.OVERWORLD).orElseThrow();
|
||||||
|
|
||||||
RegistryEntry<ChunkGeneratorSettings> overworld = chunkGeneratorSettingsRegistry.getOrCreateEntry(ChunkGeneratorSettings.OVERWORLD);
|
RegistryEntry<ChunkGeneratorSettings> overworld = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.OVERWORLD)
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
Identifier generatorID = Identifier.of("terra", pack.getID().toLowerCase(Locale.ROOT) + "/" + pack.getNamespace().toLowerCase(
|
Identifier generatorID = Identifier.of("terra", pack.getID().toLowerCase(Locale.ROOT) + "/" + pack.getNamespace().toLowerCase(
|
||||||
Locale.ROOT));
|
Locale.ROOT));
|
||||||
|
|
||||||
PRESETS.add(generatorID);
|
PRESETS.add(generatorID);
|
||||||
|
|
||||||
TerraBiomeSource biomeSource = new TerraBiomeSource(biomeRegistry, pack);
|
TerraBiomeSource biomeSource = new TerraBiomeSource(pack);
|
||||||
ChunkGenerator generator = new MinecraftChunkGeneratorWrapper(structureSetRegistry, biomeSource, pack, overworld);
|
ChunkGenerator generator = new MinecraftChunkGeneratorWrapper(biomeSource, pack, overworld);
|
||||||
|
|
||||||
DimensionOptions dimensionOptions = new DimensionOptions(overworldDimensionType, generator);
|
DimensionOptions dimensionOptions = new DimensionOptions(overworldDimensionType, generator);
|
||||||
WorldPreset preset = new WorldPreset(
|
WorldPreset preset = new WorldPreset(
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.dfsek.terra.mod.util;
|
package com.dfsek.terra.mod.util;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import net.minecraft.tag.TagKey;
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.tag.WorldPresetTags;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.tag.TagKey;
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
import net.minecraft.registry.tag.WorldPresetTags;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.gen.WorldPreset;
|
import net.minecraft.world.gen.WorldPreset;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -3,17 +3,23 @@ package com.dfsek.terra.lifecycle;
|
|||||||
import ca.solostudios.strata.Versions;
|
import ca.solostudios.strata.Versions;
|
||||||
import ca.solostudios.strata.parser.tokenizer.ParseException;
|
import ca.solostudios.strata.parser.tokenizer.ParseException;
|
||||||
import net.minecraft.MinecraftVersion;
|
import net.minecraft.MinecraftVersion;
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import com.dfsek.terra.addon.EphemeralAddon;
|
import com.dfsek.terra.addon.EphemeralAddon;
|
||||||
import com.dfsek.terra.api.addon.BaseAddon;
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
import com.dfsek.terra.lifecycle.util.BiomeUtil;
|
|
||||||
import com.dfsek.terra.mod.CommonPlatform;
|
import com.dfsek.terra.mod.CommonPlatform;
|
||||||
import com.dfsek.terra.mod.ModPlatform;
|
import com.dfsek.terra.mod.ModPlatform;
|
||||||
import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
|
import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
|
||||||
@ -23,6 +29,10 @@ 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 MinecraftServer server;
|
||||||
|
|
||||||
|
private static final AtomicReference<Registry<Biome>> BIOMES = new AtomicReference<>();
|
||||||
|
private static final AtomicReference<Registry<DimensionType>> DIMENSIONS = new AtomicReference<>();
|
||||||
|
private static final AtomicReference<Registry<ChunkGeneratorSettings>> SETTINGS = new AtomicReference<>();
|
||||||
|
|
||||||
public LifecyclePlatform() {
|
public LifecyclePlatform() {
|
||||||
CommonPlatform.initialize(this);
|
CommonPlatform.initialize(this);
|
||||||
load();
|
load();
|
||||||
@ -49,7 +59,6 @@ public abstract class LifecyclePlatform extends ModPlatform {
|
|||||||
LOGGER.warn("Failed to execute reload", throwable);
|
LOGGER.warn("Failed to execute reload", throwable);
|
||||||
return null;
|
return null;
|
||||||
}).join();
|
}).join();
|
||||||
BiomeUtil.registerBiomes();
|
|
||||||
server.getWorlds().forEach(world -> {
|
server.getWorlds().forEach(world -> {
|
||||||
if(world.getChunkManager().getChunkGenerator() instanceof MinecraftChunkGeneratorWrapper chunkGeneratorWrapper) {
|
if(world.getChunkManager().getChunkGenerator() instanceof MinecraftChunkGeneratorWrapper chunkGeneratorWrapper) {
|
||||||
getConfigRegistry().get(chunkGeneratorWrapper.getPack().getRegistryKey()).ifPresent(pack -> {
|
getConfigRegistry().get(chunkGeneratorWrapper.getPack().getRegistryKey()).ifPresent(pack -> {
|
||||||
@ -62,13 +71,21 @@ public abstract class LifecyclePlatform extends ModPlatform {
|
|||||||
return succeed;
|
return succeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setRegistries(Registry<Biome> biomeRegistry,
|
||||||
|
Registry<DimensionType> dimensionTypeRegistry,
|
||||||
|
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry) {
|
||||||
|
BIOMES.set(biomeRegistry);
|
||||||
|
DIMENSIONS.set(dimensionTypeRegistry);
|
||||||
|
SETTINGS.set(chunkGeneratorSettingsRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Iterable<BaseAddon> platformAddon() {
|
protected Iterable<BaseAddon> platformAddon() {
|
||||||
List<BaseAddon> addons = new ArrayList<>();
|
List<BaseAddon> addons = new ArrayList<>();
|
||||||
|
|
||||||
super.platformAddon().forEach(addons::add);
|
super.platformAddon().forEach(addons::add);
|
||||||
|
|
||||||
String mcVersion = MinecraftVersion.CURRENT.getReleaseTarget();
|
String mcVersion = MinecraftVersion.CURRENT.getName();
|
||||||
try {
|
try {
|
||||||
addons.add(new EphemeralAddon(Versions.parseVersion(mcVersion), "minecraft"));
|
addons.add(new EphemeralAddon(Versions.parseVersion(mcVersion), "minecraft"));
|
||||||
} catch(ParseException e) {
|
} catch(ParseException e) {
|
||||||
@ -84,5 +101,20 @@ public abstract class LifecyclePlatform extends ModPlatform {
|
|||||||
return addons;
|
return addons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Registry<DimensionType> dimensionTypeRegistry() {
|
||||||
|
return DIMENSIONS.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Registry<Biome> biomeRegistry() {
|
||||||
|
return BIOMES.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry() {
|
||||||
|
return SETTINGS.get();
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract Collection<BaseAddon> getPlatformMods();
|
protected abstract Collection<BaseAddon> getPlatformMods();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package com.dfsek.terra.lifecycle.mixin;
|
package com.dfsek.terra.lifecycle.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.registry.RegistryEntryLookup;
|
||||||
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler;
|
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
||||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
import net.minecraft.world.gen.noise.NoiseConfig;
|
import net.minecraft.world.gen.noise.NoiseConfig;
|
||||||
@ -24,10 +25,10 @@ public class NoiseConfigMixin {
|
|||||||
@Final
|
@Final
|
||||||
private MultiNoiseSampler multiNoiseSampler;
|
private MultiNoiseSampler multiNoiseSampler;
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/util/registry/Registry;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,
|
private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup<DoublePerlinNoiseSampler.NoiseParameters> noiseParametersLookup, long seed,
|
||||||
Registry<DoublePerlinNoiseSampler.NoiseParameters> noiseRegistry, long seed, CallbackInfo ci) {
|
CallbackInfo ci) {
|
||||||
SeedHack.register(multiNoiseSampler, seed);
|
SeedHack.register(multiNoiseSampler, seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.dfsek.terra.lifecycle.mixin;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry.Reference;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(Reference.class)
|
||||||
|
public interface RegistryEntryReferenceInvoker<T> {
|
||||||
|
@Invoker("setValue")
|
||||||
|
void invokeSetValue(T value);
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package com.dfsek.terra.lifecycle.mixin;
|
package com.dfsek.terra.lifecycle.mixin;
|
||||||
|
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@ -9,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
import com.dfsek.terra.lifecycle.util.RegistryUtil;
|
import com.dfsek.terra.lifecycle.util.RegistryUtil;
|
||||||
|
|
||||||
|
|
||||||
@Mixin(Registry.class)
|
@Mixin(Registries.class)
|
||||||
public class RegistryMixin {
|
public class RegistryMixin {
|
||||||
@Inject(method = "<clinit>", at = @At("RETURN"))
|
@Inject(method = "<clinit>", at = @At("RETURN"))
|
||||||
private static void registerTerraGenerators(CallbackInfo ci) {
|
private static void registerTerraGenerators(CallbackInfo ci) {
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.dfsek.terra.lifecycle.mixin;
|
||||||
|
|
||||||
|
import com.dfsek.terra.lifecycle.util.RegistryHack;
|
||||||
|
|
||||||
|
import net.minecraft.registry.SimpleRegistry;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry.Reference;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(SimpleRegistry.class)
|
||||||
|
public class SimpleRegistryMixin<T> implements RegistryHack {
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Map<T, Reference<T>> valueToEntry;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void terra_bind() {
|
||||||
|
valueToEntry.forEach((value, entry) -> {
|
||||||
|
//noinspection unchecked
|
||||||
|
((RegistryEntryReferenceInvoker<T>) entry).invokeSetValue(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.dfsek.terra.lifecycle.mixin.lifecycle;
|
||||||
|
|
||||||
|
import com.dfsek.terra.lifecycle.LifecyclePlatform;
|
||||||
|
|
||||||
|
import com.dfsek.terra.lifecycle.util.RegistryHack;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import net.minecraft.registry.MutableRegistry;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.registry.RegistryLoader;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.WorldPreset;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
|
import org.checkerframework.checker.units.qual.C;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.dfsek.terra.lifecycle.util.LifecycleUtil;
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(RegistryLoader.class)
|
||||||
|
public class RegistryLoaderMixin {
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private static Logger LOGGER;
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "load(Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/registry/DynamicRegistryManager;Ljava/util/List;)" +
|
||||||
|
"Lnet/minecraft/registry/DynamicRegistryManager$Immutable;",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V",
|
||||||
|
ordinal = 1 // we want right after the first forEach
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private static void grabManager(List<Pair<MutableRegistry<?>, Object>> instance, Consumer<Pair<MutableRegistry<?>, Object>> consumer) {
|
||||||
|
instance.forEach(mutableRegistryObjectPair -> LOGGER.debug("{}: {} entries",
|
||||||
|
mutableRegistryObjectPair.getFirst().toString(),
|
||||||
|
mutableRegistryObjectPair.getFirst().size())
|
||||||
|
);
|
||||||
|
extractRegistry(instance, RegistryKeys.BIOME).ifPresent(
|
||||||
|
biomes -> { // this redirect triggers twice, second time only with dimension registry. don't try extraction second time
|
||||||
|
MutableRegistry<DimensionType> dimensionTypes = extractRegistry(instance, RegistryKeys.DIMENSION_TYPE).orElseThrow();
|
||||||
|
MutableRegistry<WorldPreset> worldPresets = extractRegistry(instance, RegistryKeys.WORLD_PRESET).orElseThrow();
|
||||||
|
MutableRegistry<ChunkGeneratorSettings> chunkGeneratorSettings = extractRegistry(instance,
|
||||||
|
RegistryKeys.CHUNK_GENERATOR_SETTINGS).orElseThrow();
|
||||||
|
|
||||||
|
LifecyclePlatform.setRegistries(biomes, dimensionTypes, chunkGeneratorSettings);
|
||||||
|
LifecycleUtil.initialize(biomes, worldPresets);
|
||||||
|
});
|
||||||
|
instance.forEach(consumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T> Optional<MutableRegistry<T>> extractRegistry(List<Pair<MutableRegistry<?>, Object>> instance,
|
||||||
|
RegistryKey<Registry<T>> key) {
|
||||||
|
List<? extends MutableRegistry<?>> matches = instance
|
||||||
|
.stream()
|
||||||
|
.map(Pair::getFirst)
|
||||||
|
.filter(r -> r.getKey().equals(key))
|
||||||
|
.toList();
|
||||||
|
if(matches.size() > 1) {
|
||||||
|
throw new IllegalStateException("Illegal number of registries returned: " + matches);
|
||||||
|
} else if(matches.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
MutableRegistry<T> registry = (MutableRegistry<T>) matches.get(0);
|
||||||
|
((RegistryHack) registry).terra_bind();
|
||||||
|
return Optional.of(registry);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.dfsek.terra.lifecycle.mixin.lifecycle;
|
||||||
|
|
||||||
|
import com.dfsek.terra.lifecycle.util.LifecycleUtil;
|
||||||
|
|
||||||
|
import com.dfsek.terra.mod.util.MinecraftUtil;
|
||||||
|
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.server.SaveLoading;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(SaveLoading.class)
|
||||||
|
public class SaveLoadingMixin {
|
||||||
|
@ModifyArg(
|
||||||
|
method = "method_42097(Lnet/minecraft/registry/DynamicRegistryManager$Immutable;" +
|
||||||
|
"Lnet/minecraft/server/SaveLoading$SaveApplierFactory;Lnet/minecraft/resource/LifecycledResourceManager;" +
|
||||||
|
"Lnet/minecraft/registry/CombinedDynamicRegistries;Lnet/minecraft/server/SaveLoading$LoadContext;" +
|
||||||
|
"Lnet/minecraft/server/DataPackContents;)Ljava/lang/Object;",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/server/DataPackContents;refresh(Lnet/minecraft/registry/DynamicRegistryManager;)V"
|
||||||
|
),
|
||||||
|
index = 0
|
||||||
|
)
|
||||||
|
private static DynamicRegistryManager grabManager(DynamicRegistryManager in) {
|
||||||
|
MinecraftUtil.registerFlora(in.get(RegistryKeys.BIOME));
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
}
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Terra.
|
|
||||||
*
|
|
||||||
* Terra is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Terra is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Terra. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dfsek.terra.lifecycle.mixin.lifecycle.client;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.RunArgs;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.dfsek.terra.lifecycle.util.LifecycleUtil;
|
|
||||||
|
|
||||||
|
|
||||||
@Mixin(MinecraftClient.class)
|
|
||||||
public class MinecraftClientMixin {
|
|
||||||
@Inject(method = "<init>", at = @At(value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/client/util/WindowProvider;createWindow" +
|
|
||||||
"(Lnet/minecraft/client/WindowSettings;Ljava/lang/String;Ljava/lang/String;)" +
|
|
||||||
"Lnet/minecraft/client/util/Window;",
|
|
||||||
// sorta arbitrary position, after mod init, before window opens
|
|
||||||
shift = At.Shift.BEFORE))
|
|
||||||
public void injectConstructor(RunArgs args, CallbackInfo callbackInfo) {
|
|
||||||
LifecycleUtil.initialize();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Terra.
|
|
||||||
*
|
|
||||||
* Terra is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Terra is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Terra. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dfsek.terra.lifecycle.mixin.lifecycle.server;
|
|
||||||
|
|
||||||
import net.minecraft.server.Main;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.dfsek.terra.lifecycle.util.LifecycleUtil;
|
|
||||||
|
|
||||||
|
|
||||||
@Mixin(Main.class)
|
|
||||||
public class ServerMainMixin {
|
|
||||||
@Inject(method = "main([Ljava/lang/String;)V",
|
|
||||||
at = @At(value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/resource/ResourcePackManager;<init>(Lnet/minecraft/resource/ResourceType;" +
|
|
||||||
"[Lnet/minecraft/resource/ResourcePackProvider;)V")
|
|
||||||
// after registry manager creation
|
|
||||||
)
|
|
||||||
private static void injectConstructor(String[] args, CallbackInfo ci) {
|
|
||||||
LifecycleUtil.initialize();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,10 @@
|
|||||||
package com.dfsek.terra.lifecycle.util;
|
package com.dfsek.terra.lifecycle.util;
|
||||||
|
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.BuiltinRegistries;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
|
||||||
import net.minecraft.village.VillagerType;
|
import net.minecraft.village.VillagerType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -29,13 +30,12 @@ public final class BiomeUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerBiomes() {
|
public static void registerBiomes(Registry<net.minecraft.world.biome.Biome> biomeRegistry) {
|
||||||
logger.info("Registering biomes...");
|
logger.info("Registering biomes...");
|
||||||
CommonPlatform.get().getConfigRegistry().forEach(pack -> { // Register all Terra biomes.
|
CommonPlatform.get().getConfigRegistry().forEach(pack -> { // Register all Terra biomes.
|
||||||
pack.getCheckedRegistry(Biome.class)
|
pack.getCheckedRegistry(Biome.class)
|
||||||
.forEach((id, biome) -> registerBiome(biome, pack, id));
|
.forEach((id, biome) -> registerBiome(biome, pack, id, biomeRegistry));
|
||||||
});
|
});
|
||||||
MinecraftUtil.registerFlora(BuiltinRegistries.BIOME);
|
|
||||||
logger.info("Terra biomes registered.");
|
logger.info("Terra biomes registered.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,36 +46,34 @@ public final class BiomeUtil {
|
|||||||
* @param pack The ConfigPack this biome belongs to.
|
* @param pack The ConfigPack this biome belongs to.
|
||||||
*/
|
*/
|
||||||
private static void registerBiome(Biome biome, ConfigPack pack,
|
private static void registerBiome(Biome biome, ConfigPack pack,
|
||||||
com.dfsek.terra.api.registry.key.RegistryKey id) {
|
com.dfsek.terra.api.registry.key.RegistryKey id,
|
||||||
Registry<net.minecraft.world.biome.Biome> registry = BuiltinRegistries.BIOME;
|
Registry<net.minecraft.world.biome.Biome> registry) {
|
||||||
RegistryKey<net.minecraft.world.biome.Biome> vanilla = ((ProtoPlatformBiome) biome.getPlatformBiome()).get(registry);
|
RegistryKey<net.minecraft.world.biome.Biome> vanilla = ((ProtoPlatformBiome) biome.getPlatformBiome()).get(registry);
|
||||||
|
|
||||||
|
|
||||||
if(pack.getContext().get(PreLoadCompatibilityOptions.class).useVanillaBiomes()) {
|
if(pack.getContext().get(PreLoadCompatibilityOptions.class).useVanillaBiomes()) {
|
||||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(vanilla);
|
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(registry.getEntry(vanilla).orElseThrow());
|
||||||
} else {
|
} else {
|
||||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||||
|
|
||||||
net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome, registry.get(vanilla),
|
net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome, Objects.requireNonNull(registry.get(vanilla)),
|
||||||
vanillaBiomeProperties);
|
vanillaBiomeProperties);
|
||||||
|
|
||||||
Identifier identifier = new Identifier("terra", MinecraftUtil.createBiomeID(pack, id));
|
Identifier identifier = new Identifier("terra", MinecraftUtil.createBiomeID(pack, id));
|
||||||
|
|
||||||
if(registry.containsId(identifier)) {
|
if(registry.containsId(identifier)) {
|
||||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(MinecraftUtil.getEntry(registry, identifier)
|
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(MinecraftUtil.getEntry(registry, identifier)
|
||||||
.orElseThrow()
|
|
||||||
.getKey()
|
|
||||||
.orElseThrow());
|
.orElseThrow());
|
||||||
} else {
|
} else {
|
||||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(BuiltinRegistries.add(registry,
|
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(Registry.registerReference(registry,
|
||||||
MinecraftUtil.registerKey(identifier)
|
MinecraftUtil.registerKey(identifier)
|
||||||
.getValue(),
|
.getValue(),
|
||||||
minecraftBiome).getKey().orElseThrow());
|
minecraftBiome));
|
||||||
}
|
}
|
||||||
|
|
||||||
Map villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap();
|
Map<RegistryKey<net.minecraft.world.biome.Biome>, VillagerType> villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap();
|
||||||
|
|
||||||
villagerMap.put(RegistryKey.of(Registry.BIOME_KEY, identifier),
|
villagerMap.put(RegistryKey.of(RegistryKeys.BIOME, identifier),
|
||||||
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
|
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
|
||||||
villagerMap.getOrDefault(vanilla, VillagerType.PLAINS)));
|
villagerMap.getOrDefault(vanilla, VillagerType.PLAINS)));
|
||||||
|
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
package com.dfsek.terra.lifecycle.util;
|
package com.dfsek.terra.lifecycle.util;
|
||||||
|
|
||||||
import net.minecraft.util.registry.BuiltinRegistries;
|
import com.dfsek.terra.lifecycle.LifecyclePlatform;
|
||||||
|
|
||||||
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.registry.MutableRegistry;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
|
||||||
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||||
import com.dfsek.terra.mod.CommonPlatform;
|
import com.dfsek.terra.mod.CommonPlatform;
|
||||||
|
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.gen.WorldPreset;
|
||||||
|
|
||||||
|
|
||||||
public final class LifecycleUtil {
|
public final class LifecycleUtil {
|
||||||
private LifecycleUtil() {
|
private LifecycleUtil() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize(MutableRegistry<Biome> biomeMutableRegistry, MutableRegistry<WorldPreset> worldPresetMutableRegistry) {
|
||||||
CommonPlatform.get().getEventManager().callEvent(new PlatformInitializationEvent());
|
CommonPlatform.get().getEventManager().callEvent(new PlatformInitializationEvent());
|
||||||
BiomeUtil.registerBiomes();
|
BiomeUtil.registerBiomes(biomeMutableRegistry);
|
||||||
CommonPlatform.get().registerWorldTypes((id, preset) -> BuiltinRegistries.add(BuiltinRegistries.WORLD_PRESET, id, preset));
|
CommonPlatform.get().registerWorldTypes((id, preset) -> Registry.register(worldPresetMutableRegistry, id, preset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.dfsek.terra.lifecycle.util;
|
||||||
|
|
||||||
|
public interface RegistryHack {
|
||||||
|
void terra_bind();
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
package com.dfsek.terra.lifecycle.util;
|
package com.dfsek.terra.lifecycle.util;
|
||||||
|
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
|
|
||||||
import com.dfsek.terra.mod.data.Codecs;
|
import com.dfsek.terra.mod.data.Codecs;
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ public final class RegistryUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER);
|
Registry.register(Registries.CHUNK_GENERATOR, new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER);
|
||||||
Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE);
|
Registry.register(Registries.BIOME_SOURCE, new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,23 @@
|
|||||||
{
|
{
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "com.dfsek.terra.lifecycle.mixin",
|
"package": "com.dfsek.terra.lifecycle.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"NoiseConfigMixin",
|
"NoiseConfigMixin",
|
||||||
"RegistryMixin",
|
"RegistryEntryReferenceInvoker",
|
||||||
"lifecycle.MinecraftServerMixin"
|
"RegistryMixin",
|
||||||
],
|
"SimpleRegistryMixin",
|
||||||
"client": [
|
"lifecycle.MinecraftServerMixin",
|
||||||
"lifecycle.client.MinecraftClientMixin"
|
"lifecycle.RegistryLoaderMixin",
|
||||||
],
|
"lifecycle.SaveLoadingMixin"
|
||||||
"server": [
|
],
|
||||||
"lifecycle.server.ServerMainMixin"
|
"client": [
|
||||||
],
|
],
|
||||||
"injectors": {
|
"server": [
|
||||||
"defaultRequire": 1
|
],
|
||||||
},
|
"injectors": {
|
||||||
"refmap": "terra.lifecycle.refmap.json"
|
"defaultRequire": 1
|
||||||
|
},
|
||||||
|
"refmap": "terra.lifecycle.refmap.json"
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user