CreateWorldScreen.java

net.minecraft.client.gui.screens.worldselection.CreateWorldScreen

信息

  • 全限定名:net.minecraft.client.gui.screens.worldselection.CreateWorldScreen
  • 类型:public class
  • 包:net.minecraft.client.gui.screens.worldselection
  • 源码路径:src/main/java/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java
  • 起始行号:L91
  • 继承:Screen
  • 职责:

    TODO

字段/常量

  • GROUP_BOTTOM

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L92
    • 说明:

      TODO

  • TAB_COLUMN_WIDTH

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L93
    • 说明:

      TODO

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L94
    • 说明:

      TODO

  • TEMP_WORLD_PREFIX

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L95
    • 说明:

      TODO

  • GAME_MODEL_LABEL

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L96
    • 说明:

      TODO

  • NAME_LABEL

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L97
    • 说明:

      TODO

  • EXPERIMENTS_LABEL

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L98
    • 说明:

      TODO

  • ALLOW_COMMANDS_INFO

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L99
    • 说明:

      TODO

  • PREPARING_WORLD_DATA

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L100
    • 说明:

      TODO

  • HORIZONTAL_BUTTON_SPACING

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L101
    • 说明:

      TODO

  • VERTICAL_BUTTON_SPACING

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L102
    • 说明:

      TODO

  • TAB_HEADER_BACKGROUND

    • 类型: Identifier
    • 修饰符: public static final
    • 源码定位: L103
    • 说明:

      TODO

  • layout

    • 类型: HeaderAndFooterLayout
    • 修饰符: private final
    • 源码定位: L104
    • 说明:

      TODO

  • uiState

    • 类型: WorldCreationUiState
    • 修饰符: private final
    • 源码定位: L105
    • 说明:

      TODO

  • tabManager

    • 类型: TabManager
    • 修饰符: private final
    • 源码定位: L106
    • 说明:

      TODO

  • recreated

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L107
    • 说明:

      TODO

  • packValidator

    • 类型: DirectoryValidator
    • 修饰符: private final
    • 源码定位: L108
    • 说明:

      TODO

  • createWorldCallback

    • 类型: CreateWorldCallback
    • 修饰符: private final
    • 源码定位: L109
    • 说明:

      TODO

  • onClose

    • 类型: Runnable
    • 修饰符: private final
    • 源码定位: L110
    • 说明:

      TODO

  • tempDataPackDir

    • 类型: Path
    • 修饰符: private
    • 源码定位: L111
    • 说明:

      TODO

  • tempDataPackRepository

    • 类型: PackRepository
    • 修饰符: private
    • 源码定位: L112
    • 说明:

      TODO

  • tabNavigationBar

    • 类型: TabNavigationBar
    • 修饰符: private
    • 源码定位: L113
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.gui.screens.worldselection.CreateWorldScreen.GameTab

    • 类型: class
    • 修饰符: private
    • 源码定位: L629
    • 说明:

      TODO

  • net.minecraft.client.gui.screens.worldselection.CreateWorldScreen.MoreTab

    • 类型: class
    • 修饰符: private
    • 源码定位: L709
    • 说明:

      TODO

  • net.minecraft.client.gui.screens.worldselection.CreateWorldScreen.WorldTab

    • 类型: class
    • 修饰符: private
    • 源码定位: L752
    • 说明:

      TODO

构造器

private CreateWorldScreen(Minecraft minecraft, Runnable onClose, WorldCreationContext settings, Optional<ResourceKey<WorldPreset>> preset, OptionalLong seed, CreateWorldCallback createWorldCallback) @ L226

  • 构造器名:CreateWorldScreen
  • 源码定位:L226
  • 修饰符:private

参数:

  • minecraft: Minecraft
  • onClose: Runnable
  • settings: WorldCreationContext
  • preset: Optional<ResourceKey>
  • seed: OptionalLong
  • createWorldCallback: CreateWorldCallback

说明:

TODO

方法

下面的方法块按源码顺序生成。

public static void openFresh(Minecraft minecraft, Runnable onClose) @ L115

  • 方法名:openFresh
  • 源码定位:L115
  • 返回类型:void
  • 修饰符:public static

参数:

  • minecraft: Minecraft
  • onClose: Runnable

说明:

TODO

public static void openFresh(Minecraft minecraft, Runnable onClose, CreateWorldCallback createWorld) @ L125

  • 方法名:openFresh
  • 源码定位:L125
  • 返回类型:void
  • 修饰符:public static

参数:

  • minecraft: Minecraft
  • onClose: Runnable
  • createWorld: CreateWorldCallback

说明:

TODO

public static void testWorld(Minecraft minecraft, Runnable onClose) @ L135

  • 方法名:testWorld
  • 源码定位:L135
  • 返回类型:void
  • 修饰符:public static

参数:

  • minecraft: Minecraft
  • onClose: Runnable

说明:

TODO

private static void openCreateWorldScreen(Minecraft minecraft, Runnable onClose, Function<WorldLoader.DataLoadContext,WorldGenSettings> worldGenSettings, WorldCreationContextMapper worldCreationContext, ResourceKey<WorldPreset> worldPreset, CreateWorldCallback createWorld) @ L163

  • 方法名:openCreateWorldScreen
  • 源码定位:L163
  • 返回类型:void
  • 修饰符:private static

参数:

  • minecraft: Minecraft
  • onClose: Runnable
  • worldGenSettings: Function<WorldLoader.DataLoadContext,WorldGenSettings>
  • worldCreationContext: WorldCreationContextMapper
  • worldPreset: ResourceKey
  • createWorld: CreateWorldCallback

说明:

TODO

public static CreateWorldScreen createFromExisting(Minecraft minecraft, Runnable onClose, LevelSettings levelSettings, WorldCreationContext worldCreationContext, Path newDataPackDir) @ L196

  • 方法名:createFromExisting
  • 源码定位:L196
  • 返回类型:CreateWorldScreen
  • 修饰符:public static

参数:

  • minecraft: Minecraft
  • onClose: Runnable
  • levelSettings: LevelSettings
  • worldCreationContext: WorldCreationContext
  • newDataPackDir: Path

说明:

TODO

public WorldCreationUiState getUiState() @ L241

  • 方法名:getUiState
  • 源码定位:L241
  • 返回类型:WorldCreationUiState
  • 修饰符:public

参数:

说明:

TODO

protected void init() @ L245

  • 方法名:init
  • 源码定位:L245
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void setInitialFocus() @ L263

  • 方法名:setInitialFocus
  • 源码定位:L263
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

public void repositionElements() @ L267

  • 方法名:repositionElements
  • 源码定位:L267
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private static void queueLoadScreen(Minecraft minecraft, Component message) @ L279

  • 方法名:queueLoadScreen
  • 源码定位:L279
  • 返回类型:void
  • 修饰符:private static

参数:

  • minecraft: Minecraft
  • message: Component

说明:

TODO

private void onCreate() @ L283

  • 方法名:onCreate
  • 源码定位:L283
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private void createWorldAndCleanup(LayeredRegistryAccess<RegistryLayer> finalLayers, LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings, Optional<GameRules> gameRules) @ L313

  • 方法名:createWorldAndCleanup
  • 源码定位:L313
  • 返回类型:void
  • 修饰符:private

