From b20b77ef75f3eca689ac6b67105f2bdd8dfcba42 Mon Sep 17 00:00:00 2001 From: ishland Date: Sat, 4 Jan 2025 16:54:57 +0800 Subject: [PATCH] change: create clean cache when generating biomes (#195) --- .../mixin/MixinMultiNoiseBiomeSource.java | 21 ++++++++++++++++- .../mixin/MixinNoiseBasedChunkGenerator.java | 23 +++++++++++++++++++ .../mixin/MixinParameterList.java | 18 ++++++++++++++- .../mixin/MultiNoiseBiomeSourceAccess.java | 20 ++++++++++++++++ .../IExtendedMultiNoiseBiomeSource.java | 9 ++++++++ .../worldgen/IExtendedParameterList.java | 3 ++- .../worldgen/noise/LayeredNoiseUtil.java | 10 +++++++- .../main/resources/terrablender.mixins.json | 4 +++- 8 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 Common/src/main/java/terrablender/mixin/MixinNoiseBasedChunkGenerator.java create mode 100644 Common/src/main/java/terrablender/mixin/MultiNoiseBiomeSourceAccess.java create mode 100644 Common/src/main/java/terrablender/worldgen/IExtendedMultiNoiseBiomeSource.java diff --git a/Common/src/main/java/terrablender/mixin/MixinMultiNoiseBiomeSource.java b/Common/src/main/java/terrablender/mixin/MixinMultiNoiseBiomeSource.java index 1a77137..c208049 100644 --- a/Common/src/main/java/terrablender/mixin/MixinMultiNoiseBiomeSource.java +++ b/Common/src/main/java/terrablender/mixin/MixinMultiNoiseBiomeSource.java @@ -17,28 +17,36 @@ */ package terrablender.mixin; +import com.mojang.datafixers.util.Either; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.QuartPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.biome.MultiNoiseBiomeSource; +import net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterList; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; 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.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import terrablender.worldgen.IExtendedMultiNoiseBiomeSource; import terrablender.worldgen.IExtendedParameterList; import java.util.List; @Mixin(MultiNoiseBiomeSource.class) -public abstract class MixinMultiNoiseBiomeSource +public abstract class MixinMultiNoiseBiomeSource implements IExtendedMultiNoiseBiomeSource { @Shadow public abstract Climate.ParameterList> parameters(); + @Shadow @Final @Mutable + private Either>, Holder> parameters; + @Inject(method="getNoiseBiome(IIILnet/minecraft/world/level/biome/Climate$Sampler;)Lnet/minecraft/core/Holder;", at=@At("HEAD"), cancellable = true) public void getNoiseBiome(int x, int y, int z, Climate.Sampler sampler, CallbackInfoReturnable> cir) { @@ -53,4 +61,15 @@ public void addDebugInfo(List debugLines, BlockPos pos, Climate.Sampler IExtendedParameterList> extension = (IExtendedParameterList>) this.parameters(); if (extension.isInitialized()) debugLines.add("Region: " + extension.getRegion(extension.getUniqueness(qx, 0, qz)).getName().toString()); } + + @Override + public MultiNoiseBiomeSource clone() { + try { + MultiNoiseBiomeSource cloned = (MultiNoiseBiomeSource) super.clone(); + ((MixinMultiNoiseBiomeSource) (Object) cloned).parameters = Either.left(((IExtendedParameterList>) this.parameters()).clone()); + return cloned; + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } } diff --git a/Common/src/main/java/terrablender/mixin/MixinNoiseBasedChunkGenerator.java b/Common/src/main/java/terrablender/mixin/MixinNoiseBasedChunkGenerator.java new file mode 100644 index 0000000..9be3443 --- /dev/null +++ b/Common/src/main/java/terrablender/mixin/MixinNoiseBasedChunkGenerator.java @@ -0,0 +1,23 @@ +package terrablender.mixin; + +import net.minecraft.world.level.biome.BiomeResolver; +import net.minecraft.world.level.biome.MultiNoiseBiomeSource; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import terrablender.worldgen.IExtendedMultiNoiseBiomeSource; + +@Mixin(NoiseBasedChunkGenerator.class) +public class MixinNoiseBasedChunkGenerator { + + @ModifyArg(method = "doCreateBiomes", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/ChunkAccess;fillBiomesFromNoise(Lnet/minecraft/world/level/biome/BiomeResolver;Lnet/minecraft/world/level/biome/Climate$Sampler;)V")) + private BiomeResolver modifyBiomeSource(BiomeResolver biomeResolver) { + if (biomeResolver instanceof MultiNoiseBiomeSource multiNoiseBiomeSource) { + return ((IExtendedMultiNoiseBiomeSource) multiNoiseBiomeSource).clone(); + } else { + return biomeResolver; + } + } + +} diff --git a/Common/src/main/java/terrablender/mixin/MixinParameterList.java b/Common/src/main/java/terrablender/mixin/MixinParameterList.java index 63020df..8119a45 100644 --- a/Common/src/main/java/terrablender/mixin/MixinParameterList.java +++ b/Common/src/main/java/terrablender/mixin/MixinParameterList.java @@ -33,10 +33,12 @@ import terrablender.worldgen.IExtendedParameterList; import terrablender.worldgen.RegionUtils.SearchTreeEntry; import terrablender.worldgen.noise.Area; +import terrablender.worldgen.noise.InitialLayer; import terrablender.worldgen.noise.LayeredNoiseUtil; import java.util.ArrayList; import java.util.List; +import java.util.function.Supplier; @Mixin(Climate.ParameterList.class) public abstract class MixinParameterList implements IExtendedParameterList @@ -50,6 +52,7 @@ public abstract class MixinParameterList implements IExtendedParameterList private boolean initialized = false; private boolean treesPopulated = false; + private Supplier newUniqueness; private Area uniqueness; private SearchTreeEntry[] uniqueTrees; @@ -60,7 +63,9 @@ public void initializeForTerraBlender(RegistryAccess registryAccess, RegionType if (this.initialized) return; - this.uniqueness = LayeredNoiseUtil.uniqueness(registryAccess, regionType, seed); + InitialLayer initialLayer = LayeredNoiseUtil.initialUniqueness(registryAccess, regionType); + this.newUniqueness = () -> LayeredNoiseUtil.finalUniqueness(regionType, seed, initialLayer); + this.uniqueness = this.newUniqueness.get(); this.uniqueTrees = new SearchTreeEntry[Regions.getCount(regionType)]; Registry biomeRegistry = registryAccess.lookupOrThrow(Registries.BIOME); @@ -142,4 +147,15 @@ public T findValuePositional(Climate.TargetPoint target, int x, int y, int z) else return (T)biome; } + + @Override + public Climate.ParameterList clone() { + try { + Climate.ParameterList cloned = (Climate.ParameterList) super.clone(); + ((MixinParameterList) (Object) cloned).uniqueness = ((MixinParameterList) (Object) cloned).newUniqueness.get(); + return cloned; + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } } diff --git a/Common/src/main/java/terrablender/mixin/MultiNoiseBiomeSourceAccess.java b/Common/src/main/java/terrablender/mixin/MultiNoiseBiomeSourceAccess.java new file mode 100644 index 0000000..c92ace1 --- /dev/null +++ b/Common/src/main/java/terrablender/mixin/MultiNoiseBiomeSourceAccess.java @@ -0,0 +1,20 @@ +package terrablender.mixin; + +import com.mojang.datafixers.util.Either; +import net.minecraft.core.Holder; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.biome.MultiNoiseBiomeSource; +import net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterList; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(MultiNoiseBiomeSource.class) +public interface MultiNoiseBiomeSourceAccess { + + @Mutable + @Accessor + void setParameters(Either>, Holder> parameters); + +} diff --git a/Common/src/main/java/terrablender/worldgen/IExtendedMultiNoiseBiomeSource.java b/Common/src/main/java/terrablender/worldgen/IExtendedMultiNoiseBiomeSource.java new file mode 100644 index 0000000..b8bc6e9 --- /dev/null +++ b/Common/src/main/java/terrablender/worldgen/IExtendedMultiNoiseBiomeSource.java @@ -0,0 +1,9 @@ +package terrablender.worldgen; + +import net.minecraft.world.level.biome.MultiNoiseBiomeSource; + +public interface IExtendedMultiNoiseBiomeSource extends Cloneable { + + MultiNoiseBiomeSource clone(); + +} diff --git a/Common/src/main/java/terrablender/worldgen/IExtendedParameterList.java b/Common/src/main/java/terrablender/worldgen/IExtendedParameterList.java index 6ffc3c3..3b50ba9 100644 --- a/Common/src/main/java/terrablender/worldgen/IExtendedParameterList.java +++ b/Common/src/main/java/terrablender/worldgen/IExtendedParameterList.java @@ -22,7 +22,7 @@ import terrablender.api.Region; import terrablender.api.RegionType; -public interface IExtendedParameterList +public interface IExtendedParameterList extends Cloneable { void initializeForTerraBlender(RegistryAccess registryAccess, RegionType regionType, long seed); T findValuePositional(Climate.TargetPoint target, int x, int y, int z); @@ -31,4 +31,5 @@ public interface IExtendedParameterList Region getRegion(int uniqueness); int getTreeCount(); boolean isInitialized(); + Climate.ParameterList clone(); } \ No newline at end of file diff --git a/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java b/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java index cbc870d..38584bf 100644 --- a/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java +++ b/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java @@ -31,12 +31,20 @@ public class LayeredNoiseUtil { public static Area uniqueness(RegistryAccess registryAccess, RegionType regionType, long seed) { + return finalUniqueness(regionType, seed, initialUniqueness(registryAccess, regionType)); + } + + public static InitialLayer initialUniqueness(RegistryAccess registryAccess, RegionType regionType) { + return new InitialLayer(registryAccess, regionType); + } + + public static Area finalUniqueness(RegionType regionType, long seed, InitialLayer initialLayer) { int numZooms = TerraBlender.CONFIG.overworldRegionSize; if (regionType == RegionType.NETHER) numZooms = TerraBlender.CONFIG.netherRegionSize; - return createZoomedArea(seed, numZooms, new InitialLayer(registryAccess, regionType)); + return createZoomedArea(seed, numZooms, initialLayer); } public static Area biomeArea(RegistryAccess registryAccess, long seed, int size, List>> entries) diff --git a/Common/src/main/resources/terrablender.mixins.json b/Common/src/main/resources/terrablender.mixins.json index defa3b1..9c03d16 100644 --- a/Common/src/main/resources/terrablender.mixins.json +++ b/Common/src/main/resources/terrablender.mixins.json @@ -8,10 +8,12 @@ "MixinBuiltInRegistries", "MixinChunkGenerator", "MixinMultiNoiseBiomeSource", + "MixinNoiseBasedChunkGenerator", "MixinNoiseGeneratorSettings", "MixinParameterList", "MixinPrimaryLevelData", - "MixinTheEndBiomeSource" + "MixinTheEndBiomeSource", + "MultiNoiseBiomeSourceAccess" ], "client": [ "MixinWorldOpenFlows"