diff --git a/build.gradle.kts b/build.gradle.kts index 20122663d..b91c23fa7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,8 @@ preRelease(true) -versionProjects(":common:api", version("6.2.1")) -versionProjects(":common:implementation", version("6.2.1")) -versionProjects(":platforms", version("6.2.1")) +versionProjects(":common:api", version("6.3.0")) +versionProjects(":common:implementation", version("6.3.0")) +versionProjects(":platforms", version("6.3.0")) allprojects { diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 09b2244af..ee68395b9 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -4,7 +4,7 @@ object Versions { const val paralithic = "0.7.0" 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 log4j_slf4j_impl = "2.14.1" @@ -19,19 +19,19 @@ object Versions { object Fabric { 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 { - const val quiltLoader = "0.17.0" - const val fabricApi = "2.0.0-beta.4+0.57.0-1.19" + const val quiltLoader = "0.17.8" + const val fabricApi = "5.0.0-alpha.5+0.68.1-1.19.3" } object Mod { const val mixin = "0.11.2+mixin.0.8.5" - const val minecraft = "1.19" - const val yarn = "$minecraft+build.1" + const val minecraft = "1.19.3" + const val yarn = "$minecraft+build.3" const val fabricLoader = "0.14.2" const val architecuryLoom = "0.12.0.290" @@ -43,16 +43,16 @@ object Versions { } object Forge { - const val forge = "${Mod.minecraft}-41.0.63" + const val forge = "${Mod.minecraft}-44.0.18" const val burningwave = "12.53.0" } object Bukkit { const val paper = "1.18.2-R0.1-SNAPSHOT" 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 paperDevBundle = "1.19.2-R0.1-SNAPSHOT" + const val paperDevBundle = "1.19.3-R0.1-SNAPSHOT" } object Sponge { diff --git a/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/PipelineBiomeProvider.java b/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/PipelineBiomeProvider.java index 9748741a8..6c5b6f289 100644 --- a/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/PipelineBiomeProvider.java +++ b/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/PipelineBiomeProvider.java @@ -11,6 +11,7 @@ import net.jafama.FastMath; import java.util.Comparator; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import java.util.stream.StreamSupport; @@ -97,6 +98,11 @@ public class PipelineBiomeProvider implements BiomeProvider { return biomes; } + @Override + public Optional getBaseBiome(int x, int z, long seed) { + return Optional.of(getBiome(x, z, seed)); + } + @Override public Column getColumn(int x, int z, long seed, int min, int max) { return new BiomePipelineColumn(this, min, max, x, z, seed); diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java index 06450b613..ce1ec9650 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java @@ -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.BiomeNoiseProperties; 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.SlantLayer; +import com.dfsek.terra.addons.chunkgenerator.config.palette.slant.SlantLayerTemplate; 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.api.Platform; import com.dfsek.terra.api.addon.BaseAddon; @@ -36,15 +37,20 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer { @Override public void initialize() { - PropertyKey paletteInfoPropertyKey = Context.create(PaletteInfo.class); + PropertyKey paletteInfoPropertyKey = Context.create(BiomePaletteInfo.class); PropertyKey noisePropertiesPropertyKey = Context.create(BiomeNoiseProperties.class); platform.getEventManager() .getHandler(FunctionalEventHandler.class) .register(addon, ConfigPackPreLoadEvent.class) .priority(1000) .then(event -> { + + event.getPack().applyLoader(SlantHolder.CalculationMethod.class, + (type, o, loader, depthTracker) -> SlantHolder.CalculationMethod.valueOf((String) o)); + NoiseChunkGeneratorPackConfigTemplate config = event.loadTemplate(new NoiseChunkGeneratorPackConfigTemplate()); - + event.getPack().getContext().put(config); + event.getPack() .getOrCreateRegistry(ChunkGeneratorProvider.class) .register(addon.key("NOISE_3D"), @@ -53,7 +59,7 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer { config.getVerticalRes(), noisePropertiesPropertyKey, paletteInfoPropertyKey)); event.getPack() - .applyLoader(SlantLayer.class, SlantLayer::new); + .applyLoader(SlantHolder.Layer.class, SlantLayerTemplate::new); }) .failThrough(); @@ -62,8 +68,10 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer { .register(addon, ConfigurationLoadEvent.class) .then(event -> { if(event.is(Biome.class)) { + NoiseChunkGeneratorPackConfigTemplate config = event.getPack().getContext().get(NoiseChunkGeneratorPackConfigTemplate.class); + 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.load(new BiomeNoiseConfigTemplate()).get()); } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java index e636ae400..db9922980 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java @@ -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.Value; +import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; 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") @Default private @Meta int elevationBlend = 4; @@ -20,6 +22,10 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate { @Default private @Meta int verticalRes = 2; + @Value("slant.calculation-method") + @Default + private SlantHolder.@Meta CalculationMethod slantCalculationMethod = SlantHolder.CalculationMethod.Derivative; + public int getElevationBlend() { return elevationBlend; } @@ -31,4 +37,8 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate { public int getVerticalRes() { return verticalRes; } + + public SlantHolder.CalculationMethod getSlantCalculationMethod() { + return slantCalculationMethod; + } } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java index f1f0f804a..f872794c9 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java @@ -15,25 +15,23 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import java.util.Collections; import java.util.List; 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.PaletteHolderBuilder; -import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder; +import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo; +import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.world.chunk.generation.util.Palette; -public class BiomePaletteTemplate implements ObjectTemplate { +public class BiomePaletteTemplate implements ObjectTemplate { private final Platform platform; @Value("slant") @Default @Description("The slant palettes to use in this biome.") - private @Meta List<@Meta SlantLayer> slant = Collections.emptyList(); + private @Meta List slantLayers = Collections.emptyList(); @Value("slant-depth") @Default @@ -63,27 +61,16 @@ public class BiomePaletteTemplate implements ObjectTemplate { @Default 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 - public PaletteInfo get() { - PaletteHolderBuilder builder = new PaletteHolderBuilder(); - for(Map layer : palettes) { - for(Entry entry : layer.entrySet()) { - builder.add(entry.getValue(), entry.getKey()); - } - } - - TreeMap 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); + public BiomePaletteInfo get() { + return new BiomePaletteInfo(PaletteHolder.of(palettes), SlantHolder.of(slantLayers, slantDepth, slantCalculationMethod), + oceanPalette, seaLevel, updatePalette); } } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PaletteInfo.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PaletteInfo.java deleted file mode 100644 index caf3c4802..000000000 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PaletteInfo.java +++ /dev/null @@ -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 { -} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SlantLayer.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SlantLayer.java deleted file mode 100644 index d63cbbb46..000000000 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SlantLayer.java +++ /dev/null @@ -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 { - @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 layer : palettes) { - for(Entry entry : layer.entrySet()) { - builder.add(entry.getValue(), entry.getKey()); - } - } - - return builder.build(); - } -} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/slant/SlantLayerTemplate.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/slant/SlantLayerTemplate.java new file mode 100644 index 000000000..5a4fd646d --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/slant/SlantLayerTemplate.java @@ -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 { + + @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); + } +} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java index fcb8d3fe2..f0f6de8e3 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java @@ -12,7 +12,7 @@ import net.jafama.FastMath; import org.jetbrains.annotations.NotNull; 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.interpolation.LazilyEvaluatedInterpolator; 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 carverVerticalResolution; - private final PropertyKey paletteInfoPropertyKey; + private final PropertyKey paletteInfoPropertyKey; private final PropertyKey noisePropertiesKey; public NoiseChunkGenerator3D(ConfigPack pack, Platform platform, int elevationBlend, int carverHorizontalResolution, int carverVerticalResolution, PropertyKey noisePropertiesKey, - PropertyKey paletteInfoPropertyKey) { + PropertyKey paletteInfoPropertyKey) { this.platform = platform; this.air = platform.getWorldHandle().air(); this.carverHorizontalResolution = carverHorizontalResolution; @@ -97,7 +97,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) { Biome biome = biomeColumn.get(y); - PaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey); + BiomePaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey); int sea = paletteInfo.seaLevel(); Palette seaPalette = paletteInfo.ocean(); @@ -131,7 +131,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { Biome biome = biomeProvider.getBiome(x, y, z, world.getSeed()); 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 fdZ = FastMath.floorMod(z, 16); diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java index d649cf4f2..ebeabaf23 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java @@ -7,40 +7,23 @@ 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.palette.SlantHolder; +import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; import com.dfsek.terra.api.world.chunk.generation.util.Palette; 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) { - SlantHolder slant = paletteInfo.slantHolder(); - if(!slant.isEmpty() && depth <= paletteInfo.maxSlantDepth()) { - double slope = derivative(sampler, x, y, z); - if(slope > slant.getMinSlope()) { - return slant.getPalette(slope).getPalette(y); + public static Palette getPalette(int x, int y, int z, Sampler3D sampler, BiomePaletteInfo paletteInfo, int depth) { + SlantHolder slantHolder = paletteInfo.slantHolder(); + if(slantHolder.isAboveDepth(depth)) { + double slant = slantHolder.calculateSlant(sampler, x, y, z); + if(slantHolder.isInSlantThreshold(slant)) { + return slantHolder.getPalette(slant).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))); - } } \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/BiomePaletteInfo.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/BiomePaletteInfo.java new file mode 100644 index 000000000..a75eeef5f --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/BiomePaletteInfo.java @@ -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 { +} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/PaletteHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/PaletteHolder.java index 2451d063c..fcd48f4a8 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/PaletteHolder.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/PaletteHolder.java @@ -7,6 +7,13 @@ 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; @@ -27,4 +34,43 @@ public class PaletteHolder { : palettes[palettes.length - 1] : palettes[0]; } + + public static PaletteHolder of(List> palettes) { + PaletteHolderBuilder builder = new PaletteHolderBuilder(); + for(Map layer : palettes) { + for(Entry entry : layer.entrySet()) { + builder.add(entry.getValue(), entry.getKey()); + } + } + return builder.build(); + } + + private static class PaletteHolderBuilder { + private final TreeMap 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 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); + } + } } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/PaletteHolderBuilder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/PaletteHolderBuilder.java deleted file mode 100644 index 693939c75..000000000 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/PaletteHolderBuilder.java +++ /dev/null @@ -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 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 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); - } -} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SlantHolder.java deleted file mode 100644 index 6ceacee24..000000000 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SlantHolder.java +++ /dev/null @@ -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 layers; - private final double minSlope; - - private SlantHolder(TreeMap layers, double minSlope) { - this.layers = layers; - this.minSlope = minSlope; - } - - public static SlantHolder of(TreeMap layers, double minSlope) { - if(layers.size() == 1) { - Entry 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 of(double v, PaletteHolder layer) { - TreeMap map = new TreeMap<>(); - map.put(v, layer); - return map; - } - - @Override - public PaletteHolder getPalette(double slope) { - return layers; - } - } -} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/MultipleSlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/MultipleSlantHolder.java new file mode 100644 index 000000000..928edb2c2 --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/MultipleSlantHolder.java @@ -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 layers; + private final double slantThreshold; + + MultipleSlantHolder(List slant, int slantDepth, CalculationMethod calculationMethod) { + super(slantDepth, calculationMethod); + NavigableMap layers = new TreeMap<>(slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette))); + Stream 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(); + } +} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SingleSlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SingleSlantHolder.java new file mode 100644 index 000000000..fdc9b27cb --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SingleSlantHolder.java @@ -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(); + } +} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolder.java new file mode 100644 index 000000000..e70670977 --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolder.java @@ -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 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"); + } + }; +} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolderImpl.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolderImpl.java new file mode 100644 index 000000000..e7261b88e --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolderImpl.java @@ -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() + ); + } +} diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/config/BufferedImageLoader.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/config/BufferedImageLoader.java new file mode 100644 index 000000000..c2395d114 --- /dev/null +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/config/BufferedImageLoader.java @@ -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 . + */ + +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 { + 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 map) implements Properties { + } +} diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java index 3bcc1682e..611539c41 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java @@ -32,6 +32,7 @@ import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; 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.ZIPLoader; 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.MetaMapPreprocessor; import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor; @@ -280,7 +282,8 @@ public class ConfigPackImpl implements ConfigPack { @Override 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); shortcuts.forEach(registry::registerLoader); // overwrite with delegated shortcuts if present } diff --git a/platforms/bukkit/build.gradle.kts b/platforms/bukkit/build.gradle.kts index f099cb4e3..d3895ad52 100644 --- a/platforms/bukkit/build.gradle.kts +++ b/platforms/bukkit/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { shaded(project(":platforms:bukkit:common")) 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_R2", configuration = "reobf")) shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) } diff --git a/platforms/bukkit/nms/v1_19_R1/build.gradle.kts b/platforms/bukkit/nms/v1_19_R1/build.gradle.kts index 96f9038d8..b38ee0e04 100644 --- a/platforms/bukkit/nms/v1_19_R1/build.gradle.kts +++ b/platforms/bukkit/nms/v1_19_R1/build.gradle.kts @@ -6,7 +6,7 @@ repositories { dependencies { 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") } diff --git a/platforms/bukkit/nms/v1_19_R2/build.gradle.kts b/platforms/bukkit/nms/v1_19_R2/build.gradle.kts new file mode 100644 index 000000000..96f9038d8 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/build.gradle.kts @@ -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") + } +} \ No newline at end of file diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/AwfulBukkitHacks.java new file mode 100644 index 000000000..f7da9c45d --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/AwfulBukkitHacks.java @@ -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> terraBiomeMap = new HashMap<>(); + + public static void registerBiomes(ConfigRegistry configRegistry) { + try { + LOGGER.info("Hacking biome registry..."); + WritableRegistry biomeRegistry = (WritableRegistry) 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 delegateKey = ResourceKey.create( + Registries.BIOME, + new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key)) + ); + + Reference 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, List>> 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); + } + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInfo.java new file mode 100644 index 000000000..639c9eaed --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInfo.java @@ -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 biomeKey) implements Properties { +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInjector.java new file mode 100644 index 000000000..20a426949 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInjector.java @@ -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 Optional> getEntry(Registry 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); + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeProvider.java new file mode 100644 index 000000000..e7b09426d --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeProvider.java @@ -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 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 codec() { + return BiomeSource.CODEC; + } + + @Override + public @NotNull Holder 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()); + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSChunkGeneratorDelegate.java new file mode 100644 index 000000000..5faa4ba4b --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSChunkGeneratorDelegate.java @@ -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 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 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 text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) { + + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInitializer.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInitializer.java new file mode 100644 index 000000000..05814cfd4 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInitializer.java @@ -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()); + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInjectListener.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInjectListener.java new file mode 100644 index 000000000..015de732e --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInjectListener.java @@ -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 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(); + } + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSWorldProperties.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSWorldProperties.java new file mode 100644 index 000000000..cee2284d0 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSWorldProperties.java @@ -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(); + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/Reflection.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/Reflection.java new file mode 100644 index 000000000..c65df8ca1 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/Reflection.java @@ -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") + void invokeBindValue(Reference instance, T value); + } +} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/RegistryFetcher.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/RegistryFetcher.java new file mode 100644 index 000000000..f0c776f48 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/RegistryFetcher.java @@ -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 Registry getRegistry(ResourceKey> key) { + CraftServer craftserver = (CraftServer) Bukkit.getServer(); + DedicatedServer dedicatedserver = craftserver.getServer(); + return dedicatedserver + .registryAccess() + .registryOrThrow(key); + } + + public static Registry biomeRegistry() { + return getRegistry(Registries.BIOME); + } +} diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeEntryPoint.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeEntryPoint.java index b342e5a11..36446a08d 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeEntryPoint.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgeEntryPoint.java @@ -17,8 +17,9 @@ package com.dfsek.terra.forge; +import net.minecraft.registry.RegistryKeys; import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; +import net.minecraft.registry.Registry; import net.minecraft.world.biome.Biome; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; @@ -71,12 +72,12 @@ public class ForgeEntryPoint { public void registerBiomes(RegisterEvent event) { 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(Registry.WORLD_PRESET_KEY, + event.register(RegistryKeys.WORLD_PRESET, 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)); - 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)); } } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgePlatform.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgePlatform.java index 2d8b51c9a..5cf97c381 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgePlatform.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/ForgePlatform.java @@ -21,8 +21,15 @@ import ca.solostudios.strata.Versions; import ca.solostudios.strata.parser.tokenizer.ParseException; import ca.solostudios.strata.version.Version; 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.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.registries.ForgeRegistries; import net.minecraftforge.server.ServerLifecycleHooks; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; @@ -86,7 +93,7 @@ public class ForgePlatform extends ModPlatform { super.platformAddon().forEach(addons::add); - String mcVersion = MinecraftVersion.CURRENT.getReleaseTarget(); + String mcVersion = MinecraftVersion.CURRENT.getName(); try { addons.add(new EphemeralAddon(Versions.parseVersion(mcVersion), "minecraft")); } catch(ParseException e) { @@ -122,4 +129,19 @@ public class ForgePlatform extends ModPlatform { public BaseAddon getPlatformAddon() { return new ForgeAddon(this); } + + @Override + public Registry dimensionTypeRegistry() { + return null; + } + + @Override + public Registry biomeRegistry() { + return null; + } + + @Override + public Registry chunkGeneratorSettingsRegistry() { + return null; + } } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/lifecycle/NoiseConfigMixin.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/lifecycle/NoiseConfigMixin.java index 1bdffca2e..8762d51ed 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/lifecycle/NoiseConfigMixin.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/mixin/lifecycle/NoiseConfigMixin.java @@ -1,19 +1,26 @@ 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.NoiseHypercube; +import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; import net.minecraft.world.gen.densityfunction.DensityFunction; import net.minecraft.world.gen.noise.NoiseConfig; 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 com.dfsek.terra.mod.util.SeedHack; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + /** * Hack to map noise sampler to seeds @@ -22,23 +29,12 @@ import com.dfsek.terra.mod.util.SeedHack; public class NoiseConfigMixin { @Shadow @Final - private long legacyWorldSeed; + private MultiNoiseSampler multiNoiseSampler; - @Redirect(method = "(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/util/registry/Registry;J)V", - at = @At(value = "NEW", - target = "(Lnet/minecraft/world/gen/densityfunction/DensityFunction;" + - "Lnet/minecraft/world/gen/densityfunction/DensityFunction;" + - "Lnet/minecraft/world/gen/densityfunction/DensityFunction;" + - "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 list) { - MultiNoiseSampler sampler = new MultiNoiseSampler(densityFunction, densityFunction2, densityFunction3, densityFunction4, - densityFunction5, densityFunction6, list); - SeedHack.register(sampler, legacyWorldSeed); - return sampler; + @Inject(method = "(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/registry/RegistryEntryLookup;J)V", + at = @At("TAIL")) + private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup noiseParametersLookup, long seed, + CallbackInfo ci) { + SeedHack.register(multiNoiseSampler, seed); } } diff --git a/platforms/forge/src/main/java/com/dfsek/terra/forge/util/BiomeUtil.java b/platforms/forge/src/main/java/com/dfsek/terra/forge/util/BiomeUtil.java index 177a63f8e..9c14f7d1a 100644 --- a/platforms/forge/src/main/java/com/dfsek/terra/forge/util/BiomeUtil.java +++ b/platforms/forge/src/main/java/com/dfsek/terra/forge/util/BiomeUtil.java @@ -1,9 +1,9 @@ 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.registry.BuiltinRegistries; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryKey; import net.minecraft.village.VillagerType; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegisterEvent.RegisterHelper; @@ -39,7 +39,6 @@ public final class BiomeUtil { pack.getCheckedRegistry(Biome.class) .forEach((id, biome) -> registerBiome(biome, pack, id, helper)); }); - MinecraftUtil.registerFlora(BuiltinRegistries.BIOME); logger.info("Terra biomes registered."); } @@ -52,7 +51,8 @@ public final class BiomeUtil { private static void registerBiome(Biome biome, ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey id, RegisterHelper helper) { - RegistryKey vanilla = ((ProtoPlatformBiome) biome.getPlatformBiome()).get(BuiltinRegistries.BIOME); + RegistryEntry + vanilla = ForgeRegistries.BIOMES.getHolder(((ProtoPlatformBiome) biome.getPlatformBiome()).getHandle()).orElseThrow(); if(pack.getContext().get(PreLoadCompatibilityOptions.class).useVanillaBiomes()) { @@ -61,7 +61,7 @@ public final class BiomeUtil { VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome, - ForgeRegistries.BIOMES.getDelegateOrThrow(vanilla) + ForgeRegistries.BIOMES.getDelegateOrThrow(vanilla.getKey().orElseThrow()) .value(), vanillaBiomeProperties); @@ -69,24 +69,20 @@ public final class BiomeUtil { if(ForgeRegistries.BIOMES.containsKey(identifier)) { ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(ForgeRegistries.BIOMES.getHolder(identifier) - .orElseThrow() - .getKey() .orElseThrow()); } else { helper.register(MinecraftUtil.registerKey(identifier).getValue(), minecraftBiome); ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(ForgeRegistries.BIOMES.getHolder(identifier) - .orElseThrow() - .getKey() .orElseThrow()); } - Map villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap(); + Map, VillagerType> villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap(); - villagerMap.put(RegistryKey.of(Registry.BIOME_KEY, identifier), + villagerMap.put(RegistryKey.of(RegistryKeys.BIOME, identifier), 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); } } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java index 4a6efa188..9f26738b1 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java @@ -5,21 +5,26 @@ import com.dfsek.tectonic.api.depth.DepthTracker; import com.dfsek.tectonic.api.exception.LoadException; import net.minecraft.entity.EntityType; 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.sound.BiomeAdditionsSound; import net.minecraft.sound.BiomeMoodSound; import net.minecraft.sound.MusicSound; import net.minecraft.sound.SoundEvent; import net.minecraft.util.Identifier; -import net.minecraft.util.registry.BuiltinRegistries; import net.minecraft.village.VillagerType; +import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome.Precipitation; import net.minecraft.world.biome.Biome.TemperatureModifier; import net.minecraft.world.biome.BiomeEffects.GrassColorModifier; import net.minecraft.world.biome.BiomeParticleConfig; import net.minecraft.world.biome.SpawnSettings; import net.minecraft.world.biome.SpawnSettings.SpawnEntry; +import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.gen.WorldPreset; +import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -57,7 +62,7 @@ public abstract class ModPlatform extends AbstractPlatform { public void registerWorldTypes(BiConsumer registerFunction) { getRawConfigRegistry() - .forEach(pack -> PresetUtil.createDefault(pack).apply(registerFunction)); + .forEach(pack -> PresetUtil.createDefault(pack, this).apply(registerFunction)); } @Override @@ -94,7 +99,7 @@ public abstract class ModPlatform extends AbstractPlatform { private ProtoPlatformBiome parseBiome(String id, DepthTracker tracker) throws LoadException { 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); } @@ -105,6 +110,10 @@ public abstract class ModPlatform extends AbstractPlatform { protected abstract BaseAddon getPlatformAddon(); + public abstract Registry dimensionTypeRegistry(); + public abstract Registry biomeRegistry(); + public abstract Registry chunkGeneratorSettingsRegistry(); + @Override public @NotNull WorldHandle getWorldHandle() { return worldHandle; diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeAdditionsSoundTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeAdditionsSoundTemplate.java index e9d4a2038..4a66cf6e5 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeAdditionsSoundTemplate.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeAdditionsSoundTemplate.java @@ -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.Value; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.minecraft.registry.Registries; import net.minecraft.sound.BiomeAdditionsSound; import net.minecraft.sound.SoundEvent; @@ -21,7 +22,7 @@ public class BiomeAdditionsSoundTemplate implements ObjectTemplate { if(sound == null || soundCultivationTicks == null || soundSpawnRange == null || soundExtraDistance == null) { return null; } else { - return new BiomeMoodSound(sound, soundCultivationTicks, soundSpawnRange, soundExtraDistance); + return new BiomeMoodSound(Registries.SOUND_EVENT.getEntry(sound), soundCultivationTicks, soundSpawnRange, soundExtraDistance); } } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java index 538a80870..a48ec5c54 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java @@ -6,6 +6,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.command.argument.ParticleEffectArgumentType; +import net.minecraft.registry.Registries; import net.minecraft.world.biome.BiomeParticleConfig; @@ -25,7 +26,7 @@ public class BiomeParticleConfigTemplate implements ObjectTemplate> { @@ -15,6 +16,6 @@ public class EntityTypeTemplate implements ObjectTemplate> { @Override public EntityType get() { - return Registry.ENTITY_TYPE.get(id); + return Registries.ENTITY_TYPE.get(id); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/MusicSoundTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/MusicSoundTemplate.java index 17745a9af..b9f563621 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/MusicSoundTemplate.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/MusicSoundTemplate.java @@ -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.Value; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.minecraft.registry.Registries; import net.minecraft.sound.MusicSound; import net.minecraft.sound.SoundEvent; @@ -29,7 +30,7 @@ public class MusicSoundTemplate implements ObjectTemplate { if(sound == null || minDelay == null || maxDelay == null || replaceCurrentMusic == null) { return null; } else { - return new MusicSound(sound, minDelay, maxDelay, replaceCurrentMusic); + return new MusicSound(Registries.SOUND_EVENT.getEntry(sound), minDelay, maxDelay, replaceCurrentMusic); } } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/ProtoPlatformBiome.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/ProtoPlatformBiome.java index f9524ef58..11bbae507 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/ProtoPlatformBiome.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/ProtoPlatformBiome.java @@ -17,9 +17,10 @@ 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.registry.Registry; -import net.minecraft.util.registry.RegistryKey; +import net.minecraft.registry.Registry; import net.minecraft.world.biome.Biome; import java.util.Objects; @@ -31,7 +32,7 @@ import com.dfsek.terra.mod.util.MinecraftUtil; public class ProtoPlatformBiome implements PlatformBiome { private final Identifier identifier; - private RegistryKey delegate; + private RegistryEntry delegate; public ProtoPlatformBiome(Identifier identifier) { this.identifier = identifier; @@ -42,15 +43,15 @@ public class ProtoPlatformBiome implements PlatformBiome { } @Override - public Object getHandle() { + public Identifier getHandle() { return identifier; } - public RegistryKey getDelegate() { + public RegistryEntry getDelegate() { return delegate; } - public void setDelegate(RegistryKey delegate) { + public void setDelegate(RegistryEntry delegate) { this.delegate = Objects.requireNonNull(delegate); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SoundEventTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SoundEventTemplate.java index 5e87dc21a..b5b7fe079 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SoundEventTemplate.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SoundEventTemplate.java @@ -21,9 +21,9 @@ public class SoundEventTemplate implements ObjectTemplate { if(id == null) { return null; } else if(distanceToTravel == null) { - return new SoundEvent(id); + return SoundEvent.of(id); } else { - return new SoundEvent(id, distanceToTravel); + return SoundEvent.of(id, distanceToTravel); } } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/VillagerTypeTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/VillagerTypeTemplate.java index f8cce4832..9aaf3362b 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/VillagerTypeTemplate.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/VillagerTypeTemplate.java @@ -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.Value; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; +import net.minecraft.registry.Registry; import net.minecraft.village.VillagerType; @@ -15,6 +16,6 @@ public class VillagerTypeTemplate implements ObjectTemplate { @Override public VillagerType get() { - return Registry.VILLAGER_TYPE.get(id); + return Registries.VILLAGER_TYPE.get(id); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java index 5f5dd615a..890e3e2b5 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java @@ -2,8 +2,8 @@ package com.dfsek.terra.mod.data; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.util.dynamic.RegistryOps; -import net.minecraft.util.registry.Registry; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryOps; import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; import com.dfsek.terra.api.config.ConfigPack; @@ -35,10 +35,7 @@ public final class Codecs { id))))); public static final Codec TERRA_BIOME_SOURCE = RecordCodecBuilder - .create(instance -> instance.group(RegistryOps.createRegistryCodec(Registry.BIOME_KEY) - .fieldOf("biome_registry") - .stable() - .forGetter(TerraBiomeSource::getBiomeRegistry), + .create(instance -> instance.group( CONFIG_PACK.fieldOf("pack") .stable() .forGetter(TerraBiomeSource::getPack)) @@ -47,10 +44,6 @@ public final class Codecs { public static final Codec MINECRAFT_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder .create( instance -> instance.group( - RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY) - .fieldOf("structure_registry") - .stable() - .forGetter(MinecraftChunkGeneratorWrapper::getNoiseRegistry), TERRA_BIOME_SOURCE.fieldOf("biome_source") .stable() .forGetter(MinecraftChunkGeneratorWrapper::getBiomeSource), @@ -60,6 +53,7 @@ public final class Codecs { ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings") .stable() .forGetter(MinecraftChunkGeneratorWrapper::getSettings) - ).apply(instance, instance.stable(MinecraftChunkGeneratorWrapper::new)) + ).apply(instance, instance.stable( + MinecraftChunkGeneratorWrapper::new)) ); } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java index 5742120d6..75fd4f498 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java @@ -17,9 +17,12 @@ package com.dfsek.terra.mod.generation; +import com.dfsek.terra.mod.util.SeedHack; + import com.mojang.serialization.Codec; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.structure.StructureSet; import net.minecraft.util.Util; 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.ChunkRandom; import net.minecraft.util.math.random.RandomSeed; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryEntry; +import net.minecraft.registry.Registry; import net.minecraft.world.ChunkRegion; import net.minecraft.world.HeightLimitView; 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 final TerraBiomeSource biomeSource; - private final Registry noiseRegistry; private final RegistryEntry settings; private ChunkGenerator delegate; private ConfigPack pack; - public MinecraftChunkGeneratorWrapper(Registry noiseRegistry, TerraBiomeSource biomeSource, ConfigPack configPack, + public MinecraftChunkGeneratorWrapper(TerraBiomeSource biomeSource, ConfigPack configPack, RegistryEntry settingsSupplier) { - super(noiseRegistry, Optional.empty(), biomeSource); - this.noiseRegistry = noiseRegistry; + super(biomeSource); this.pack = configPack; this.settings = settingsSupplier; @@ -88,10 +88,6 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun this.biomeSource = biomeSource; } - public Registry getNoiseRegistry() { - return noiseRegistry; - } - @Override protected Codec getCodec() { 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, PreLoadCompatibilityOptions compatibilityOptions) { - StructureWeightSampler structureWeightSampler = StructureWeightSampler.method_42695(structureAccessor, chunk.getPos()); + StructureWeightSampler structureWeightSampler = StructureWeightSampler.createStructureWeightSampler(structureAccessor, chunk.getPos()); double threshold = compatibilityOptions.getBeardThreshold(); double airThreshold = compatibilityOptions.getAirThreshold(); int xi = chunk.getPos().x << 4; @@ -185,7 +181,7 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun @Override 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(); int min = height.getBottomY(); for(int y = height.getTopY() - 1; y >= min; y--) { @@ -199,7 +195,7 @@ public class MinecraftChunkGeneratorWrapper extends net.minecraft.world.gen.chun @Override public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height, NoiseConfig noiseConfig) { 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(); for(int y = height.getTopY() - 1; y >= height.getBottomY(); y--) { array[y - height.getBottomY()] = (BlockState) delegate.getBlock(properties, x, y, z, biomeProvider); diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java index 5730cee80..7ab085780 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java @@ -18,8 +18,9 @@ package com.dfsek.terra.mod.generation; import com.mojang.serialization.Codec; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryEntry; +import net.minecraft.registry.Registry; +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.util.MultiNoiseUtil.MultiNoiseSampler; import org.slf4j.Logger; @@ -37,16 +38,14 @@ import com.dfsek.terra.mod.util.SeedHack; public class TerraBiomeSource extends BiomeSource { private static final Logger LOGGER = LoggerFactory.getLogger(TerraBiomeSource.class); - private final Registry biomeRegistry; private ConfigPack pack; - public TerraBiomeSource(Registry biomes, ConfigPack pack) { + public TerraBiomeSource(ConfigPack pack) { super(StreamSupport .stream(pack.getBiomeProvider() .getBiomes() .spliterator(), false) - .map(b -> biomes.getOrCreateEntry(((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate()))); - this.biomeRegistry = biomes; + .map(b -> ((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate())); this.pack = pack; LOGGER.debug("Biomes: " + getBiomes()); @@ -58,23 +57,17 @@ public class TerraBiomeSource extends BiomeSource { } @Override - public RegistryEntry getBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseSampler noiseSampler) { - return biomeRegistry - .entryOf(((ProtoPlatformBiome) pack + public RegistryEntry getBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseSampler noiseSampler) { + return ((ProtoPlatformBiome) pack .getBiomeProvider() .getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, SeedHack.getSeed(noiseSampler)) - .getPlatformBiome()).getDelegate() - ); + .getPlatformBiome()).getDelegate(); } public BiomeProvider getProvider() { return pack.getBiomeProvider(); } - public Registry getBiomeRegistry() { - return biomeRegistry; - } - public ConfigPack getPack() { return pack; } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java index 5d26b6c43..66582857a 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java @@ -21,8 +21,11 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.command.CommandRegistryAccess; 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.registry.Registry; +import net.minecraft.registry.Registry; import java.util.Set; import java.util.stream.Collectors; @@ -38,8 +41,12 @@ public class MinecraftItemHandle implements ItemHandle { @Override public Item createItem(String data) { try { - return (Item) new ItemStackArgumentType(new CommandRegistryAccess( - CommonPlatform.get().getServer().getRegistryManager())).parse(new StringReader(data)).getItem(); + return (Item) new ItemStackArgumentType(new CommandRegistryAccess() { + @Override + public RegistryWrapper createWrapper(RegistryKey> registryRef) { + return CommonPlatform.get().getServer().getRegistryManager().getWrapperOrThrow(registryRef); + } + }).parse(new StringReader(data)).getItem(); } catch(CommandSyntaxException e) { throw new IllegalArgumentException("Invalid item data \"" + data + "\"", e); } @@ -47,11 +54,11 @@ public class MinecraftItemHandle implements ItemHandle { @Override public Enchantment getEnchantment(String id) { - return (Enchantment) (Registry.ENCHANTMENT.get(Identifier.tryParse(id))); + return (Enchantment) (Registries.ENCHANTMENT.get(Identifier.tryParse(id))); } @Override public Set getEnchantments() { - return Registry.ENCHANTMENT.stream().map(enchantment -> (Enchantment) enchantment).collect(Collectors.toSet()); + return Registries.ENCHANTMENT.stream().map(enchantment -> (Enchantment) enchantment).collect(Collectors.toSet()); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java index 13eef4b2d..aabc38471 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java @@ -20,8 +20,9 @@ package com.dfsek.terra.mod.handle; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.block.Blocks; import net.minecraft.command.argument.BlockArgumentParser; +import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; +import net.minecraft.registry.Registry; import org.jetbrains.annotations.NotNull; import com.dfsek.terra.api.block.state.BlockState; @@ -36,7 +37,7 @@ public class MinecraftWorldHandle implements WorldHandle { @Override public @NotNull BlockState createBlockState(@NotNull String data) { 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); return (BlockState) state; } catch(CommandSyntaxException e) { @@ -53,6 +54,6 @@ public class MinecraftWorldHandle implements WorldHandle { public @NotNull EntityType getEntity(@NotNull String id) { Identifier 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); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/VillagerTypeAccessor.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/VillagerTypeAccessor.java index 477c0647b..68ae33e35 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/VillagerTypeAccessor.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/VillagerTypeAccessor.java @@ -1,6 +1,6 @@ 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.world.biome.Biome; import org.spongepowered.asm.mixin.Mixin; diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java index f28c27a62..95fe9154c 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java @@ -21,9 +21,11 @@ import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.MobSpawnerBlockEntity; +import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; 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 org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Implements; @@ -48,13 +50,16 @@ public abstract class MobSpawnerBlockEntityMixin extends BlockEntity { @Shadow public abstract MobSpawnerLogic getLogic(); + @Shadow + public abstract void setEntityType(net.minecraft.entity.EntityType entityType, Random random); + public EntityType terra$getSpawnedType() { - return (EntityType) Registry.ENTITY_TYPE.get( + return (EntityType) Registries.ENTITY_TYPE.get( Identifier.tryParse(((MobSpawnerLogicAccessor) getLogic()).getSpawnEntry().getNbt().getString("id"))); } 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() { diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java index 636a3f721..2ec3cf649 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java @@ -5,8 +5,9 @@ import com.google.common.collect.ImmutableMap; import com.mojang.serialization.MapCodec; import net.minecraft.block.AbstractBlock.AbstractBlockState; import net.minecraft.block.Block; +import net.minecraft.registry.Registries; 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.Interface; import org.spongepowered.asm.mixin.Intrinsic; @@ -66,7 +67,7 @@ public abstract class BlockStateMixin extends State { 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; } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java index a9ecb9354..d4a27e750 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java @@ -1,8 +1,10 @@ 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.util.registry.DynamicRegistryManager; -import net.minecraft.util.registry.Registry; import net.minecraft.world.biome.Biome; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -18,11 +20,11 @@ public class DataPackContentsMixin { /* * #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) { - TagUtil.registerWorldPresetTags(dynamicRegistryManager.get(Registry.WORLD_PRESET_KEY)); + TagUtil.registerWorldPresetTags(dynamicRegistryManager.get(RegistryKeys.WORLD_PRESET)); - Registry biomeRegistry = dynamicRegistryManager.get(Registry.BIOME_KEY); + Registry biomeRegistry = dynamicRegistryManager.get(RegistryKeys.BIOME); TagUtil.registerBiomeTags(biomeRegistry); MinecraftUtil.registerFlora(biomeRegistry); } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftUtil.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftUtil.java index 69f91e6f6..53f406adc 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftUtil.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftUtil.java @@ -3,11 +3,13 @@ package com.dfsek.terra.mod.util; import net.minecraft.block.entity.LootableContainerBlockEntity; import net.minecraft.block.entity.MobSpawnerBlockEntity; 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.math.BlockPos; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryEntry; -import net.minecraft.util.registry.RegistryKey; +import net.minecraft.registry.Registry; import net.minecraft.world.WorldAccess; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome.Builder; @@ -23,6 +25,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Function; import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.api.block.entity.Container; @@ -46,7 +49,7 @@ public final class MinecraftUtil { public static Optional> getEntry(Registry registry, Identifier identifier) { return registry.getOrEmpty(identifier) .flatMap(registry::getKey) - .map(registry::getOrCreateEntry); + .flatMap(registry::getEntry); } public static BlockEntity createState(WorldAccess worldAccess, BlockPos pos) { @@ -91,7 +94,7 @@ public final class MinecraftUtil { } public static RegistryKey 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, @@ -131,7 +134,7 @@ public final class MinecraftUtil { if(vanillaBiomeProperties.getLoopSound() == null) { vanilla.getEffects().getLoopSound().ifPresent(effects::loopSound); } else { - effects.loopSound(vanillaBiomeProperties.getLoopSound()); + effects.loopSound(Registries.SOUND_EVENT.getEntry(vanillaBiomeProperties.getLoopSound())); } if(vanillaBiomeProperties.getMoodSound() == null) { diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java index f4fd942c8..5bf790dfa 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java @@ -1,11 +1,13 @@ 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.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.source.MultiNoiseBiomeSource; 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 List PRESETS = new ArrayList<>(); - public static Pair createDefault(ConfigPack pack) { - Registry dimensionTypeRegistry = BuiltinRegistries.DIMENSION_TYPE; - Registry chunkGeneratorSettingsRegistry = BuiltinRegistries.CHUNK_GENERATOR_SETTINGS; - Registry structureSetRegistry = BuiltinRegistries.STRUCTURE_SET; - Registry noiseParametersRegistry = BuiltinRegistries.NOISE_PARAMETERS; - Registry biomeRegistry = BuiltinRegistries.BIOME; + public static Pair createDefault(ConfigPack pack, ModPlatform platform) { + Registry dimensionTypeRegistry = platform.dimensionTypeRegistry(); + Registry chunkGeneratorSettingsRegistry = platform.chunkGeneratorSettingsRegistry(); - RegistryEntry theNetherDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.THE_NETHER); + RegistryEntry theNetherDimensionType = dimensionTypeRegistry.getEntry(DimensionTypes.THE_NETHER).orElseThrow(); RegistryEntry - netherChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getOrCreateEntry(ChunkGeneratorSettings.NETHER); + netherChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.NETHER).orElseThrow(); DimensionOptions netherDimensionOptions = new DimensionOptions(theNetherDimensionType, - new NoiseChunkGenerator(structureSetRegistry, - noiseParametersRegistry, - MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource( - biomeRegistry), - netherChunkGeneratorSettings)); - RegistryEntry theEndDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.THE_END); - RegistryEntry endChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getOrCreateEntry( - ChunkGeneratorSettings.END); + new NoiseChunkGenerator( + MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource( + platform.biomeRegistry().getReadOnlyWrapper()), + netherChunkGeneratorSettings)); + RegistryEntry theEndDimensionType = dimensionTypeRegistry.getEntry(DimensionTypes.THE_END).orElseThrow(); + RegistryEntry endChunkGeneratorSettings = chunkGeneratorSettingsRegistry.getEntry( + ChunkGeneratorSettings.END).orElseThrow(); DimensionOptions endDimensionOptions = new DimensionOptions(theEndDimensionType, - new NoiseChunkGenerator(structureSetRegistry, noiseParametersRegistry, - new TheEndBiomeSource(biomeRegistry), - endChunkGeneratorSettings)); + new NoiseChunkGenerator( + TheEndBiomeSource.createVanilla( + platform.biomeRegistry().getReadOnlyWrapper()), + endChunkGeneratorSettings)); - RegistryEntry overworldDimensionType = dimensionTypeRegistry.getOrCreateEntry(DimensionTypes.OVERWORLD); + RegistryEntry overworldDimensionType = dimensionTypeRegistry.getEntry(DimensionTypes.OVERWORLD).orElseThrow(); - RegistryEntry overworld = chunkGeneratorSettingsRegistry.getOrCreateEntry(ChunkGeneratorSettings.OVERWORLD); + RegistryEntry overworld = chunkGeneratorSettingsRegistry.getEntry(ChunkGeneratorSettings.OVERWORLD) + .orElseThrow(); Identifier generatorID = Identifier.of("terra", pack.getID().toLowerCase(Locale.ROOT) + "/" + pack.getNamespace().toLowerCase( Locale.ROOT)); PRESETS.add(generatorID); - TerraBiomeSource biomeSource = new TerraBiomeSource(biomeRegistry, pack); - ChunkGenerator generator = new MinecraftChunkGeneratorWrapper(structureSetRegistry, biomeSource, pack, overworld); + TerraBiomeSource biomeSource = new TerraBiomeSource(pack); + ChunkGenerator generator = new MinecraftChunkGeneratorWrapper(biomeSource, pack, overworld); DimensionOptions dimensionOptions = new DimensionOptions(overworldDimensionType, generator); WorldPreset preset = new WorldPreset( diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/TagUtil.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/TagUtil.java index 8edf50afc..81289fdfb 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/TagUtil.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/TagUtil.java @@ -1,10 +1,10 @@ package com.dfsek.terra.mod.util; import com.google.common.collect.ImmutableMap; -import net.minecraft.tag.TagKey; -import net.minecraft.tag.WorldPresetTags; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.Registry; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.registry.tag.WorldPresetTags; import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.WorldPreset; import org.slf4j.Logger; diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java index f218380d7..8efe9562c 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java @@ -3,17 +3,23 @@ package com.dfsek.terra.lifecycle; import ca.solostudios.strata.Versions; import ca.solostudios.strata.parser.tokenizer.ParseException; import net.minecraft.MinecraftVersion; +import net.minecraft.registry.DynamicRegistryManager; +import net.minecraft.registry.Registry; 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.LoggerFactory; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; import com.dfsek.terra.addon.EphemeralAddon; 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.ModPlatform; 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 MinecraftServer server; + private static final AtomicReference> BIOMES = new AtomicReference<>(); + private static final AtomicReference> DIMENSIONS = new AtomicReference<>(); + private static final AtomicReference> SETTINGS = new AtomicReference<>(); + public LifecyclePlatform() { CommonPlatform.initialize(this); load(); @@ -49,7 +59,6 @@ public abstract class LifecyclePlatform extends ModPlatform { LOGGER.warn("Failed to execute reload", throwable); return null; }).join(); - BiomeUtil.registerBiomes(); server.getWorlds().forEach(world -> { if(world.getChunkManager().getChunkGenerator() instanceof MinecraftChunkGeneratorWrapper chunkGeneratorWrapper) { getConfigRegistry().get(chunkGeneratorWrapper.getPack().getRegistryKey()).ifPresent(pack -> { @@ -62,13 +71,21 @@ public abstract class LifecyclePlatform extends ModPlatform { return succeed; } + public static void setRegistries(Registry biomeRegistry, + Registry dimensionTypeRegistry, + Registry chunkGeneratorSettingsRegistry) { + BIOMES.set(biomeRegistry); + DIMENSIONS.set(dimensionTypeRegistry); + SETTINGS.set(chunkGeneratorSettingsRegistry); + } + @Override protected Iterable platformAddon() { List addons = new ArrayList<>(); super.platformAddon().forEach(addons::add); - String mcVersion = MinecraftVersion.CURRENT.getReleaseTarget(); + String mcVersion = MinecraftVersion.CURRENT.getName(); try { addons.add(new EphemeralAddon(Versions.parseVersion(mcVersion), "minecraft")); } catch(ParseException e) { @@ -84,5 +101,20 @@ public abstract class LifecyclePlatform extends ModPlatform { return addons; } + @Override + public Registry dimensionTypeRegistry() { + return DIMENSIONS.get(); + } + + @Override + public Registry biomeRegistry() { + return BIOMES.get(); + } + + @Override + public Registry chunkGeneratorSettingsRegistry() { + return SETTINGS.get(); + } + protected abstract Collection getPlatformMods(); } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/NoiseConfigMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/NoiseConfigMixin.java index 2793aa500..e8091826a 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/NoiseConfigMixin.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/NoiseConfigMixin.java @@ -1,7 +1,8 @@ package com.dfsek.terra.lifecycle.mixin; +import net.minecraft.registry.RegistryEntryLookup; 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.gen.chunk.ChunkGeneratorSettings; import net.minecraft.world.gen.noise.NoiseConfig; @@ -24,10 +25,10 @@ public class NoiseConfigMixin { @Final private MultiNoiseSampler multiNoiseSampler; - @Inject(method = "(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/util/registry/Registry;J)V", + @Inject(method = "(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/registry/RegistryEntryLookup;J)V", at = @At("TAIL")) - private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, - Registry noiseRegistry, long seed, CallbackInfo ci) { + private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup noiseParametersLookup, long seed, + CallbackInfo ci) { SeedHack.register(multiNoiseSampler, seed); } } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/RegistryEntryReferenceInvoker.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/RegistryEntryReferenceInvoker.java new file mode 100644 index 000000000..d84b643cb --- /dev/null +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/RegistryEntryReferenceInvoker.java @@ -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 { + @Invoker("setValue") + void invokeSetValue(T value); +} diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/RegistryMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/RegistryMixin.java index 8e2c12c70..a2d516931 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/RegistryMixin.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/RegistryMixin.java @@ -1,6 +1,7 @@ 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.injection.At; 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; -@Mixin(Registry.class) +@Mixin(Registries.class) public class RegistryMixin { @Inject(method = "", at = @At("RETURN")) private static void registerTerraGenerators(CallbackInfo ci) { diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/SimpleRegistryMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/SimpleRegistryMixin.java new file mode 100644 index 000000000..2da9f317d --- /dev/null +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/SimpleRegistryMixin.java @@ -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 implements RegistryHack { + @Shadow + @Final + private Map> valueToEntry; + + @Override + public void terra_bind() { + valueToEntry.forEach((value, entry) -> { + //noinspection unchecked + ((RegistryEntryReferenceInvoker) entry).invokeSetValue(value); + }); + } +} diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/RegistryLoaderMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/RegistryLoaderMixin.java new file mode 100644 index 000000000..98f601b83 --- /dev/null +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/RegistryLoaderMixin.java @@ -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, Object>> instance, Consumer, 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 dimensionTypes = extractRegistry(instance, RegistryKeys.DIMENSION_TYPE).orElseThrow(); + MutableRegistry worldPresets = extractRegistry(instance, RegistryKeys.WORLD_PRESET).orElseThrow(); + MutableRegistry chunkGeneratorSettings = extractRegistry(instance, + RegistryKeys.CHUNK_GENERATOR_SETTINGS).orElseThrow(); + + LifecyclePlatform.setRegistries(biomes, dimensionTypes, chunkGeneratorSettings); + LifecycleUtil.initialize(biomes, worldPresets); + }); + instance.forEach(consumer); + } + + @SuppressWarnings("unchecked") + private static Optional> extractRegistry(List, Object>> instance, + RegistryKey> key) { + List> 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 registry = (MutableRegistry) matches.get(0); + ((RegistryHack) registry).terra_bind(); + return Optional.of(registry); + } +} diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/SaveLoadingMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/SaveLoadingMixin.java new file mode 100644 index 000000000..260d3c4a2 --- /dev/null +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/SaveLoadingMixin.java @@ -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; + } +} diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/client/MinecraftClientMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/client/MinecraftClientMixin.java deleted file mode 100644 index 30f092786..000000000 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/client/MinecraftClientMixin.java +++ /dev/null @@ -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 . - */ - -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 = "", 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(); - } -} diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/server/ServerMainMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/server/ServerMainMixin.java deleted file mode 100644 index e2e52bd2a..000000000 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/server/ServerMainMixin.java +++ /dev/null @@ -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 . - */ - -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;(Lnet/minecraft/resource/ResourceType;" + - "[Lnet/minecraft/resource/ResourcePackProvider;)V") - // after registry manager creation - ) - private static void injectConstructor(String[] args, CallbackInfo ci) { - LifecycleUtil.initialize(); - } -} diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java index f0d3e06e6..0eadea7f4 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java @@ -1,9 +1,10 @@ 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.registry.BuiltinRegistries; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryKey; +import net.minecraft.registry.Registry; import net.minecraft.village.VillagerType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,13 +30,12 @@ public final class BiomeUtil { } - public static void registerBiomes() { + public static void registerBiomes(Registry biomeRegistry) { logger.info("Registering biomes..."); CommonPlatform.get().getConfigRegistry().forEach(pack -> { // Register all Terra biomes. 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."); } @@ -46,36 +46,34 @@ public final class BiomeUtil { * @param pack The ConfigPack this biome belongs to. */ private static void registerBiome(Biome biome, ConfigPack pack, - com.dfsek.terra.api.registry.key.RegistryKey id) { - Registry registry = BuiltinRegistries.BIOME; + com.dfsek.terra.api.registry.key.RegistryKey id, + Registry registry) { RegistryKey vanilla = ((ProtoPlatformBiome) biome.getPlatformBiome()).get(registry); if(pack.getContext().get(PreLoadCompatibilityOptions.class).useVanillaBiomes()) { - ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(vanilla); + ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(registry.getEntry(vanilla).orElseThrow()); } else { 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); Identifier identifier = new Identifier("terra", MinecraftUtil.createBiomeID(pack, id)); if(registry.containsId(identifier)) { ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(MinecraftUtil.getEntry(registry, identifier) - .orElseThrow() - .getKey() .orElseThrow()); } else { - ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(BuiltinRegistries.add(registry, + ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(Registry.registerReference(registry, MinecraftUtil.registerKey(identifier) .getValue(), - minecraftBiome).getKey().orElseThrow()); + minecraftBiome)); } - Map villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap(); + Map, VillagerType> villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap(); - villagerMap.put(RegistryKey.of(Registry.BIOME_KEY, identifier), + villagerMap.put(RegistryKey.of(RegistryKeys.BIOME, identifier), Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(), villagerMap.getOrDefault(vanilla, VillagerType.PLAINS))); diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java index 498de58aa..70291458b 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java @@ -1,19 +1,27 @@ 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.mod.CommonPlatform; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.WorldPreset; + public final class LifecycleUtil { private LifecycleUtil() { } - public static void initialize() { + public static void initialize(MutableRegistry biomeMutableRegistry, MutableRegistry worldPresetMutableRegistry) { CommonPlatform.get().getEventManager().callEvent(new PlatformInitializationEvent()); - BiomeUtil.registerBiomes(); - CommonPlatform.get().registerWorldTypes((id, preset) -> BuiltinRegistries.add(BuiltinRegistries.WORLD_PRESET, id, preset)); + BiomeUtil.registerBiomes(biomeMutableRegistry); + CommonPlatform.get().registerWorldTypes((id, preset) -> Registry.register(worldPresetMutableRegistry, id, preset)); } } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryHack.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryHack.java new file mode 100644 index 000000000..347a13bfa --- /dev/null +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryHack.java @@ -0,0 +1,5 @@ +package com.dfsek.terra.lifecycle.util; + +public interface RegistryHack { + void terra_bind(); +} diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java index 9f17b89e3..6c6ee4ad6 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java @@ -1,7 +1,8 @@ package com.dfsek.terra.lifecycle.util; +import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; +import net.minecraft.registry.Registry; import com.dfsek.terra.mod.data.Codecs; @@ -12,7 +13,7 @@ public final class RegistryUtil { } public static void register() { - Registry.register(Registry.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.CHUNK_GENERATOR, new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER); + Registry.register(Registries.BIOME_SOURCE, new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE); } } diff --git a/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json b/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json index 7ec5e4d95..bf42757a4 100644 --- a/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json +++ b/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json @@ -1,21 +1,23 @@ { - "required": true, - "minVersion": "0.8", - "package": "com.dfsek.terra.lifecycle.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "NoiseConfigMixin", - "RegistryMixin", - "lifecycle.MinecraftServerMixin" - ], - "client": [ - "lifecycle.client.MinecraftClientMixin" - ], - "server": [ - "lifecycle.server.ServerMainMixin" - ], - "injectors": { - "defaultRequire": 1 - }, - "refmap": "terra.lifecycle.refmap.json" + "required": true, + "minVersion": "0.8", + "package": "com.dfsek.terra.lifecycle.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "NoiseConfigMixin", + "RegistryEntryReferenceInvoker", + "RegistryMixin", + "SimpleRegistryMixin", + "lifecycle.MinecraftServerMixin", + "lifecycle.RegistryLoaderMixin", + "lifecycle.SaveLoadingMixin" + ], + "client": [ + ], + "server": [ + ], + "injectors": { + "defaultRequire": 1 + }, + "refmap": "terra.lifecycle.refmap.json" } \ No newline at end of file