参数:

  • finalLayers: LayeredRegistryAccess
  • worldDataAndGenSettings: LevelDataAndDimensions.WorldDataAndGenSettings
  • gameRules: Optional

说明:

TODO

private boolean createNewWorld(LayeredRegistryAccess<RegistryLayer> finalLayers, LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings, Optional<GameRules> gameRules) @ L323

  • 方法名:createNewWorld
  • 源码定位:L323
  • 返回类型:boolean
  • 修饰符:private

参数:

  • finalLayers: LayeredRegistryAccess
  • worldDataAndGenSettings: LevelDataAndDimensions.WorldDataAndGenSettings
  • gameRules: Optional

说明:

TODO

private LevelSettings createLevelSettings(boolean isDebug) @ L341

  • 方法名:createLevelSettings
  • 源码定位:L341
  • 返回类型:LevelSettings
  • 修饰符:private

参数:

  • isDebug: boolean

说明:

TODO

public boolean keyPressed(KeyEvent event) @ L356

  • 方法名:keyPressed
  • 源码定位:L356
  • 返回类型:boolean
  • 修饰符:public

参数:

  • event: KeyEvent

说明:

TODO

public void onClose() @ L370

  • 方法名:onClose
  • 源码定位:L370
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void popScreen() @ L375

  • 方法名:popScreen
  • 源码定位:L375
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L380

  • 方法名:extractRenderState
  • 源码定位:L380
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor
  • mouseX: int
  • mouseY: int
  • a: float

说明:

TODO

protected void extractMenuBackground(GuiGraphicsExtractor graphics) @ L388

  • 方法名:extractMenuBackground
  • 源码定位:L388
  • 返回类型:void
  • 修饰符:protected

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

private Path getOrCreateTempDataPackDir() @ L394

  • 方法名:getOrCreateTempDataPackDir
  • 源码定位:L394
  • 返回类型:Path
  • 修饰符:private

参数:

说明:

TODO

private void openExperimentsScreen(WorldDataConfiguration dataConfiguration) @ L408

  • 方法名:openExperimentsScreen
  • 源码定位:L408
  • 返回类型:void
  • 修饰符:private

参数:

  • dataConfiguration: WorldDataConfiguration

说明:

TODO

private void openDataPackSelectionScreen(WorldDataConfiguration dataConfiguration) @ L420

  • 方法名:openDataPackSelectionScreen
  • 源码定位:L420
  • 返回类型:void
  • 修饰符:private

参数:

  • dataConfiguration: WorldDataConfiguration

说明:

TODO

private void tryApplyNewDataPacks(PackRepository packRepository, boolean isDataPackScreen, Consumer<WorldDataConfiguration> onAbort) @ L435

  • 方法名:tryApplyNewDataPacks
  • 源码定位:L435
  • 返回类型:void
  • 修饰符:private

参数:

  • packRepository: PackRepository
  • isDataPackScreen: boolean
  • onAbort: Consumer

说明:

TODO

private void applyNewPackConfig(PackRepository packRepository, WorldDataConfiguration newConfig, Consumer<WorldDataConfiguration> onAbort) @ L459

  • 方法名:applyNewPackConfig
  • 源码定位:L459
  • 返回类型:void
  • 修饰符:private

参数:

  • packRepository: PackRepository
  • newConfig: WorldDataConfiguration
  • onAbort: Consumer

说明:

TODO

private static WorldLoader.InitConfig createDefaultLoadConfig(PackRepository packRepository, WorldDataConfiguration config) @ L523

  • 方法名:createDefaultLoadConfig
  • 源码定位:L523
  • 返回类型:WorldLoader.InitConfig
  • 修饰符:private static

参数:

  • packRepository: PackRepository
  • config: WorldDataConfiguration

说明:

TODO

private void removeTempDataPackDir() @ L528

  • 方法名:removeTempDataPackDir
  • 源码定位:L528
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private static void copyBetweenDirs(Path sourceDir, Path targetDir, Path sourcePath) @ L546

  • 方法名:copyBetweenDirs
  • 源码定位:L546
  • 返回类型:void
  • 修饰符:private static

参数:

  • sourceDir: Path
  • targetDir: Path
  • sourcePath: Path

说明:

TODO

private static Optional<LevelStorageSource.LevelStorageAccess> createNewWorldDirectory(Minecraft minecraft, String worldFolder, Path tempDataPackDir) @ L555

  • 方法名:createNewWorldDirectory
  • 源码定位:L555
  • 返回类型:Optional<LevelStorageSource.LevelStorageAccess>
  • 修饰符:private static

参数:

  • minecraft: Minecraft
  • worldFolder: String
  • tempDataPackDir: Path

说明:

TODO

public static Path createTempDataPackDirFromExistingWorld(Path sourcePackDir, Minecraft minecraft) @ L585

  • 方法名:createTempDataPackDirFromExistingWorld
  • 源码定位:L585
  • 返回类型:Path
  • 修饰符:public static

参数:

  • sourcePackDir: Path
  • minecraft: Minecraft

说明:

TODO

private Pair<Path,PackRepository> getDataPackSelectionSettings(WorldDataConfiguration dataConfiguration) @ L613

  • 方法名:getDataPackSelectionSettings
  • 源码定位:L613
  • 返回类型:Pair<Path,PackRepository>
  • 修饰符:private

