mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +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.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.gen.WorldPresets;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@@ -39,32 +39,27 @@ public final class Codecs {
|
||||
.fieldOf("biome_registry")
|
||||
.stable()
|
||||
.forGetter(TerraBiomeSource::getBiomeRegistry),
|
||||
Codec.LONG.fieldOf("seed")
|
||||
.stable()
|
||||
.forGetter(TerraBiomeSource::getSeed),
|
||||
CONFIG_PACK.fieldOf("pack")
|
||||
.stable()
|
||||
.forGetter(TerraBiomeSource::getPack))
|
||||
.apply(instance, instance.stable(TerraBiomeSource::new)));
|
||||
|
||||
public static final Codec<FabricChunkGeneratorWrapper> FABRIC_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder.create(
|
||||
instance -> instance.group(
|
||||
RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY)
|
||||
.fieldOf("structure_registry")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getNoiseRegistry),
|
||||
TERRA_BIOME_SOURCE.fieldOf("biome_source")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getBiomeSource),
|
||||
Codec.LONG.fieldOf("seed")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getSeed),
|
||||
CONFIG_PACK.fieldOf("pack")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getPack),
|
||||
ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getSettings)
|
||||
).apply(instance, instance.stable(FabricChunkGeneratorWrapper::new))
|
||||
);
|
||||
public static final Codec<FabricChunkGeneratorWrapper> FABRIC_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder
|
||||
.create(
|
||||
instance -> instance.group(
|
||||
RegistryOps.createRegistryCodec(Registry.STRUCTURE_SET_KEY)
|
||||
.fieldOf("structure_registry")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getNoiseRegistry),
|
||||
TERRA_BIOME_SOURCE.fieldOf("biome_source")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getBiomeSource),
|
||||
CONFIG_PACK.fieldOf("pack")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getPack),
|
||||
ChunkGeneratorSettings.REGISTRY_CODEC.fieldOf("settings")
|
||||
.stable()
|
||||
.forGetter(FabricChunkGeneratorWrapper::getSettings)
|
||||
).apply(instance, instance.stable(FabricChunkGeneratorWrapper::new))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.dfsek.terra.fabric.generation;
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.structure.StructureSet;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
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 {
|
||||
private static final Logger logger = LoggerFactory.getLogger(FabricChunkGeneratorWrapper.class);
|
||||
|
||||
private final long seed;
|
||||
private final TerraBiomeSource biomeSource;
|
||||
private final Registry<StructureSet> noiseRegistry;
|
||||
private final RegistryEntry<ChunkGeneratorSettings> settings;
|
||||
private ChunkGenerator delegate;
|
||||
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) {
|
||||
super(noiseRegistry, Optional.empty(), biomeSource);
|
||||
this.noiseRegistry = noiseRegistry;
|
||||
@@ -83,8 +83,6 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
|
||||
this.delegate = pack.getGeneratorProvider().newInstance(pack);
|
||||
logger.info("Loading world with config pack {}", pack.getID());
|
||||
this.biomeSource = biomeSource;
|
||||
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public Registry<StructureSet> getNoiseRegistry() {
|
||||
@@ -158,7 +156,7 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
|
||||
@Override
|
||||
public int getHeight(int x, int z, Type heightmap, HeightLimitView height, NoiseConfig noiseConfig) {
|
||||
int y = height.getTopY();
|
||||
WorldProperties properties = FabricAdapter.adapt(height, seed);
|
||||
WorldProperties properties = FabricAdapter.adapt(height, noiseConfig.getLegacyWorldSeed());
|
||||
BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties);
|
||||
while(y >= getMinimumY() && !heightmap.getBlockPredicate().test(
|
||||
(BlockState) delegate.getBlock(properties, x, y - 1, z, biomeProvider))) {
|
||||
@@ -170,7 +168,7 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
|
||||
@Override
|
||||
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView height, NoiseConfig noiseConfig) {
|
||||
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);
|
||||
for(int y = height.getTopY() - 1; y >= height.getBottomY(); y--) {
|
||||
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;
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public RegistryEntry<ChunkGeneratorSettings> getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@@ -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.util.ProtoPlatformBiome;
|
||||
|
||||
import com.dfsek.terra.fabric.util.SeedHack;
|
||||
|
||||
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.RegistryEntry;
|
||||
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.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
|
||||
@@ -37,17 +42,17 @@ public class TerraBiomeSource extends BiomeSource {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TerraBiomeSource.class);
|
||||
private final Registry<net.minecraft.world.biome.Biome> biomeRegistry;
|
||||
private final long seed;
|
||||
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
|
||||
.stream(pack.getBiomeProvider()
|
||||
.getBiomes()
|
||||
.spliterator(), false)
|
||||
.map(b -> biomes.getOrCreateEntry(((ProtoPlatformBiome) b.getPlatformBiome()).getDelegate())));
|
||||
this.biomeRegistry = biomes;
|
||||
this.seed = seed;
|
||||
this.pack = pack;
|
||||
|
||||
LOGGER.debug("Biomes: " + getBiomes());
|
||||
@@ -63,7 +68,7 @@ public class TerraBiomeSource extends BiomeSource {
|
||||
return biomeRegistry
|
||||
.entryOf(((ProtoPlatformBiome) pack
|
||||
.getBiomeProvider()
|
||||
.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, seed)
|
||||
.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2, SeedHack.getSeed(noiseSampler))
|
||||
.getPlatformBiome()).getDelegate()
|
||||
);
|
||||
}
|
||||
@@ -83,8 +88,4 @@ public class TerraBiomeSource extends BiomeSource {
|
||||
public void setPack(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,51 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "com.dfsek.terra.fabric.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"access.MobSpawnerLogicAccessor",
|
||||
"access.StateAccessor",
|
||||
"access.StructureAccessorAccessor",
|
||||
"compat.GenerationSettingsFloraFeaturesMixin",
|
||||
"implementations.BiomeMixin",
|
||||
"implementations.HandleImplementationMixin",
|
||||
"implementations.block.BlockMixin",
|
||||
"implementations.block.entity.BlockEntityMixin",
|
||||
"implementations.block.entity.LootableContainerBlockEntityMixin",
|
||||
"implementations.block.entity.MobSpawnerBlockEntityMixin",
|
||||
"implementations.block.entity.SignBlockEntityMixin",
|
||||
"implementations.block.state.BlockStateMixin",
|
||||
"implementations.block.state.PropertyMixin",
|
||||
"implementations.chunk.ChunkRegionMixin",
|
||||
"implementations.chunk.WorldChunkMixin",
|
||||
"implementations.chunk.data.ProtoChunkMixin",
|
||||
"implementations.entity.EntityMixin",
|
||||
"implementations.entity.EntityTypeMixin",
|
||||
"implementations.entity.PlayerEntityMixin",
|
||||
"implementations.entity.ServerCommandSourceMixin",
|
||||
"implementations.inventory.LockableContainerBlockEntityMixin",
|
||||
"implementations.inventory.item.ItemMixin",
|
||||
"implementations.inventory.item.ItemStackMixin",
|
||||
"implementations.inventory.meta.EnchantmentMixin",
|
||||
"implementations.inventory.meta.ItemStackDamageableMixin",
|
||||
"implementations.inventory.meta.ItemStackMetaMixin",
|
||||
"implementations.world.ChunkRegionMixin",
|
||||
"implementations.world.ServerWorldMixin",
|
||||
"lifecycle.DataPackContentsMixin",
|
||||
"lifecycle.MinecraftServerMixin",
|
||||
"lifecycle.RegistryMixin"
|
||||
],
|
||||
"client": [
|
||||
"lifecycle.client.MinecraftClientMixin"
|
||||
],
|
||||
"server": [
|
||||
"lifecycle.server.ServerMainMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"refmap": "terra-refmap.json"
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "com.dfsek.terra.fabric.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"access.MobSpawnerLogicAccessor",
|
||||
"access.StateAccessor",
|
||||
"access.StructureAccessorAccessor",
|
||||
"compat.GenerationSettingsFloraFeaturesMixin",
|
||||
"implementations.BiomeMixin",
|
||||
"implementations.HandleImplementationMixin",
|
||||
"implementations.block.BlockMixin",
|
||||
"implementations.block.entity.BlockEntityMixin",
|
||||
"implementations.block.entity.LootableContainerBlockEntityMixin",
|
||||
"implementations.block.entity.MobSpawnerBlockEntityMixin",
|
||||
"implementations.block.entity.SignBlockEntityMixin",
|
||||
"implementations.block.state.BlockStateMixin",
|
||||
"implementations.block.state.PropertyMixin",
|
||||
"implementations.chunk.ChunkRegionMixin",
|
||||
"implementations.chunk.WorldChunkMixin",
|
||||
"implementations.chunk.data.ProtoChunkMixin",
|
||||
"implementations.entity.EntityMixin",
|
||||
"implementations.entity.EntityTypeMixin",
|
||||
"implementations.entity.PlayerEntityMixin",
|
||||
"implementations.entity.ServerCommandSourceMixin",
|
||||
"implementations.inventory.LockableContainerBlockEntityMixin",
|
||||
"implementations.inventory.item.ItemMixin",
|
||||
"implementations.inventory.item.ItemStackMixin",
|
||||
"implementations.inventory.meta.EnchantmentMixin",
|
||||
"implementations.inventory.meta.ItemStackDamageableMixin",
|
||||
"implementations.inventory.meta.ItemStackMetaMixin",
|
||||
"implementations.world.ChunkRegionMixin",
|
||||
"implementations.world.ServerWorldMixin",
|
||||
"lifecycle.DataPackContentsMixin",
|
||||
"lifecycle.MinecraftServerMixin",
|
||||
"lifecycle.NoiseConfigMixin",
|
||||
"lifecycle.RegistryMixin",
|
||||
"lifecycle.WorldPresetsRegistrarMixin"
|
||||
],
|
||||
"client": [
|
||||
"lifecycle.client.MinecraftClientMixin"
|
||||
],
|
||||
"server": [
|
||||
"lifecycle.server.ServerMainMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"refmap": "terra-refmap.json"
|
||||
}
|
||||
Reference in New Issue
Block a user