Expand the LevelStem codec to allow dimension jsons to specify that the dimension's chunk generator should use the overworld/server's seed (#7955)

This commit is contained in:
Joseph B authored and GitHub committed 2022-01-20 11:46:08 -08:00
1 parent f1bafce275
commit 93ce9e72f7
7 files changed
+113 -1

No files matched your search

@@ -32,6 +32,8 @@ import java.util.Optional;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
@@ -46,9 +48,12 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.mojang.datafixers.kinds.App;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Lifecycle;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.mojang.serialization.codecs.RecordCodecBuilder.Mu;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -100,6 +105,9 @@ import net.minecraft.core.Registry;
import net.minecraft.core.MappedRegistry;
import net.minecraft.world.*;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.BaseSpawner;
import net.minecraft.world.level.block.entity.FurnaceBlockEntity;
@@ -1249,6 +1257,50 @@ public class ForgeHooks
{
MinecraftForge.EVENT_BUS.post(new EntityEvent.EnteringSection(entity, packedOldPos, packedNewPos));
}
/**
* Called when dimension jsons are parsed.
* Creates a copy of the worldgen settings and its dimension registry,
* where dimensions that specify that they should use the server seed will use the server seed
* instead of the seed that mojang requires be specified in the json.
**/
public static WorldGenSettings loadDimensionsWithServerSeed(WorldGenSettings wgs)
{
// get the original worldgen settings' settings
long seed = wgs.seed();
boolean generateFeatures = wgs.generateFeatures();
boolean generateBonusChest = wgs.generateBonusChest();
MappedRegistry<LevelStem> originalRegistry = wgs.dimensions();
Optional<String> legacyCustomOptions = wgs.legacyCustomOptions;
// make a copy of the dimension registry; for dimensions that specify that they should use the server seed instead
// of the hardcoded json seed, recreate them with the correct seed
MappedRegistry<LevelStem> seededRegistry = new MappedRegistry<>(Registry.LEVEL_STEM_REGISTRY, Lifecycle.experimental());
for (Entry<ResourceKey<LevelStem>, LevelStem> entry : originalRegistry.entrySet())
{
ResourceKey<LevelStem> key = entry.getKey();
LevelStem dimension = entry.getValue();
if (dimension.useServerSeed())
{
seededRegistry.register(key, new LevelStem(dimension.typeSupplier(), dimension.generator().withSeed(seed), true), originalRegistry.lifecycle(entry.getValue()));
}
else
{
seededRegistry.register(key, dimension, originalRegistry.lifecycle(dimension));
}
}
return new WorldGenSettings(seed, generateFeatures, generateBonusChest, seededRegistry, legacyCustomOptions);
}
/** Called in the LevelStem codec builder to add extra fields to dimension jsons **/
public static App<Mu<LevelStem>, LevelStem> expandLevelStemCodec(RecordCodecBuilder.Instance<LevelStem> builder, Supplier<App<Mu<LevelStem>, LevelStem>> vanillaFieldsSupplier)
{
App<Mu<LevelStem>, LevelStem> vanillaFields = vanillaFieldsSupplier.get();
return builder.group(vanillaFields).and(
Codec.BOOL.optionalFieldOf("forge:use_server_seed", false).forGetter(levelStem -> levelStem.useServerSeed()))
.apply(builder, (stem, useServerSeed) -> new LevelStem(stem.typeSupplier(), stem.generator(), useServerSeed));
}
public static void writeAdditionalLevelSaveData(WorldData worldData, CompoundTag levelTag)
{
@@ -1331,5 +1383,4 @@ public class ForgeHooks
LOGGER.error(WORLDPERSISTENCE, buf.toString());
}
}
}