参数:

  • dataConfiguration: WorldDataConfiguration

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class CreateWorldScreen extends Screen {
    private static final int GROUP_BOTTOM = 1;
    private static final int TAB_COLUMN_WIDTH = 210;
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final String TEMP_WORLD_PREFIX = "mcworld-";
    private static final Component GAME_MODEL_LABEL = Component.translatable("selectWorld.gameMode");
    private static final Component NAME_LABEL = Component.translatable("selectWorld.enterName");
    private static final Component EXPERIMENTS_LABEL = Component.translatable("selectWorld.experiments");
    private static final Component ALLOW_COMMANDS_INFO = Component.translatable("selectWorld.allowCommands.info");
    private static final Component PREPARING_WORLD_DATA = Component.translatable("createWorld.preparing");
    private static final int HORIZONTAL_BUTTON_SPACING = 10;
    private static final int VERTICAL_BUTTON_SPACING = 8;
    public static final Identifier TAB_HEADER_BACKGROUND = Identifier.withDefaultNamespace("textures/gui/tab_header_background.png");
    private final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this);
    private final WorldCreationUiState uiState;
    private final TabManager tabManager = new TabManager(x$0 -> this.addRenderableWidget(x$0), x$0 -> this.removeWidget(x$0));
    private boolean recreated;
    private final DirectoryValidator packValidator;
    private final CreateWorldCallback createWorldCallback;
    private final Runnable onClose;
    private @Nullable Path tempDataPackDir;
    private @Nullable PackRepository tempDataPackRepository;
    private @Nullable TabNavigationBar tabNavigationBar;
 
    public static void openFresh(Minecraft minecraft, Runnable onClose) {
        openFresh(
            minecraft,
            onClose,
            (createWorldScreen, finalLayers, worldDataAndGenSettings, gameRules, tempDataPackDir) -> createWorldScreen.createNewWorld(
                finalLayers, worldDataAndGenSettings, gameRules
            )
        );
    }
 
    public static void openFresh(Minecraft minecraft, Runnable onClose, CreateWorldCallback createWorld) {
        WorldCreationContextMapper worldCreationContext = (managers, registries, cookie) -> new WorldCreationContext(
            cookie.worldGenSettings(), registries, managers, cookie.dataConfiguration()
        );
        Function<WorldLoader.DataLoadContext, WorldGenSettings> worldGenSettings = context -> new WorldGenSettings(
            WorldOptions.defaultWithRandomSeed(), WorldPresets.createNormalWorldDimensions(context.datapackWorldgen())
        );
        openCreateWorldScreen(minecraft, onClose, worldGenSettings, worldCreationContext, WorldPresets.NORMAL, createWorld);
    }
 
    public static void testWorld(Minecraft minecraft, Runnable onClose) {
        WorldCreationContextMapper worldCreationContext = (managers, registries, cookie) -> new WorldCreationContext(
            cookie.worldGenSettings().options(),
            cookie.worldGenSettings().dimensions(),
            registries,
            managers,
            cookie.dataConfiguration(),
            new InitialWorldCreationOptions(
                WorldCreationUiState.SelectedGameMode.CREATIVE,
                new GameRuleMap.Builder().set(GameRules.ADVANCE_TIME, false).set(GameRules.ADVANCE_WEATHER, false).set(GameRules.SPAWN_MOBS, false).build(),
                FlatLevelGeneratorPresets.REDSTONE_READY
            )
        );
        Function<WorldLoader.DataLoadContext, WorldGenSettings> worldGenSettings = context -> new WorldGenSettings(
            WorldOptions.testWorldWithRandomSeed(), WorldPresets.createFlatWorldDimensions(context.datapackWorldgen())
        );
        openCreateWorldScreen(
            minecraft,
            onClose,
            worldGenSettings,
            worldCreationContext,
            WorldPresets.FLAT,
            (createWorldScreen, finalLayers, worldDataAndGenSettings, gameRules, tempDataPackDir) -> createWorldScreen.createNewWorld(
                finalLayers, worldDataAndGenSettings, gameRules
            )
        );
    }
 
    private static void openCreateWorldScreen(
        Minecraft minecraft,
        Runnable onClose,
        Function<WorldLoader.DataLoadContext, WorldGenSettings> worldGenSettings,
        WorldCreationContextMapper worldCreationContext,
        ResourceKey<WorldPreset> worldPreset,
        CreateWorldCallback createWorld
    ) {
        queueLoadScreen(minecraft, PREPARING_WORLD_DATA);
        long start = Util.getMillis();
        PackRepository vanillaOnlyPackRepository = new PackRepository(new ServerPacksSource(minecraft.directoryValidator()));
        WorldDataConfiguration dataConfig = SharedConstants.IS_RUNNING_IN_IDE
            ? new WorldDataConfiguration(new DataPackConfig(List.of("vanilla", "tests"), List.of()), FeatureFlags.DEFAULT_FLAGS)
            : WorldDataConfiguration.DEFAULT;
        WorldLoader.InitConfig loadConfig = createDefaultLoadConfig(vanillaOnlyPackRepository, dataConfig);
        CompletableFuture<WorldCreationContext> loadResult = WorldLoader.load(
            loadConfig,
            context -> new WorldLoader.DataLoadOutput<>(
                new DataPackReloadCookie(worldGenSettings.apply(context), context.dataConfiguration()), context.datapackDimensions()
            ),
            (resources, managers, registries, cookie) -> {
                resources.close();
                return worldCreationContext.apply(managers, registries, cookie);
            },
            Util.backgroundExecutor(),
            minecraft
        );
        minecraft.managedBlock(loadResult::isDone);
        long end = Util.getMillis();
        LOGGER.debug("Resource load for world creation blocked for {} ms", end - start);
        minecraft.setScreen(new CreateWorldScreen(minecraft, onClose, loadResult.join(), Optional.of(worldPreset), OptionalLong.empty(), createWorld));
    }
 
    public static CreateWorldScreen createFromExisting(
        Minecraft minecraft, Runnable onClose, LevelSettings levelSettings, WorldCreationContext worldCreationContext, @Nullable Path newDataPackDir
    ) {
        CreateWorldScreen result = new CreateWorldScreen(
            minecraft,
            onClose,
            worldCreationContext,
            WorldPresets.fromSettings(worldCreationContext.selectedDimensions()),
            OptionalLong.of(worldCreationContext.options().seed()),
            (createWorldScreen, finalLayers, worldDataAndGenSettings, gameRules, tempDataPackDir) -> createWorldScreen.createNewWorld(
                finalLayers, worldDataAndGenSettings, gameRules
            )
        );
        result.recreated = true;
        result.uiState.setName(levelSettings.levelName());
        result.uiState.setAllowCommands(levelSettings.allowCommands());
        result.uiState.setDifficulty(levelSettings.difficultySettings().difficulty());
        result.uiState.getGameRules().setAll(worldCreationContext.initialWorldCreationOptions().gameRuleOverwrites(), null);
        if (levelSettings.difficultySettings().hardcore()) {
            result.uiState.setGameMode(WorldCreationUiState.SelectedGameMode.HARDCORE);
        } else if (levelSettings.gameType().isSurvival()) {
            result.uiState.setGameMode(WorldCreationUiState.SelectedGameMode.SURVIVAL);
        } else if (levelSettings.gameType().isCreative()) {
            result.uiState.setGameMode(WorldCreationUiState.SelectedGameMode.CREATIVE);
        }
 
        result.tempDataPackDir = newDataPackDir;
        return result;
    }
 
    private CreateWorldScreen(
        Minecraft minecraft,
        Runnable onClose,
        WorldCreationContext settings,
        Optional<ResourceKey<WorldPreset>> preset,
        OptionalLong seed,
        CreateWorldCallback createWorldCallback
    ) {
        super(Component.translatable("selectWorld.create"));
        this.onClose = onClose;
        this.packValidator = minecraft.directoryValidator();
        this.createWorldCallback = createWorldCallback;
        this.uiState = new WorldCreationUiState(minecraft.getLevelSource().getBaseDir(), settings, preset, seed);
    }
 
    public WorldCreationUiState getUiState() {
        return this.uiState;
    }
 
    @Override
    protected void init() {
        this.tabNavigationBar = TabNavigationBar.builder(this.tabManager, this.width)
            .addTabs(new CreateWorldScreen.GameTab(), new CreateWorldScreen.WorldTab(), new CreateWorldScreen.MoreTab())
            .build();
        this.addRenderableWidget(this.tabNavigationBar);
        LinearLayout footer = this.layout.addToFooter(LinearLayout.horizontal().spacing(8));
        footer.addChild(Button.builder(Component.translatable("selectWorld.create"), button -> this.onCreate()).build());
        footer.addChild(Button.builder(CommonComponents.GUI_CANCEL, button -> this.popScreen()).build());
        this.layout.visitWidgets(button -> {
            button.setTabOrderGroup(1);
            this.addRenderableWidget(button);
        });
        this.tabNavigationBar.selectTab(0, false);
        this.uiState.onChanged();
        this.repositionElements();
    }
 
    @Override
    protected void setInitialFocus() {
    }
 
    @Override
    public void repositionElements() {
        if (this.tabNavigationBar != null) {
            this.tabNavigationBar.updateWidth(this.width);
            int tabAreaTop = this.tabNavigationBar.getRectangle().bottom();
            ScreenRectangle tabArea = new ScreenRectangle(0, tabAreaTop, this.width, this.height - this.layout.getFooterHeight() - tabAreaTop);
            this.tabManager.setTabArea(tabArea);
            this.layout.setHeaderHeight(tabAreaTop);
            this.layout.arrangeElements();
        }
    }
 
    private static void queueLoadScreen(Minecraft minecraft, Component message) {
        minecraft.setScreenAndShow(new GenericMessageScreen(message));
    }
 
    private void onCreate() {
        WorldCreationContext context = this.uiState.getSettings();
        WorldDimensions worldDimensions = context.selectedDimensions();
        WorldDimensions.Complete finalDimensions = worldDimensions.bake(context.datapackDimensions());
        LayeredRegistryAccess<RegistryLayer> finalLayers = context.worldgenRegistries()
            .replaceFrom(RegistryLayer.DIMENSIONS, finalDimensions.dimensionsRegistryAccess());
        FeatureFlagSet enabledFeatures = context.dataConfiguration().enabledFeatures();
        Lifecycle lifecycleFromFeatures = FeatureFlags.isExperimental(enabledFeatures) ? Lifecycle.experimental() : Lifecycle.stable();
        Lifecycle lifecycleFromRegistries = finalLayers.compositeAccess().allRegistriesLifecycle();
        Lifecycle lifecycle = lifecycleFromRegistries.add(lifecycleFromFeatures);
        boolean skipWarning = !this.recreated && lifecycleFromRegistries == Lifecycle.stable();
        boolean isDebug = finalDimensions.specialWorldProperty() == PrimaryLevelData.SpecialWorldProperty.DEBUG;
        LevelSettings levelSettings = this.createLevelSettings(isDebug);
        GameRules gameRules;
        if (isDebug) {
            gameRules = MinecraftServer.DEFAULT_GAME_RULES.get();
            gameRules.set(GameRules.ADVANCE_TIME, false, null);
        } else {
            gameRules = this.uiState.getGameRules().copy(enabledFeatures);
        }
 
        PrimaryLevelData worldData = new PrimaryLevelData(levelSettings, finalDimensions.specialWorldProperty(), lifecycle);
        WorldOptions options = this.uiState.getSettings().options();
        WorldGenSettings worldGenSettings = new WorldGenSettings(options, worldDimensions);
        LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings = new LevelDataAndDimensions.WorldDataAndGenSettings(worldData, worldGenSettings);
        WorldOpenFlows.confirmWorldCreation(
            this.minecraft, this, lifecycle, () -> this.createWorldAndCleanup(finalLayers, worldDataAndGenSettings, Optional.of(gameRules)), skipWarning
        );
    }
 
    private void createWorldAndCleanup(
        LayeredRegistryAccess<RegistryLayer> finalLayers, LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings, Optional<GameRules> gameRules
    ) {
        boolean worldCreationSuccessful = this.createWorldCallback.create(this, finalLayers, worldDataAndGenSettings, gameRules, this.tempDataPackDir);
        this.removeTempDataPackDir();
        if (!worldCreationSuccessful) {
            this.popScreen();
        }
    }
 
    private boolean createNewWorld(
        LayeredRegistryAccess<RegistryLayer> finalLayers, LevelDataAndDimensions.WorldDataAndGenSettings worldDataAndGenSettings, Optional<GameRules> gameRules
    ) {
        String worldFolder = this.uiState.getTargetFolder();
        WorldCreationContext context = this.uiState.getSettings();
        queueLoadScreen(this.minecraft, PREPARING_WORLD_DATA);
        Optional<LevelStorageSource.LevelStorageAccess> newWorldAccess = createNewWorldDirectory(this.minecraft, worldFolder, this.tempDataPackDir);
        if (newWorldAccess.isEmpty()) {
            SystemToast.onPackCopyFailure(this.minecraft, worldFolder);
            return false;
        } else {
            this.minecraft
                .createWorldOpenFlows()
                .createLevelFromExistingSettings(newWorldAccess.get(), context.dataPackResources(), finalLayers, worldDataAndGenSettings, gameRules);
            return true;
        }
    }
 
    private LevelSettings createLevelSettings(boolean isDebug) {
        String name = this.uiState.getName().trim();
        return isDebug
            ? new LevelSettings(
                name, GameType.SPECTATOR, new LevelSettings.DifficultySettings(Difficulty.PEACEFUL, false, false), true, WorldDataConfiguration.DEFAULT
            )
            : new LevelSettings(
                name,
                this.uiState.getGameMode().gameType,
                new LevelSettings.DifficultySettings(this.uiState.getDifficulty(), this.uiState.isHardcore(), false),
                this.uiState.isAllowCommands(),
                this.uiState.getSettings().dataConfiguration()
            );
    }
 
    @Override
    public boolean keyPressed(KeyEvent event) {
        if (this.tabNavigationBar.keyPressed(event)) {
            return true;
        } else if (super.keyPressed(event)) {
            return true;
        } else if (event.isConfirmation()) {
            this.onCreate();
            return true;
        } else {
            return false;
        }
    }
 
    @Override
    public void onClose() {
        this.popScreen();
    }
 
    public void popScreen() {
        this.onClose.run();
        this.removeTempDataPackDir();
    }
 
    @Override
    public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
        super.extractRenderState(graphics, mouseX, mouseY, a);
        graphics.blit(
            RenderPipelines.GUI_TEXTURED, Screen.FOOTER_SEPARATOR, 0, this.height - this.layout.getFooterHeight() - 2, 0.0F, 0.0F, this.width, 2, 32, 2
        );
    }
 
    @Override
    protected void extractMenuBackground(GuiGraphicsExtractor graphics) {
        graphics.blit(RenderPipelines.GUI_TEXTURED, TAB_HEADER_BACKGROUND, 0, 0, 0.0F, 0.0F, this.width, this.layout.getHeaderHeight(), 16, 16);
        this.extractMenuBackground(graphics, 0, this.layout.getHeaderHeight(), this.width, this.height);
    }
 
    private @Nullable Path getOrCreateTempDataPackDir() {
        if (this.tempDataPackDir == null) {
            try {
                this.tempDataPackDir = Files.createTempDirectory("mcworld-");
            } catch (IOException var2) {
                LOGGER.warn("Failed to create temporary dir", (Throwable)var2);
                SystemToast.onPackCopyFailure(this.minecraft, this.uiState.getTargetFolder());
                this.popScreen();
            }
        }
 
        return this.tempDataPackDir;
    }
 
    private void openExperimentsScreen(WorldDataConfiguration dataConfiguration) {
        Pair<Path, PackRepository> settings = this.getDataPackSelectionSettings(dataConfiguration);
        if (settings != null) {
            this.minecraft
                .setScreen(
                    new ExperimentsScreen(
                        this, settings.getSecond(), packRepository -> this.tryApplyNewDataPacks(packRepository, false, this::openExperimentsScreen)
                    )
                );
        }
    }
 
    private void openDataPackSelectionScreen(WorldDataConfiguration dataConfiguration) {
        Pair<Path, PackRepository> settings = this.getDataPackSelectionSettings(dataConfiguration);
        if (settings != null) {
            this.minecraft
                .setScreen(
                    new PackSelectionScreen(
                        settings.getSecond(),
                        packRepository -> this.tryApplyNewDataPacks(packRepository, true, this::openDataPackSelectionScreen),
                        settings.getFirst(),
                        Component.translatable("dataPack.title")
                    )
                );
        }
    }
 
    private void tryApplyNewDataPacks(PackRepository packRepository, boolean isDataPackScreen, Consumer<WorldDataConfiguration> onAbort) {
        List<String> newEnabled = ImmutableList.copyOf(packRepository.getSelectedIds());
        List<String> newDisabled = packRepository.getAvailableIds().stream().filter(id -> !newEnabled.contains(id)).collect(ImmutableList.toImmutableList());
        WorldDataConfiguration newConfig = new WorldDataConfiguration(
            new DataPackConfig(newEnabled, newDisabled), this.uiState.getSettings().dataConfiguration().enabledFeatures()
        );
        if (this.uiState.tryUpdateDataConfiguration(newConfig)) {
            this.minecraft.setScreen(this);
        } else {
            FeatureFlagSet requestedFeatureFlags = packRepository.getRequestedFeatureFlags();
            if (FeatureFlags.isExperimental(requestedFeatureFlags) && isDataPackScreen) {
                this.minecraft.setScreen(new ConfirmExperimentalFeaturesScreen(packRepository.getSelectedPacks(), accepted -> {
                    if (accepted) {
                        this.applyNewPackConfig(packRepository, newConfig, onAbort);
                    } else {
                        onAbort.accept(this.uiState.getSettings().dataConfiguration());
                    }
                }));
            } else {
                this.applyNewPackConfig(packRepository, newConfig, onAbort);
            }
        }
    }
 
    private void applyNewPackConfig(PackRepository packRepository, WorldDataConfiguration newConfig, Consumer<WorldDataConfiguration> onAbort) {
        this.minecraft.setScreenAndShow(new GenericMessageScreen(Component.translatable("dataPack.validation.working")));
        WorldLoader.InitConfig config = createDefaultLoadConfig(packRepository, newConfig);
        WorldLoader.<DataPackReloadCookie, WorldCreationContext>load(
                config,
                context -> {
                    if (context.datapackWorldgen().lookupOrThrow(Registries.WORLD_PRESET).listElements().findAny().isEmpty()) {
                        throw new IllegalStateException("Needs at least one world preset to continue");
                    } else if (context.datapackWorldgen().lookupOrThrow(Registries.BIOME).listElements().findAny().isEmpty()) {
                        throw new IllegalStateException("Needs at least one biome continue");
                    } else {
                        WorldCreationContext existingContext = this.uiState.getSettings();
                        DynamicOps<JsonElement> writeOps = existingContext.worldgenLoadContext().createSerializationContext(JsonOps.INSTANCE);
                        DataResult<JsonElement> encoded = WorldGenSettings.CODEC
                            .encodeStart(writeOps, new WorldGenSettings(existingContext.options(), existingContext.selectedDimensions()))
                            .setLifecycle(Lifecycle.stable());
                        DynamicOps<JsonElement> readOps = context.datapackWorldgen().createSerializationContext(JsonOps.INSTANCE);
                        WorldGenSettings settings = encoded.<WorldGenSettings>flatMap(r -> WorldGenSettings.CODEC.parse(readOps, r))
                            .getOrThrow(error -> new IllegalStateException("Error parsing worldgen settings after loading data packs: " + error));
                        return new WorldLoader.DataLoadOutput<>(new DataPackReloadCookie(settings, context.dataConfiguration()), context.datapackDimensions());
                    }
                },
                (resources, managers, registries, cookie) -> {
                    resources.close();
                    return new WorldCreationContext(cookie.worldGenSettings(), registries, managers, cookie.dataConfiguration());
                },
                Util.backgroundExecutor(),
                this.minecraft
            )
            .thenApply(settings -> {
                settings.validate();
                return (WorldCreationContext)settings;
            })
            .thenAcceptAsync(this.uiState::setSettings, this.minecraft)
            .handleAsync(
                (nothing, throwable) -> {
                    if (throwable != null) {
                        LOGGER.warn("Failed to validate datapack", throwable);
                        this.minecraft
                            .setScreen(
                                new ConfirmScreen(
                                    retry -> {
                                        if (retry) {
                                            onAbort.accept(this.uiState.getSettings().dataConfiguration());
                                        } else {
                                            onAbort.accept(WorldDataConfiguration.DEFAULT);
                                        }
                                    },
                                    Component.translatable("dataPack.validation.failed"),
                                    CommonComponents.EMPTY,
                                    Component.translatable("dataPack.validation.back"),
                                    Component.translatable("dataPack.validation.reset")
                                )
                            );
                    } else {
                        this.minecraft.setScreen(this);
                    }
 
                    return null;
                },
                this.minecraft
            );
    }
 
    private static WorldLoader.InitConfig createDefaultLoadConfig(PackRepository packRepository, WorldDataConfiguration config) {
        WorldLoader.PackConfig packConfig = new WorldLoader.PackConfig(packRepository, config, false, true);
        return new WorldLoader.InitConfig(packConfig, Commands.CommandSelection.INTEGRATED, LevelBasedPermissionSet.GAMEMASTER);
    }
 
    private void removeTempDataPackDir() {
        if (this.tempDataPackDir != null && Files.exists(this.tempDataPackDir)) {
            try (Stream<Path> files = Files.walk(this.tempDataPackDir)) {
                files.sorted(Comparator.reverseOrder()).forEach(path -> {
                    try {
                        Files.delete(path);
                    } catch (IOException var2) {
                        LOGGER.warn("Failed to remove temporary file {}", path, var2);
                    }
                });
            } catch (IOException var6) {
                LOGGER.warn("Failed to list temporary dir {}", this.tempDataPackDir);
            }
        }
 
        this.tempDataPackDir = null;
    }
 
    private static void copyBetweenDirs(Path sourceDir, Path targetDir, Path sourcePath) {
        try {
            Util.copyBetweenDirs(sourceDir, targetDir, sourcePath);
        } catch (IOException var4) {
            LOGGER.warn("Failed to copy datapack file from {} to {}", sourcePath, targetDir);
            throw new UncheckedIOException(var4);
        }
    }
 
    private static Optional<LevelStorageSource.LevelStorageAccess> createNewWorldDirectory(
        Minecraft minecraft, String worldFolder, @Nullable Path tempDataPackDir
    ) {
        try {
            LevelStorageSource.LevelStorageAccess access = minecraft.getLevelSource().createAccess(worldFolder);
            if (tempDataPackDir == null) {
                return Optional.of(access);
            }
 
            try {
                Optional var6;
                try (Stream<Path> files = Files.walk(tempDataPackDir)) {
                    Path targetDir = access.getLevelPath(LevelResource.DATAPACK_DIR);
                    FileUtil.createDirectoriesSafe(targetDir);
                    files.filter(f -> !f.equals(tempDataPackDir)).forEach(source -> copyBetweenDirs(tempDataPackDir, targetDir, source));
                    var6 = Optional.of(access);
                }
 
                return var6;
            } catch (UncheckedIOException | IOException var9) {
                LOGGER.warn("Failed to copy datapacks to world {}", worldFolder, var9);
                access.close();
            }
        } catch (UncheckedIOException | IOException var10) {
            LOGGER.warn("Failed to create access for {}", worldFolder, var10);
        }
 
        return Optional.empty();
    }
 
    public static Path createTempDataPackDirFromExistingWorld(Path sourcePackDir, Minecraft minecraft) {
        MutableObject<Path> tempDataPackDir = new MutableObject<>();
 
        try (Stream<Path> dataPackContents = Files.walk(sourcePackDir)) {
            dataPackContents.filter(p -> !p.equals(sourcePackDir)).forEach(source -> {
                Path targetDir = tempDataPackDir.get();
                if (targetDir == null) {
                    try {
                        targetDir = Files.createTempDirectory("mcworld-");
                    } catch (IOException var5) {
                        LOGGER.warn("Failed to create temporary dir");
                        throw new UncheckedIOException(var5);
                    }
 
                    tempDataPackDir.setValue(targetDir);
                }
 
                copyBetweenDirs(sourcePackDir, targetDir, source);
            });
        } catch (UncheckedIOException | IOException var8) {
            LOGGER.warn("Failed to copy datapacks from world {}", sourcePackDir, var8);
            SystemToast.onPackCopyFailure(minecraft, sourcePackDir.toString());
            return null;
        }
 
        return tempDataPackDir.get();
    }
 
    private @Nullable Pair<Path, PackRepository> getDataPackSelectionSettings(WorldDataConfiguration dataConfiguration) {
        Path dataPackDir = this.getOrCreateTempDataPackDir();
        if (dataPackDir != null) {
            if (this.tempDataPackRepository == null) {
                this.tempDataPackRepository = ServerPacksSource.createPackRepository(dataPackDir, this.packValidator);
                this.tempDataPackRepository.reload();
            }
 
            this.tempDataPackRepository.setSelected(dataConfiguration.dataPacks().getEnabled());
            return Pair.of(dataPackDir, this.tempDataPackRepository);
        } else {
            return null;
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private class GameTab extends GridLayoutTab {
        private static final Component TITLE = Component.translatable("createWorld.tab.game.title");
        private static final Component ALLOW_COMMANDS = Component.translatable("selectWorld.allowCommands");
        private final EditBox nameEdit;
 
        private GameTab() {
            Objects.requireNonNull(CreateWorldScreen.this);
            super(TITLE);
            GridLayout.RowHelper helper = this.layout.rowSpacing(8).createRowHelper(1);
            LayoutSettings buttonLayoutSettings = helper.newCellSettings();
            this.nameEdit = new EditBox(CreateWorldScreen.this.font, 208, 20, Component.translatable("selectWorld.enterName"));
            this.nameEdit.setValue(CreateWorldScreen.this.uiState.getName());
            this.nameEdit.setResponder(CreateWorldScreen.this.uiState::setName);
            CreateWorldScreen.this.uiState
                .addListener(
                    uiState -> this.nameEdit
                        .setTooltip(
                            Tooltip.create(
                                Component.translatable(
                                    "selectWorld.targetFolder", Component.literal(uiState.getTargetFolder()).withStyle(ChatFormatting.ITALIC)
                                )
                            )
                        )
                );
            CreateWorldScreen.this.setInitialFocus(this.nameEdit);
            helper.addChild(
                CommonLayouts.labeledElement(CreateWorldScreen.this.font, this.nameEdit, CreateWorldScreen.NAME_LABEL),
                helper.newCellSettings().alignHorizontallyCenter()
            );
            CycleButton<WorldCreationUiState.SelectedGameMode> gameModeButton = helper.addChild(
                CycleButton.<WorldCreationUiState.SelectedGameMode>builder(
                        selectedGameMode -> selectedGameMode.displayName, CreateWorldScreen.this.uiState.getGameMode()
                    )
                    .withValues(
                        WorldCreationUiState.SelectedGameMode.SURVIVAL,
                        WorldCreationUiState.SelectedGameMode.HARDCORE,
                        WorldCreationUiState.SelectedGameMode.CREATIVE
                    )
                    .create(0, 0, 210, 20, CreateWorldScreen.GAME_MODEL_LABEL, (button, gameMode) -> CreateWorldScreen.this.uiState.setGameMode(gameMode)),
                buttonLayoutSettings
            );
            CreateWorldScreen.this.uiState.addListener(data -> {
                gameModeButton.setValue(data.getGameMode());
                gameModeButton.active = !data.isDebug();
                gameModeButton.setTooltip(Tooltip.create(data.getGameMode().getInfo()));
            });
            CycleButton<Difficulty> difficultyButton = helper.addChild(
                CycleButton.builder(Difficulty::getDisplayName, CreateWorldScreen.this.uiState.getDifficulty())
                    .withValues(Difficulty.values())
                    .create(0, 0, 210, 20, Component.translatable("options.difficulty"), (button, value) -> CreateWorldScreen.this.uiState.setDifficulty(value)),
                buttonLayoutSettings
            );
            CreateWorldScreen.this.uiState.addListener(d -> {
                difficultyButton.setValue(CreateWorldScreen.this.uiState.getDifficulty());
                difficultyButton.active = !CreateWorldScreen.this.uiState.isHardcore();
                difficultyButton.setTooltip(Tooltip.create(CreateWorldScreen.this.uiState.getDifficulty().getInfo()));
            });
            CycleButton<Boolean> allowCommandsButton = helper.addChild(
                CycleButton.onOffBuilder(CreateWorldScreen.this.uiState.isAllowCommands())
                    .withTooltip(state -> Tooltip.create(CreateWorldScreen.ALLOW_COMMANDS_INFO))
                    .create(0, 0, 210, 20, ALLOW_COMMANDS, (b, state) -> CreateWorldScreen.this.uiState.setAllowCommands(state))
            );
            CreateWorldScreen.this.uiState.addListener(d -> {
                allowCommandsButton.setValue(CreateWorldScreen.this.uiState.isAllowCommands());
                allowCommandsButton.active = !CreateWorldScreen.this.uiState.isDebug() && !CreateWorldScreen.this.uiState.isHardcore();
            });
            if (!SharedConstants.getCurrentVersion().stable()) {
                helper.addChild(
                    Button.builder(
                            CreateWorldScreen.EXPERIMENTS_LABEL,
                            button -> CreateWorldScreen.this.openExperimentsScreen(CreateWorldScreen.this.uiState.getSettings().dataConfiguration())
                        )
                        .width(210)
                        .build()
                );
            }
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private class MoreTab extends GridLayoutTab {
        private static final Component TITLE = Component.translatable("createWorld.tab.more.title");
        private static final Component GAME_RULES_LABEL = Component.translatable("selectWorld.gameRules");
        private static final Component DATA_PACKS_LABEL = Component.translatable("selectWorld.dataPacks");
 
        private MoreTab() {
            Objects.requireNonNull(CreateWorldScreen.this);
            super(TITLE);
            GridLayout.RowHelper helper = this.layout.rowSpacing(8).createRowHelper(1);
            helper.addChild(Button.builder(GAME_RULES_LABEL, b -> this.openGameRulesScreen()).width(210).build());
            helper.addChild(
                Button.builder(
                        CreateWorldScreen.EXPERIMENTS_LABEL,
                        b -> CreateWorldScreen.this.openExperimentsScreen(CreateWorldScreen.this.uiState.getSettings().dataConfiguration())
                    )
                    .width(210)
                    .build()
            );
            helper.addChild(
                Button.builder(
                        DATA_PACKS_LABEL,
                        b -> CreateWorldScreen.this.openDataPackSelectionScreen(CreateWorldScreen.this.uiState.getSettings().dataConfiguration())
                    )
                    .width(210)
                    .build()
            );
        }
 
        private void openGameRulesScreen() {
            CreateWorldScreen.this.minecraft
                .setScreen(
                    new WorldCreationGameRulesScreen(
                        CreateWorldScreen.this.uiState.getGameRules().copy(CreateWorldScreen.this.uiState.getSettings().dataConfiguration().enabledFeatures()),
                        gameRules -> {
                            CreateWorldScreen.this.minecraft.setScreen(CreateWorldScreen.this);
                            gameRules.ifPresent(CreateWorldScreen.this.uiState::setGameRules);
                        }
                    )
                );
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private class WorldTab extends GridLayoutTab {
        private static final Component TITLE = Component.translatable("createWorld.tab.world.title");
        private static final Component AMPLIFIED_HELP_TEXT = Component.translatable("generator.minecraft.amplified.info");
        private static final Component GENERATE_STRUCTURES = Component.translatable("selectWorld.mapFeatures");
        private static final Component GENERATE_STRUCTURES_INFO = Component.translatable("selectWorld.mapFeatures.info");
        private static final Component BONUS_CHEST = Component.translatable("selectWorld.bonusItems");
        private static final Component SEED_LABEL = Component.translatable("selectWorld.enterSeed");
        private static final Component SEED_EMPTY_HINT = Component.translatable("selectWorld.seedInfo");
        private static final int WORLD_TAB_WIDTH = 310;
        private final EditBox seedEdit;
        private final Button customizeTypeButton;
 
        private WorldTab() {
            Objects.requireNonNull(CreateWorldScreen.this);
            super(TITLE);
            GridLayout.RowHelper helper = this.layout.columnSpacing(10).rowSpacing(8).createRowHelper(2);
            CycleButton<WorldCreationUiState.WorldTypeEntry> typeButton = helper.addChild(
                CycleButton.builder(WorldCreationUiState.WorldTypeEntry::describePreset, CreateWorldScreen.this.uiState.getWorldType())
                    .withValues(this.createWorldTypeValueSupplier())
                    .withCustomNarration(CreateWorldScreen.WorldTab::createTypeButtonNarration)
                    .create(
                        0,
                        0,
                        150,
                        20,
                        Component.translatable("selectWorld.mapType"),
                        (button, newPreset) -> CreateWorldScreen.this.uiState.setWorldType(newPreset)
                    )
            );
            typeButton.setValue(CreateWorldScreen.this.uiState.getWorldType());
            CreateWorldScreen.this.uiState.addListener(data -> {
                WorldCreationUiState.WorldTypeEntry worldType = data.getWorldType();
                typeButton.setValue(worldType);
                if (worldType.isAmplified()) {
                    typeButton.setTooltip(Tooltip.create(AMPLIFIED_HELP_TEXT));
                } else {
                    typeButton.setTooltip(null);
                }
 
                typeButton.active = CreateWorldScreen.this.uiState.getWorldType().preset() != null;
            });
            this.customizeTypeButton = helper.addChild(
                Button.builder(Component.translatable("selectWorld.customizeType"), b -> this.openPresetEditor()).build()
            );
            CreateWorldScreen.this.uiState.addListener(data -> this.customizeTypeButton.active = !data.isDebug() && data.getPresetEditor() != null);
            this.seedEdit = new EditBox(CreateWorldScreen.this.font, 308, 20, Component.translatable("selectWorld.enterSeed")) {
                {
                    Objects.requireNonNull(WorldTab.this);
                }
 
                @Override
                protected MutableComponent createNarrationMessage() {
                    return super.createNarrationMessage().append(CommonComponents.NARRATION_SEPARATOR).append(CreateWorldScreen.WorldTab.SEED_EMPTY_HINT);
                }
            };
            this.seedEdit.setHint(SEED_EMPTY_HINT);
            this.seedEdit.setValue(CreateWorldScreen.this.uiState.getSeed());
            this.seedEdit.setResponder(value -> CreateWorldScreen.this.uiState.setSeed(this.seedEdit.getValue()));
            helper.addChild(CommonLayouts.labeledElement(CreateWorldScreen.this.font, this.seedEdit, SEED_LABEL), 2);
            SwitchGrid.Builder switchGridBuilder = SwitchGrid.builder(310);
            switchGridBuilder.addSwitch(
                    GENERATE_STRUCTURES, CreateWorldScreen.this.uiState::isGenerateStructures, CreateWorldScreen.this.uiState::setGenerateStructures
                )
                .withIsActiveCondition(() -> !CreateWorldScreen.this.uiState.isDebug())
                .withInfo(GENERATE_STRUCTURES_INFO);
            switchGridBuilder.addSwitch(BONUS_CHEST, CreateWorldScreen.this.uiState::isBonusChest, CreateWorldScreen.this.uiState::setBonusChest)
                .withIsActiveCondition(() -> !CreateWorldScreen.this.uiState.isHardcore() && !CreateWorldScreen.this.uiState.isDebug());
            SwitchGrid switchGrid = switchGridBuilder.build();
            helper.addChild(switchGrid.layout(), 2);
            CreateWorldScreen.this.uiState.addListener(d -> switchGrid.refreshStates());
        }
 
        private void openPresetEditor() {
            PresetEditor editor = CreateWorldScreen.this.uiState.getPresetEditor();
            if (editor != null) {
                CreateWorldScreen.this.minecraft.setScreen(editor.createEditScreen(CreateWorldScreen.this, CreateWorldScreen.this.uiState.getSettings()));
            }
        }
 
        private CycleButton.ValueListSupplier<WorldCreationUiState.WorldTypeEntry> createWorldTypeValueSupplier() {
            return new CycleButton.ValueListSupplier<WorldCreationUiState.WorldTypeEntry>() {
                {
                    Objects.requireNonNull(WorldTab.this);
                }
 
                @Override
                public List<WorldCreationUiState.WorldTypeEntry> getSelectedList() {
                    return CycleButton.DEFAULT_ALT_LIST_SELECTOR.getAsBoolean()
                        ? CreateWorldScreen.this.uiState.getAltPresetList()
                        : CreateWorldScreen.this.uiState.getNormalPresetList();
                }
 
                @Override
                public List<WorldCreationUiState.WorldTypeEntry> getDefaultList() {
                    return CreateWorldScreen.this.uiState.getNormalPresetList();
                }
            };
        }
 
        private static MutableComponent createTypeButtonNarration(CycleButton<WorldCreationUiState.WorldTypeEntry> button) {
            return button.getValue().isAmplified()
                ? CommonComponents.joinForNarration(button.createDefaultNarrationMessage(), AMPLIFIED_HELP_TEXT)
                : button.createDefaultNarrationMessage();
        }
    }
}

引用的其他类

  • SharedConstants

    • 引用位置: 方法调用
    • 关联成员: SharedConstants.getCurrentVersion()
  • Minecraft

    • 引用位置: 参数
  • GuiGraphicsExtractor

    • 引用位置: 参数
  • Button

    • 引用位置: 方法调用
    • 关联成员: Button.builder()
  • CycleButton

    • 引用位置: 方法调用
    • 关联成员: CycleButton.builder(), CycleButton.onOffBuilder()
  • EditBox

    • 引用位置: 构造调用
    • 关联成员: EditBox()
  • Tooltip

    • 引用位置: 方法调用
    • 关联成员: Tooltip.create()
  • TabManager

    • 引用位置: 字段/构造调用
    • 关联成员: TabManager()
  • TabNavigationBar

    • 引用位置: 字段/方法调用
    • 关联成员: TabNavigationBar.builder()
  • SystemToast

    • 引用位置: 方法调用
    • 关联成员: SystemToast.onPackCopyFailure()
  • CommonLayouts

    • 引用位置: 方法调用
    • 关联成员: CommonLayouts.labeledElement()
  • HeaderAndFooterLayout

    • 引用位置: 字段/构造调用
    • 关联成员: HeaderAndFooterLayout()
  • LinearLayout

    • 引用位置: 方法调用
    • 关联成员: LinearLayout.horizontal()
  • ScreenRectangle

    • 引用位置: 构造调用
    • 关联成员: ScreenRectangle()
  • ConfirmScreen

    • 引用位置: 构造调用
    • 关联成员: ConfirmScreen()
  • GenericMessageScreen

    • 引用位置: 构造调用
    • 关联成员: GenericMessageScreen()
  • Screen

    • 引用位置: 继承
  • PackSelectionScreen

    • 引用位置: 构造调用
    • 关联成员: PackSelectionScreen()
  • ConfirmExperimentalFeaturesScreen

    • 引用位置: 构造调用
    • 关联成员: ConfirmExperimentalFeaturesScreen()
  • CreateWorldCallback

    • 引用位置: 参数/字段
  • DataPackReloadCookie

    • 引用位置: 构造调用
    • 关联成员: DataPackReloadCookie()
  • ExperimentsScreen

    • 引用位置: 构造调用
    • 关联成员: ExperimentsScreen()
  • InitialWorldCreationOptions

    • 引用位置: 构造调用
    • 关联成员: InitialWorldCreationOptions()
  • SwitchGrid

    • 引用位置: 方法调用
    • 关联成员: SwitchGrid.builder()
  • WorldCreationContext

    • 引用位置: 参数/构造调用
    • 关联成员: WorldCreationContext()
  • WorldCreationContextMapper

    • 引用位置: 参数
  • WorldCreationGameRulesScreen

    • 引用位置: 构造调用
    • 关联成员: WorldCreationGameRulesScreen()
  • WorldCreationUiState

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: WorldCreationUiState()
  • WorldOpenFlows

    • 引用位置: 方法调用
    • 关联成员: WorldOpenFlows.confirmWorldCreation()
  • KeyEvent

    • 引用位置: 参数
  • LayeredRegistryAccess

    • 引用位置: 参数
  • CommonComponents

    • 引用位置: 方法调用
    • 关联成员: CommonComponents.joinForNarration()
  • Component

    • 引用位置: 参数/字段/方法调用
    • 关联成员: Component.literal(), Component.translatable()
  • Identifier

    • 引用位置: 字段/方法调用
    • 关联成员: Identifier.withDefaultNamespace()
  • ResourceKey

    • 引用位置: 参数
  • RegistryLayer

    • 引用位置: 参数
  • WorldLoader

    • 引用位置: 参数/方法调用/构造调用/返回值
    • 关联成员: InitConfig(), PackConfig(), WorldLoader.InitConfig(), WorldLoader.PackConfig(), WorldLoader.load()
  • PackRepository

    • 引用位置: 参数/字段/构造调用/返回值
    • 关联成员: PackRepository()
  • ServerPacksSource

    • 引用位置: 方法调用/构造调用
    • 关联成员: ServerPacksSource(), ServerPacksSource.createPackRepository()
  • FileUtil

    • 引用位置: 方法调用
    • 关联成员: FileUtil.createDirectoriesSafe()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.backgroundExecutor(), Util.copyBetweenDirs(), Util.getMillis()
  • Difficulty

    • 引用位置: 方法调用
    • 关联成员: Difficulty.values()
  • FeatureFlags

    • 引用位置: 方法调用
    • 关联成员: FeatureFlags.isExperimental()
  • DataPackConfig

    • 引用位置: 构造调用
    • 关联成员: DataPackConfig()
  • LevelSettings

    • 引用位置: 参数/方法调用/构造调用/返回值
    • 关联成员: DifficultySettings(), LevelSettings(), LevelSettings.DifficultySettings()
  • WorldDataConfiguration

    • 引用位置: 参数/构造调用
    • 关联成员: WorldDataConfiguration()
  • GameRuleMap

    • 引用位置: 方法调用/构造调用
    • 关联成员: Builder(), GameRuleMap.Builder()
  • GameRules

    • 引用位置: 参数
  • WorldGenSettings

    • 引用位置: 参数/构造调用
    • 关联成员: WorldGenSettings()
  • WorldOptions

    • 引用位置: 方法调用
    • 关联成员: WorldOptions.defaultWithRandomSeed(), WorldOptions.testWorldWithRandomSeed()
  • WorldPreset

    • 引用位置: 参数
  • WorldPresets

    • 引用位置: 方法调用
    • 关联成员: WorldPresets.createFlatWorldDimensions(), WorldPresets.createNormalWorldDimensions(), WorldPresets.fromSettings()
  • LevelDataAndDimensions

    • 引用位置: 参数/方法调用/构造调用
    • 关联成员: LevelDataAndDimensions.WorldDataAndGenSettings(), WorldDataAndGenSettings()
  • LevelStorageSource

    • 引用位置: 返回值
  • PrimaryLevelData

    • 引用位置: 构造调用
    • 关联成员: PrimaryLevelData()
  • DirectoryValidator

    • 引用位置: 字段