mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 23:01:03 +00:00
add seed hack for biome provider
This commit is contained in:
@@ -20,6 +20,7 @@ package com.dfsek.terra.fabric;
|
|||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.gen.WorldPresets;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|||||||
@@ -39,15 +39,13 @@ public final class Codecs {
|
|||||||
.fieldOf("biome_registry")
|
.fieldOf("biome_registry")
|
||||||
.stable()
|
.stable()
|
||||||
.forGetter(TerraBiomeSource::getBiomeRegistry),
|
.forGetter(TerraBiomeSource::getBiomeRegistry),
|
||||||
Codec.LONG.fieldOf("seed")
|
|
||||||
.stable()
|
|
||||||
.forGetter(TerraBiomeSource::getSeed),
|
|
||||||
CONFIG_PACK.fieldOf("pack")
|
CONFIG_PACK.fieldOf("pack")
|
||||||
.stable()
|
.stable()
|
||||||
.forGetter(TerraBiomeSource::getPack))
|
.forGetter(TerraBiomeSource::getPack))
|
||||||
.apply(instance, instance.stable(TerraBiomeSource::new)));
|
.apply(instance, instance.stable(TerraBiomeSource::new)));
|
||||||
|
|
||||||
public static final Codec<FabricChunkGeneratorWrapper> FABRIC_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder.create(
|
public static final Codec<FabricChunkGeneratorWrapper> FABRIC_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder
|
||||||
|
.create(
|
||||||
instance -> instance.group(
|
instance -> instance.group(
|
||||||
RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY)
|
RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY)
|
||||||
.fieldOf("structure_registry")
|
.fieldOf("structure_registry")
|
||||||
@@ -56,9 +54,6 @@ public final class Codecs {
|
|||||||
TERRA_BIOME_SOURCE.fieldOf("biome_source")
|
TERRA_BIOME_SOURCE.fieldOf("biome_source")
|
||||||
.stable()
|
.stable()
|
||||||
.forGetter(FabricChunkGeneratorWrapper::getBiomeSource),
|
.forGetter(FabricChunkGeneratorWrapper::getBiomeSource),
|
||||||
Codec.LONG.fieldOf("seed")
|
|
||||||
.stable()
|
|
||||||
.forGetter(FabricChunkGeneratorWrapper::getSeed),
|
|
||||||
CONFIG_PACK.fieldOf("pack")
|
CONFIG_PACK.fieldOf("pack")
|
||||||
.stable()
|
.stable()
|
||||||
.forGetter(FabricChunkGeneratorWrapper::getPack),
|
.forGetter(FabricChunkGeneratorWrapper::getPack),
|
||||||
|
|||||||
+4
-10
@@ -20,6 +20,7 @@ package com.dfsek.terra.fabric.generation;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.structure.StructureSet;
|
import net.minecraft.structure.StructureSet;
|
||||||
|
import net.minecraft.util.Util;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.util.math.random.CheckedRandom;
|
import net.minecraft.util.math.random.CheckedRandom;
|
||||||
@@ -66,14 +67,13 @@ import com.dfsek.terra.fabric.util.FabricAdapter;
|
|||||||
public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.ChunkGenerator implements GeneratorWrapper {
|
public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.ChunkGenerator implements GeneratorWrapper {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(FabricChunkGeneratorWrapper.class);
|
private static final Logger logger = LoggerFactory.getLogger(FabricChunkGeneratorWrapper.class);
|
||||||
|
|
||||||
private final long seed;
|
|
||||||
private final TerraBiomeSource biomeSource;
|
private final TerraBiomeSource biomeSource;
|
||||||
private final Registry<StructureSet> noiseRegistry;
|
private final Registry<StructureSet> noiseRegistry;
|
||||||
private final RegistryEntry<ChunkGeneratorSettings> settings;
|
private final RegistryEntry<ChunkGeneratorSettings> settings;
|
||||||
private ChunkGenerator delegate;
|
private ChunkGenerator delegate;
|
||||||
private ConfigPack pack;
|
private ConfigPack pack;
|
||||||
|
|
||||||
public FabricChunkGeneratorWrapper(Registry<StructureSet> noiseRegistry, TerraBiomeSource biomeSource, long seed, ConfigPack configPack,
|
public FabricChunkGeneratorWrapper(Registry<StructureSet> noiseRegistry, TerraBiomeSource biomeSource, ConfigPack configPack,
|
||||||
RegistryEntry<ChunkGeneratorSettings> settingsSupplier) {
|
RegistryEntry<ChunkGeneratorSettings> settingsSupplier) {
|
||||||
super(noiseRegistry, Optional.empty(), biomeSource);
|
super(noiseRegistry, Optional.empty(), biomeSource);
|
||||||
this.noiseRegistry = noiseRegistry;
|
this.noiseRegistry = noiseRegistry;
|
||||||
@@ -83,8 +83,6 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
|
|||||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||||
logger.info("Loading world with config pack {}", pack.getID());
|
logger.info("Loading world with config pack {}", pack.getID());
|
||||||
this.biomeSource = biomeSource;
|
this.biomeSource = biomeSource;
|
||||||
|
|
||||||
this.seed = seed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Registry<StructureSet> getNoiseRegistry() {
|
public Registry<StructureSet> getNoiseRegistry() {
|
||||||
@@ -158,7 +156,7 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
|
|||||||
@Override
|
@Override
|
||||||
public int getHeight(int x, int z, Type heightmap, HeightLimitView height, NoiseConfig noiseConfig) {
|
public int getHeight(int x, int z, Type heightmap, HeightLimitView height, NoiseConfig noiseConfig) {
|
||||||
int y = height.getTopY();
|
int y = height.getTopY();
|
||||||
WorldProperties properties = FabricAdapter.adapt(height, seed);
|
WorldProperties properties = FabricAdapter.adapt(height, noiseConfig.getLegacyWorldSeed());
|
||||||
BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties);
|
BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties);
|
||||||
while(y >= getMinimumY() && !heightmap.getBlockPredicate().test(
|
while(y >= getMinimumY() && !heightmap.getBlockPredicate().test(
|
||||||
(BlockState) delegate.getBlock(properties, x, y - 1, z, biomeProvider))) {
|
(BlockState) delegate.getBlock(properties, x, y - 1, z, biomeProvider))) {
|
||||||
@@ -170,7 +168,7 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
|
|||||||
@Override
|
@Override
|
||||||
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height, NoiseConfig noiseConfig) {
|
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height, NoiseConfig noiseConfig) {
|
||||||
BlockState[] array = new BlockState[height.getHeight()];
|
BlockState[] array = new BlockState[height.getHeight()];
|
||||||
WorldProperties properties = FabricAdapter.adapt(height, seed);
|
WorldProperties properties = FabricAdapter.adapt(height, noiseConfig.getLegacyWorldSeed());
|
||||||
BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties);
|
BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties);
|
||||||
for(int y = height.getTopY() - 1; y >= height.getBottomY(); y--) {
|
for(int y = height.getTopY() - 1; y >= height.getBottomY(); y--) {
|
||||||
array[y - height.getBottomY()] = (BlockState) delegate.getBlock(properties, x, y, z, biomeProvider);
|
array[y - height.getBottomY()] = (BlockState) delegate.getBlock(properties, x, y, z, biomeProvider);
|
||||||
@@ -206,10 +204,6 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
|
|||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getSeed() {
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegistryEntry<ChunkGeneratorSettings> getSettings() {
|
public RegistryEntry<ChunkGeneratorSettings> getSettings() {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-8
@@ -22,7 +22,11 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
|||||||
import com.dfsek.terra.fabric.data.Codecs;
|
import com.dfsek.terra.fabric.data.Codecs;
|
||||||
import com.dfsek.terra.fabric.util.ProtoPlatformBiome;
|
import com.dfsek.terra.fabric.util.ProtoPlatformBiome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.fabric.util.SeedHack;
|
||||||
|
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.util.registry.RegistryEntry;
|
import net.minecraft.util.registry.RegistryEntry;
|
||||||
import net.minecraft.world.biome.source.BiomeSource;
|
import net.minecraft.world.biome.source.BiomeSource;
|
||||||
@@ -30,6 +34,7 @@ import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
|
||||||
@@ -37,17 +42,17 @@ public class TerraBiomeSource extends BiomeSource {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(TerraBiomeSource.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(TerraBiomeSource.class);
|
||||||
private final Registry<net.minecraft.world.biome.Biome> biomeRegistry;
|
private final Registry<net.minecraft.world.biome.Biome> biomeRegistry;
|
||||||
private final long seed;
|
|
||||||
private ConfigPack pack;
|
private ConfigPack pack;
|
||||||
|
|
||||||
public TerraBiomeSource(Registry<net.minecraft.world.biome.Biome> biomes, long seed, ConfigPack pack) {
|
private final Object2LongMap<MultiNoiseSampler> noiseToSeed = new Object2LongOpenHashMap<>();
|
||||||
|
|
||||||
|
public TerraBiomeSource(Registry<net.minecraft.world.biome.Biome> biomes, ConfigPack pack) {
|
||||||
super(StreamSupport
|
super(StreamSupport
|
||||||
.stream(pack.getBiomeProvider()
|
.stream(pack.getBiomeProvider()
|
||||||
.getBiomes()
|
.getBiomes()
|
||||||
.spliterator(), false)
|
.spliterator(), false)
|
||||||
.map(b -> biomes.getOrCreateEntry(((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate())));
|
.map(b -> biomes.getOrCreateEntry(((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate())));
|
||||||
this.biomeRegistry = biomes;
|
this.biomeRegistry = biomes;
|
||||||
this.seed = seed;
|
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
|
|
||||||
LOGGER.debug("Biomes: " + getBiomes());
|
LOGGER.debug("Biomes: " + getBiomes());
|
||||||
@@ -63,7 +68,7 @@ public class TerraBiomeSource extends BiomeSource {
|
|||||||
return biomeRegistry
|
return biomeRegistry
|
||||||
.entryOf(((ProtoPlatformBiome) pack
|
.entryOf(((ProtoPlatformBiome) pack
|
||||||
.getBiomeProvider()
|
.getBiomeProvider()
|
||||||
.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, seed)
|
.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, SeedHack.getSeed(noiseSampler))
|
||||||
.getPlatformBiome()).getDelegate()
|
.getPlatformBiome()).getDelegate()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -83,8 +88,4 @@ public class TerraBiomeSource extends BiomeSource {
|
|||||||
public void setPack(ConfigPack pack) {
|
public void setPack(ConfigPack pack) {
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getSeed() {
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
package com.dfsek.terra.fabric.mixin.lifecycle;
|
||||||
|
|
||||||
|
import com.dfsek.terra.fabric.util.SeedHack;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
||||||
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
|
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.callback.CallbackInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack to map noise sampler to seeds
|
||||||
|
*/
|
||||||
|
@Mixin(NoiseConfig.class)
|
||||||
|
public class NoiseConfigMixin {
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private MultiNoiseSampler multiNoiseSampler;
|
||||||
|
|
||||||
|
@Inject(method = "<init>(Lnet/minecraft/world/gen/chunk/ChunkGeneratorSettings;Lnet/minecraft/util/registry/Registry;J)V", at = @At("TAIL"))
|
||||||
|
private void mapMultiNoise(ChunkGeneratorSettings chunkGeneratorSettings, Registry<DoublePerlinNoiseSampler.NoiseParameters> noiseRegistry, long seed, CallbackInfo ci) {
|
||||||
|
SeedHack.register(multiNoiseSampler, seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
package com.dfsek.terra.fabric.mixin.lifecycle;
|
||||||
|
|
||||||
|
import com.dfsek.terra.fabric.FabricEntryPoint;
|
||||||
|
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
|
||||||
|
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
|
||||||
|
|
||||||
|
import net.minecraft.structure.StructureSet;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler.NoiseParameters;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.RegistryEntry;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.dimension.DimensionOptions;
|
||||||
|
import net.minecraft.world.gen.WorldPreset;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
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.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(targets = "net/minecraft/world/gen/WorldPresets$Registrar")
|
||||||
|
public abstract class WorldPresetsRegistrarMixin {
|
||||||
|
@Shadow
|
||||||
|
protected abstract RegistryEntry<WorldPreset> register(RegistryKey<WorldPreset> key, DimensionOptions dimensionOptions);
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected abstract DimensionOptions createOverworldOptions(ChunkGenerator chunkGenerator);
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Registry<StructureSet> structureSetRegistry;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Registry<NoiseParameters> noiseParametersRegistry;
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Registry<Biome> biomeRegistry;
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry;
|
||||||
|
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
@Inject(method = "initAndGetDefault()Lnet/minecraft/util/registry/RegistryEntry;", at = @At("HEAD"))
|
||||||
|
private void injectInit(CallbackInfoReturnable<RegistryEntry<WorldPreset>> cir) {
|
||||||
|
LOGGER.info("Registering Terra world types...");
|
||||||
|
RegistryEntry<ChunkGeneratorSettings> overworld = chunkGeneratorSettingsRegistry.getOrCreateEntry(ChunkGeneratorSettings.OVERWORLD);
|
||||||
|
FabricEntryPoint
|
||||||
|
.getPlatform()
|
||||||
|
.getRawConfigRegistry()
|
||||||
|
.forEach((id, pack) -> register(
|
||||||
|
terraWorldKey(id.getNamespace(), id.getID()),
|
||||||
|
createOverworldOptions(
|
||||||
|
new FabricChunkGeneratorWrapper(
|
||||||
|
structureSetRegistry,
|
||||||
|
new TerraBiomeSource(biomeRegistry, pack),
|
||||||
|
pack,
|
||||||
|
overworld)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RegistryKey<WorldPreset> terraWorldKey(String packNamespace, String id) {
|
||||||
|
return RegistryKey.of(Registry.WORLD_PRESET_KEY, Identifier.of("terra", id.toLowerCase(Locale.ROOT) + "/" + id.toLowerCase(
|
||||||
|
Locale.ROOT)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.dfsek.terra.fabric.util;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
|
||||||
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil.MultiNoiseSampler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holder for hacky biome source seed workaround
|
||||||
|
*/
|
||||||
|
public class SeedHack {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SeedHack.class);
|
||||||
|
|
||||||
|
private static final Object2LongMap<MultiNoiseSampler> seedMap = new Object2LongOpenHashMap<>();
|
||||||
|
|
||||||
|
public static long getSeed(MultiNoiseSampler sampler) {
|
||||||
|
if(!seedMap.containsKey(sampler)) {
|
||||||
|
throw new IllegalArgumentException("Sampler is not registered: " + sampler);
|
||||||
|
}
|
||||||
|
return seedMap.getLong(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(MultiNoiseSampler sampler, long seed) {
|
||||||
|
LOGGER.info("Registered seed {} to sampler {}", seed, sampler);
|
||||||
|
seedMap.put(sampler, seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,9 @@
|
|||||||
"implementations.world.ServerWorldMixin",
|
"implementations.world.ServerWorldMixin",
|
||||||
"lifecycle.DataPackContentsMixin",
|
"lifecycle.DataPackContentsMixin",
|
||||||
"lifecycle.MinecraftServerMixin",
|
"lifecycle.MinecraftServerMixin",
|
||||||
"lifecycle.RegistryMixin"
|
"lifecycle.NoiseConfigMixin",
|
||||||
|
"lifecycle.RegistryMixin",
|
||||||
|
"lifecycle.WorldPresetsRegistrarMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"lifecycle.client.MinecraftClientMixin"
|
"lifecycle.client.MinecraftClientMixin"
|
||||||
|
|||||||
Reference in New Issue
Block a user