WorldPreset serialization and better structure for BiomeGenerator builder;
This commit is contained in:
parent
d63d773bb8
commit
c74b7b2d28
20 changed files with 365 additions and 244 deletions
|
@ -1,44 +1,38 @@
|
|||
package org.betterx.bclib.presets.worldgen;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.WorldDataAPI;
|
||||
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
|
||||
import org.betterx.bclib.mixin.common.WorldPresetAccessor;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.RegistryFileCodec;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BCLWorldPreset extends WorldPreset {
|
||||
public final WorldPresetSettings settings;
|
||||
public final int sortOrder;
|
||||
public static final Codec<BCLWorldPreset> DIRECT_CODEC = RecordCodecBuilder.create(builderInstance -> {
|
||||
RecordCodecBuilder<BCLWorldPreset, Map<ResourceKey<LevelStem>, LevelStem>> dimensionsBuidler = Codec
|
||||
.unboundedMap(ResourceKey.codec(Registry.LEVEL_STEM_REGISTRY), LevelStem.CODEC)
|
||||
.fieldOf("dimensions")
|
||||
.forGetter(worldPreset -> worldPreset.getDimensions());
|
||||
|
||||
RecordCodecBuilder<BCLWorldPreset, Integer> sortBuilder = Codec.INT
|
||||
.fieldOf("sort_order")
|
||||
.forGetter(wp -> wp.sortOrder);
|
||||
private static final String TAG_GENERATOR = LevelGenUtil.TAG_GENERATOR;
|
||||
|
||||
RecordCodecBuilder<BCLWorldPreset, WorldPresetSettings> settingsBuilder = WorldPresetSettings.CODEC
|
||||
.fieldOf("settings")
|
||||
.forGetter(wp -> wp.settings);
|
||||
private static int NEXT_IN_SORT_ORDER = 1000;
|
||||
|
||||
return builderInstance
|
||||
.group(dimensionsBuidler, sortBuilder, settingsBuilder)
|
||||
.apply(builderInstance, BCLWorldPreset::new);
|
||||
});
|
||||
|
||||
public static final Codec<Holder<WorldPreset>> CODEC = RegistryFileCodec.create(
|
||||
Registry.WORLD_PRESET_REGISTRY,
|
||||
(Codec<WorldPreset>) ((Object) DIRECT_CODEC)
|
||||
);
|
||||
public BCLWorldPreset(
|
||||
Map<ResourceKey<LevelStem>, LevelStem> map,
|
||||
Optional<Integer> sortOrder,
|
||||
Optional<WorldPresetSettings> settings
|
||||
) {
|
||||
this(map, sortOrder.orElse(NEXT_IN_SORT_ORDER++), settings.orElse(VanillaWorldPresetSettings.DEFAULT));
|
||||
}
|
||||
|
||||
public BCLWorldPreset(Map<ResourceKey<LevelStem>, LevelStem> map, int sortOrder, WorldPresetSettings settings) {
|
||||
super(map);
|
||||
|
@ -50,4 +44,28 @@ public class BCLWorldPreset extends WorldPreset {
|
|||
return ((WorldPresetAccessor) this).bcl_getDimensions();
|
||||
}
|
||||
|
||||
public static WorldPresetSettings writeWorldPresetSettings(Optional<Holder<WorldPreset>> worldPreset) {
|
||||
if (worldPreset.isPresent() && worldPreset.get().value() instanceof BCLWorldPreset wp) {
|
||||
writeWorldPresetSettings(wp.settings);
|
||||
return wp.settings;
|
||||
} else {
|
||||
writeWorldPresetSettings(VanillaWorldPresetSettings.DEFAULT);
|
||||
return VanillaWorldPresetSettings.DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeWorldPresetSettings(WorldPresetSettings presetSettings) {
|
||||
final RegistryOps<Tag> registryOps = RegistryOps.create(NbtOps.INSTANCE, BuiltinRegistries.ACCESS);
|
||||
final var codec = WorldPresetSettings.CODEC.orElse(presetSettings);
|
||||
final var encodeResult = codec.encodeStart(registryOps, presetSettings);
|
||||
|
||||
if (encodeResult.result().isPresent()) {
|
||||
final CompoundTag settingsNbt = WorldDataAPI.getRootTag(BCLib.TOGETHER_WORLDS);
|
||||
settingsNbt.put(TAG_GENERATOR, encodeResult.result().get());
|
||||
} else {
|
||||
BCLib.LOGGER.error("Unable to encode world generator settings generator for level.dat.");
|
||||
}
|
||||
|
||||
WorldDataAPI.saveFile(BCLib.TOGETHER_WORLDS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package org.betterx.bclib.presets.worldgen;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class VanillaWorldPresetSettings extends WorldPresetSettings {
|
||||
public static final VanillaWorldPresetSettings DEFAULT = new VanillaWorldPresetSettings();
|
||||
public static final Codec<VanillaWorldPresetSettings> CODEC = Codec.unit(VanillaWorldPresetSettings::new);
|
||||
|
||||
@Override
|
||||
public Codec<? extends WorldPresetSettings> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldGenSettings repairSettingsOnLoad(RegistryAccess registryAccess, WorldGenSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeSource fixBiomeSource(BiomeSource biomeSource, Set<Holder<Biome>> datapackBiomes) {
|
||||
return biomeSource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package org.betterx.bclib.presets.worldgen;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.LifeCycleAPI;
|
||||
import org.betterx.bclib.api.v2.WorldDataAPI;
|
||||
import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.api.v2.datafixer.DataFixerAPI;
|
||||
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI;
|
||||
import org.betterx.bclib.interfaces.WorldGenSettingsComponentAccessor;
|
||||
import org.betterx.bclib.mixin.common.RegistryOpsAccessor;
|
||||
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldGenSettingsComponent;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WorldBootstrap {
|
||||
private static class Helpers {
|
||||
|
||||
private static void initializeWorldDataAPI(
|
||||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
boolean newWorld
|
||||
) {
|
||||
File levelPath = levelStorageAccess.getLevelPath(LevelResource.ROOT).toFile();
|
||||
initializeWorldDataAPI(levelPath, newWorld);
|
||||
}
|
||||
|
||||
private static void setupWorld() {
|
||||
InternalBiomeAPI.prepareNewLevel();
|
||||
DataExchangeAPI.prepareServerside();
|
||||
}
|
||||
|
||||
private static void initializeWorldDataAPI(File levelBaseDir, boolean newWorld) {
|
||||
WorldDataAPI.load(new File(levelBaseDir, "data"));
|
||||
|
||||
if (newWorld) {
|
||||
WorldDataAPI.saveFile(BCLib.MOD_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class DedicatedServer {
|
||||
public static void registryReady(RegistryOps<Tag> regOps) {
|
||||
InternalBiomeAPI.initRegistry(regOps);
|
||||
}
|
||||
|
||||
public static void setupWorld(LevelStorageSource.LevelStorageAccess levelStorageAccess) {
|
||||
Helpers.setupWorld();
|
||||
|
||||
File levelDat = levelStorageAccess.getLevelPath(LevelResource.LEVEL_DATA_FILE).toFile();
|
||||
if (!levelDat.exists()) {
|
||||
BCLib.LOGGER.info("Creating a new World, no fixes needed");
|
||||
Helpers.initializeWorldDataAPI(levelStorageAccess, true);
|
||||
BCLWorldPreset.writeWorldPresetSettings(Optional.empty());
|
||||
DataFixerAPI.initializePatchData();
|
||||
} else {
|
||||
Helpers.initializeWorldDataAPI(levelStorageAccess, false);
|
||||
DataFixerAPI.fixData(levelStorageAccess, false, (didFix) -> {/* not called when showUI==false */});
|
||||
}
|
||||
|
||||
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
}
|
||||
}
|
||||
|
||||
public static class InGUI {
|
||||
public static void registryReady(WorldGenSettingsComponent worldGenSettingsComponent) {
|
||||
InternalBiomeAPI.initRegistry(worldGenSettingsComponent.registryHolder());
|
||||
}
|
||||
|
||||
public static void registryReady(Optional<RegistryOps<Tag>> registryOps) {
|
||||
if (registryOps.orElse(null) instanceof RegistryOpsAccessor acc) {
|
||||
InternalBiomeAPI.initRegistry(acc.bcl_getRegistryAccess());
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupNewWorld(
|
||||
Optional<LevelStorageSource.LevelStorageAccess> levelStorageAccess,
|
||||
WorldGenSettingsComponent worldGenSettingsComponent
|
||||
) {
|
||||
if (levelStorageAccess.isPresent()) {
|
||||
Helpers.setupWorld();
|
||||
|
||||
Helpers.initializeWorldDataAPI(levelStorageAccess.get(), true);
|
||||
|
||||
if (worldGenSettingsComponent instanceof WorldGenSettingsComponentAccessor acc) {
|
||||
BCLWorldPreset.writeWorldPresetSettings(acc.bcl_getPreset());
|
||||
}
|
||||
|
||||
DataFixerAPI.initializePatchData();
|
||||
// DataFixerAPI.createWorldData(
|
||||
// levelStorageAccess.get(),
|
||||
// worldGenSettingsComponent.settings().worldGenSettings()
|
||||
// );
|
||||
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not call {@link LifeCycleAPI#_runBeforeLevelLoad()}
|
||||
*/
|
||||
public static void setupLoadedWorld(
|
||||
String levelID,
|
||||
LevelStorageSource levelSource
|
||||
) {
|
||||
Helpers.setupWorld();
|
||||
try {
|
||||
var levelStorageAccess = levelSource.createAccess(levelID);
|
||||
Helpers.initializeWorldDataAPI(levelStorageAccess, true);
|
||||
levelStorageAccess.close();
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error("Failed to initialize data in world", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class InFreshLevel {
|
||||
public static void setupNewWorld(
|
||||
String levelID,
|
||||
WorldGenSettings worldGenSettings,
|
||||
LevelStorageSource levelSource,
|
||||
Optional<Holder<WorldPreset>> worldPreset
|
||||
) {
|
||||
InGUI.setupLoadedWorld(levelID, levelSource);
|
||||
|
||||
BCLWorldPreset.writeWorldPresetSettings(worldPreset);
|
||||
DataFixerAPI.initializePatchData();
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
}
|
||||
}
|
||||
|
||||
public static WorldGenSettings enforceInNewWorld(WorldGenSettings worldGenSettings) {
|
||||
worldGenSettings = LevelGenUtil
|
||||
.getWorldSettings()
|
||||
.repairSettingsOnLoad(InternalBiomeAPI.worldRegistryAccess(), worldGenSettings);
|
||||
return worldGenSettings;
|
||||
}
|
||||
|
||||
public static WorldGenSettings enforceInLoadedWorld(
|
||||
Optional<RegistryOps<Tag>> registryOps,
|
||||
WorldGenSettings worldGenSettings
|
||||
) {
|
||||
if (registryOps.orElse(null) instanceof RegistryOpsAccessor acc) {
|
||||
return LevelGenUtil
|
||||
.getWorldSettings()
|
||||
.repairSettingsOnLoad(acc.bcl_getRegistryAccess(), worldGenSettings);
|
||||
//.repairSettingsOnLoad(InternalBiomeAPI.worldRegistryAccess(), worldGenSettings);
|
||||
} else {
|
||||
BCLib.LOGGER.error("Unable to obtain registryAccess when enforcing generators.");
|
||||
}
|
||||
return worldGenSettings;
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@ public abstract class WorldPresetSettings {
|
|||
|
||||
public static void bootstrap() {
|
||||
register(BCLib.makeID("bcl_world_preset_settings"), BCLWorldPresetSettings.CODEC);
|
||||
register(BCLib.makeID("vanilla_world_preset_settings"), VanillaWorldPresetSettings.CODEC);
|
||||
}
|
||||
|
||||
public abstract Codec<? extends WorldPresetSettings> codec();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue