minecraft-src/net/minecraft/client/gui/screens/worldselection/WorldCreationUiState.java
2025-07-04 02:00:41 +03:00

324 lines
11 KiB
Java

package net.minecraft.client.gui.screens.worldselection;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.function.Consumer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.FileUtil;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.TagKey;
import net.minecraft.tags.WorldPresetTags;
import net.minecraft.world.Difficulty;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.WorldDataConfiguration;
import net.minecraft.world.level.levelgen.WorldOptions;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorPreset;
import net.minecraft.world.level.levelgen.presets.WorldPreset;
import net.minecraft.world.level.levelgen.presets.WorldPresets;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class WorldCreationUiState {
private static final Component DEFAULT_WORLD_NAME = Component.translatable("selectWorld.newWorld");
private final List<Consumer<WorldCreationUiState>> listeners = new ArrayList();
private String name = DEFAULT_WORLD_NAME.getString();
private WorldCreationUiState.SelectedGameMode gameMode = WorldCreationUiState.SelectedGameMode.SURVIVAL;
private Difficulty difficulty = Difficulty.NORMAL;
@Nullable
private Boolean allowCommands;
private String seed;
private boolean generateStructures;
private boolean bonusChest;
private final Path savesFolder;
private String targetFolder;
private WorldCreationContext settings;
private WorldCreationUiState.WorldTypeEntry worldType;
private final List<WorldCreationUiState.WorldTypeEntry> normalPresetList = new ArrayList();
private final List<WorldCreationUiState.WorldTypeEntry> altPresetList = new ArrayList();
private GameRules gameRules;
public WorldCreationUiState(Path savesFolder, WorldCreationContext settings, Optional<ResourceKey<WorldPreset>> preset, OptionalLong seed) {
this.savesFolder = savesFolder;
this.settings = settings;
this.worldType = new WorldCreationUiState.WorldTypeEntry((Holder<WorldPreset>)findPreset(settings, preset).orElse(null));
this.updatePresetLists();
this.seed = seed.isPresent() ? Long.toString(seed.getAsLong()) : "";
this.generateStructures = settings.options().generateStructures();
this.bonusChest = settings.options().generateBonusChest();
this.targetFolder = this.findResultFolder(this.name);
this.gameMode = settings.initialWorldCreationOptions().selectedGameMode();
this.gameRules = new GameRules(settings.dataConfiguration().enabledFeatures());
settings.initialWorldCreationOptions().disabledGameRules().forEach(key -> this.gameRules.<GameRules.BooleanValue>getRule(key).set(false, null));
Optional.ofNullable(settings.initialWorldCreationOptions().flatLevelPreset())
.flatMap(resourceKey -> settings.worldgenLoadContext().lookup(Registries.FLAT_LEVEL_GENERATOR_PRESET).flatMap(registry -> registry.get(resourceKey)))
.map(reference -> ((FlatLevelGeneratorPreset)reference.value()).settings())
.ifPresent(flatLevelGeneratorSettings -> this.updateDimensions(PresetEditor.flatWorldConfigurator(flatLevelGeneratorSettings)));
}
public void addListener(Consumer<WorldCreationUiState> listener) {
this.listeners.add(listener);
}
public void onChanged() {
boolean bl = this.isBonusChest();
if (bl != this.settings.options().generateBonusChest()) {
this.settings = this.settings.withOptions(worldOptions -> worldOptions.withBonusChest(bl));
}
boolean bl2 = this.isGenerateStructures();
if (bl2 != this.settings.options().generateStructures()) {
this.settings = this.settings.withOptions(worldOptions -> worldOptions.withStructures(bl2));
}
for (Consumer<WorldCreationUiState> consumer : this.listeners) {
consumer.accept(this);
}
}
public void setName(String name) {
this.name = name;
this.targetFolder = this.findResultFolder(name);
this.onChanged();
}
private String findResultFolder(String name) {
String string = name.trim();
try {
return FileUtil.findAvailableName(this.savesFolder, !string.isEmpty() ? string : DEFAULT_WORLD_NAME.getString(), "");
} catch (Exception var5) {
try {
return FileUtil.findAvailableName(this.savesFolder, "World", "");
} catch (IOException var4) {
throw new RuntimeException("Could not create save folder", var4);
}
}
}
public String getName() {
return this.name;
}
public String getTargetFolder() {
return this.targetFolder;
}
public void setGameMode(WorldCreationUiState.SelectedGameMode gameMode) {
this.gameMode = gameMode;
this.onChanged();
}
public WorldCreationUiState.SelectedGameMode getGameMode() {
return this.isDebug() ? WorldCreationUiState.SelectedGameMode.DEBUG : this.gameMode;
}
public void setDifficulty(Difficulty difficulty) {
this.difficulty = difficulty;
this.onChanged();
}
public Difficulty getDifficulty() {
return this.isHardcore() ? Difficulty.HARD : this.difficulty;
}
public boolean isHardcore() {
return this.getGameMode() == WorldCreationUiState.SelectedGameMode.HARDCORE;
}
public void setAllowCommands(boolean allowCommands) {
this.allowCommands = allowCommands;
this.onChanged();
}
public boolean isAllowCommands() {
if (this.isDebug()) {
return true;
} else if (this.isHardcore()) {
return false;
} else {
return this.allowCommands == null ? this.getGameMode() == WorldCreationUiState.SelectedGameMode.CREATIVE : this.allowCommands;
}
}
public void setSeed(String seed) {
this.seed = seed;
this.settings = this.settings.withOptions(worldOptions -> worldOptions.withSeed(WorldOptions.parseSeed(this.getSeed())));
this.onChanged();
}
public String getSeed() {
return this.seed;
}
public void setGenerateStructures(boolean generateStructures) {
this.generateStructures = generateStructures;
this.onChanged();
}
public boolean isGenerateStructures() {
return this.isDebug() ? false : this.generateStructures;
}
public void setBonusChest(boolean bonusChest) {
this.bonusChest = bonusChest;
this.onChanged();
}
public boolean isBonusChest() {
return !this.isDebug() && !this.isHardcore() ? this.bonusChest : false;
}
public void setSettings(WorldCreationContext settings) {
this.settings = settings;
this.updatePresetLists();
this.onChanged();
}
public WorldCreationContext getSettings() {
return this.settings;
}
public void updateDimensions(WorldCreationContext.DimensionsUpdater dimensionsUpdater) {
this.settings = this.settings.withDimensions(dimensionsUpdater);
this.onChanged();
}
protected boolean tryUpdateDataConfiguration(WorldDataConfiguration worldDataConfiguration) {
WorldDataConfiguration worldDataConfiguration2 = this.settings.dataConfiguration();
if (worldDataConfiguration2.dataPacks().getEnabled().equals(worldDataConfiguration.dataPacks().getEnabled())
&& worldDataConfiguration2.enabledFeatures().equals(worldDataConfiguration.enabledFeatures())) {
this.settings = new WorldCreationContext(
this.settings.options(),
this.settings.datapackDimensions(),
this.settings.selectedDimensions(),
this.settings.worldgenRegistries(),
this.settings.dataPackResources(),
worldDataConfiguration,
this.settings.initialWorldCreationOptions()
);
return true;
} else {
return false;
}
}
public boolean isDebug() {
return this.settings.selectedDimensions().isDebug();
}
public void setWorldType(WorldCreationUiState.WorldTypeEntry worldType) {
this.worldType = worldType;
Holder<WorldPreset> holder = worldType.preset();
if (holder != null) {
this.updateDimensions((frozen, worldDimensions) -> holder.value().createWorldDimensions());
}
}
public WorldCreationUiState.WorldTypeEntry getWorldType() {
return this.worldType;
}
@Nullable
public PresetEditor getPresetEditor() {
Holder<WorldPreset> holder = this.getWorldType().preset();
return holder != null ? (PresetEditor)PresetEditor.EDITORS.get(holder.unwrapKey()) : null;
}
public List<WorldCreationUiState.WorldTypeEntry> getNormalPresetList() {
return this.normalPresetList;
}
public List<WorldCreationUiState.WorldTypeEntry> getAltPresetList() {
return this.altPresetList;
}
private void updatePresetLists() {
Registry<WorldPreset> registry = this.getSettings().worldgenLoadContext().lookupOrThrow(Registries.WORLD_PRESET);
this.normalPresetList.clear();
this.normalPresetList
.addAll(
(Collection)getNonEmptyList(registry, WorldPresetTags.NORMAL)
.orElseGet(() -> registry.listElements().map(WorldCreationUiState.WorldTypeEntry::new).toList())
);
this.altPresetList.clear();
this.altPresetList.addAll((Collection)getNonEmptyList(registry, WorldPresetTags.EXTENDED).orElse(this.normalPresetList));
Holder<WorldPreset> holder = this.worldType.preset();
if (holder != null) {
WorldCreationUiState.WorldTypeEntry worldTypeEntry = (WorldCreationUiState.WorldTypeEntry)findPreset(this.getSettings(), holder.unwrapKey())
.map(WorldCreationUiState.WorldTypeEntry::new)
.orElse((WorldCreationUiState.WorldTypeEntry)this.normalPresetList.getFirst());
boolean bl = PresetEditor.EDITORS.get(holder.unwrapKey()) != null;
if (bl) {
this.worldType = worldTypeEntry;
} else {
this.setWorldType(worldTypeEntry);
}
}
}
private static Optional<Holder<WorldPreset>> findPreset(WorldCreationContext context, Optional<ResourceKey<WorldPreset>> preset) {
return preset.flatMap(resourceKey -> context.worldgenLoadContext().lookupOrThrow(Registries.WORLD_PRESET).get(resourceKey));
}
private static Optional<List<WorldCreationUiState.WorldTypeEntry>> getNonEmptyList(Registry<WorldPreset> registry, TagKey<WorldPreset> key) {
return registry.get(key).map(named -> named.stream().map(WorldCreationUiState.WorldTypeEntry::new).toList()).filter(list -> !list.isEmpty());
}
public void setGameRules(GameRules gameRules) {
this.gameRules = gameRules;
this.onChanged();
}
public GameRules getGameRules() {
return this.gameRules;
}
@Environment(EnvType.CLIENT)
public static enum SelectedGameMode {
SURVIVAL("survival", GameType.SURVIVAL),
HARDCORE("hardcore", GameType.SURVIVAL),
CREATIVE("creative", GameType.CREATIVE),
DEBUG("spectator", GameType.SPECTATOR);
public final GameType gameType;
public final Component displayName;
private final Component info;
private SelectedGameMode(final String id, final GameType gameType) {
this.gameType = gameType;
this.displayName = Component.translatable("selectWorld.gameMode." + id);
this.info = Component.translatable("selectWorld.gameMode." + id + ".info");
}
public Component getInfo() {
return this.info;
}
}
@Environment(EnvType.CLIENT)
public record WorldTypeEntry(@Nullable Holder<WorldPreset> preset) {
private static final Component CUSTOM_WORLD_DESCRIPTION = Component.translatable("generator.custom");
public Component describePreset() {
return (Component)Optional.ofNullable(this.preset)
.flatMap(Holder::unwrapKey)
.map(resourceKey -> Component.translatable(resourceKey.location().toLanguageKey("generator")))
.orElse(CUSTOM_WORLD_DESCRIPTION);
}
public boolean isAmplified() {
return Optional.ofNullable(this.preset).flatMap(Holder::unwrapKey).filter(resourceKey -> resourceKey.equals(WorldPresets.AMPLIFIED)).isPresent();
}
}
}