295 lines
11 KiB
Java
295 lines
11 KiB
Java
package net.minecraft.client.gui.screens;
|
|
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.collect.Lists;
|
|
import com.mojang.logging.LogUtils;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.GuiGraphics;
|
|
import net.minecraft.client.gui.components.Button;
|
|
import net.minecraft.client.gui.components.EditBox;
|
|
import net.minecraft.client.gui.components.ObjectSelectionList;
|
|
import net.minecraft.client.gui.navigation.CommonInputs;
|
|
import net.minecraft.client.gui.screens.worldselection.WorldCreationContext;
|
|
import net.minecraft.core.Holder;
|
|
import net.minecraft.core.HolderGetter;
|
|
import net.minecraft.core.RegistryAccess;
|
|
import net.minecraft.core.Holder.Reference;
|
|
import net.minecraft.core.registries.Registries;
|
|
import net.minecraft.network.chat.CommonComponents;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.resources.ResourceKey;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.tags.FlatLevelGeneratorPresetTags;
|
|
import net.minecraft.world.flag.FeatureFlagSet;
|
|
import net.minecraft.world.level.biome.Biome;
|
|
import net.minecraft.world.level.biome.Biomes;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.dimension.DimensionType;
|
|
import net.minecraft.world.level.levelgen.flat.FlatLayerInfo;
|
|
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorPreset;
|
|
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
|
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.slf4j.Logger;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class PresetFlatWorldScreen extends Screen {
|
|
static final ResourceLocation SLOT_SPRITE = ResourceLocation.withDefaultNamespace("container/slot");
|
|
static final Logger LOGGER = LogUtils.getLogger();
|
|
private static final int SLOT_BG_SIZE = 18;
|
|
private static final int SLOT_STAT_HEIGHT = 20;
|
|
private static final int SLOT_BG_X = 1;
|
|
private static final int SLOT_BG_Y = 1;
|
|
private static final int SLOT_FG_X = 2;
|
|
private static final int SLOT_FG_Y = 2;
|
|
private static final ResourceKey<Biome> DEFAULT_BIOME = Biomes.PLAINS;
|
|
public static final Component UNKNOWN_PRESET = Component.translatable("flat_world_preset.unknown");
|
|
/**
|
|
* The parent GUI
|
|
*/
|
|
private final CreateFlatWorldScreen parent;
|
|
private Component shareText;
|
|
private Component listText;
|
|
private PresetFlatWorldScreen.PresetsList list;
|
|
private Button selectButton;
|
|
EditBox export;
|
|
FlatLevelGeneratorSettings settings;
|
|
|
|
public PresetFlatWorldScreen(CreateFlatWorldScreen parent) {
|
|
super(Component.translatable("createWorld.customize.presets.title"));
|
|
this.parent = parent;
|
|
}
|
|
|
|
@Nullable
|
|
private static FlatLayerInfo getLayerInfoFromString(HolderGetter<Block> blockGetter, String layerInfo, int currentHeight) {
|
|
List<String> list = Splitter.on('*').limit(2).splitToList(layerInfo);
|
|
int i;
|
|
String string;
|
|
if (list.size() == 2) {
|
|
string = (String)list.get(1);
|
|
|
|
try {
|
|
i = Math.max(Integer.parseInt((String)list.get(0)), 0);
|
|
} catch (NumberFormatException var11) {
|
|
LOGGER.error("Error while parsing flat world string", (Throwable)var11);
|
|
return null;
|
|
}
|
|
} else {
|
|
string = (String)list.get(0);
|
|
i = 1;
|
|
}
|
|
|
|
int j = Math.min(currentHeight + i, DimensionType.Y_SIZE);
|
|
int k = j - currentHeight;
|
|
|
|
Optional<Reference<Block>> optional;
|
|
try {
|
|
optional = blockGetter.get(ResourceKey.create(Registries.BLOCK, ResourceLocation.parse(string)));
|
|
} catch (Exception var10) {
|
|
LOGGER.error("Error while parsing flat world string", (Throwable)var10);
|
|
return null;
|
|
}
|
|
|
|
if (optional.isEmpty()) {
|
|
LOGGER.error("Error while parsing flat world string => Unknown block, {}", string);
|
|
return null;
|
|
} else {
|
|
return new FlatLayerInfo(k, (Block)((Reference)optional.get()).value());
|
|
}
|
|
}
|
|
|
|
private static List<FlatLayerInfo> getLayersInfoFromString(HolderGetter<Block> blockGetter, String layerInfo) {
|
|
List<FlatLayerInfo> list = Lists.<FlatLayerInfo>newArrayList();
|
|
String[] strings = layerInfo.split(",");
|
|
int i = 0;
|
|
|
|
for (String string : strings) {
|
|
FlatLayerInfo flatLayerInfo = getLayerInfoFromString(blockGetter, string, i);
|
|
if (flatLayerInfo == null) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
list.add(flatLayerInfo);
|
|
i += flatLayerInfo.getHeight();
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static FlatLevelGeneratorSettings fromString(
|
|
HolderGetter<Block> blockGetter,
|
|
HolderGetter<Biome> biomeGetter,
|
|
HolderGetter<StructureSet> structureSetGetter,
|
|
HolderGetter<PlacedFeature> placedFeatureGetter,
|
|
String settings,
|
|
FlatLevelGeneratorSettings layerGenerationSettings
|
|
) {
|
|
Iterator<String> iterator = Splitter.on(';').split(settings).iterator();
|
|
if (!iterator.hasNext()) {
|
|
return FlatLevelGeneratorSettings.getDefault(biomeGetter, structureSetGetter, placedFeatureGetter);
|
|
} else {
|
|
List<FlatLayerInfo> list = getLayersInfoFromString(blockGetter, (String)iterator.next());
|
|
if (list.isEmpty()) {
|
|
return FlatLevelGeneratorSettings.getDefault(biomeGetter, structureSetGetter, placedFeatureGetter);
|
|
} else {
|
|
Reference<Biome> reference = biomeGetter.getOrThrow(DEFAULT_BIOME);
|
|
Holder<Biome> holder = reference;
|
|
if (iterator.hasNext()) {
|
|
String string = (String)iterator.next();
|
|
holder = (Holder<Biome>)Optional.ofNullable(ResourceLocation.tryParse(string))
|
|
.map(resourceLocation -> ResourceKey.create(Registries.BIOME, resourceLocation))
|
|
.flatMap(biomeGetter::get)
|
|
.orElseGet(() -> {
|
|
LOGGER.warn("Invalid biome: {}", string);
|
|
return reference;
|
|
});
|
|
}
|
|
|
|
return layerGenerationSettings.withBiomeAndLayers(list, layerGenerationSettings.structureOverrides(), holder);
|
|
}
|
|
}
|
|
}
|
|
|
|
static String save(FlatLevelGeneratorSettings levelGeneratorSettings) {
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
for (int i = 0; i < levelGeneratorSettings.getLayersInfo().size(); i++) {
|
|
if (i > 0) {
|
|
stringBuilder.append(",");
|
|
}
|
|
|
|
stringBuilder.append(levelGeneratorSettings.getLayersInfo().get(i));
|
|
}
|
|
|
|
stringBuilder.append(";");
|
|
stringBuilder.append(
|
|
levelGeneratorSettings.getBiome().unwrapKey().map(ResourceKey::location).orElseThrow(() -> new IllegalStateException("Biome not registered"))
|
|
);
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
@Override
|
|
protected void init() {
|
|
this.shareText = Component.translatable("createWorld.customize.presets.share");
|
|
this.listText = Component.translatable("createWorld.customize.presets.list");
|
|
this.export = new EditBox(this.font, 50, 40, this.width - 100, 20, this.shareText);
|
|
this.export.setMaxLength(1230);
|
|
WorldCreationContext worldCreationContext = this.parent.parent.getUiState().getSettings();
|
|
RegistryAccess registryAccess = worldCreationContext.worldgenLoadContext();
|
|
FeatureFlagSet featureFlagSet = worldCreationContext.dataConfiguration().enabledFeatures();
|
|
HolderGetter<Biome> holderGetter = registryAccess.lookupOrThrow(Registries.BIOME);
|
|
HolderGetter<StructureSet> holderGetter2 = registryAccess.lookupOrThrow(Registries.STRUCTURE_SET);
|
|
HolderGetter<PlacedFeature> holderGetter3 = registryAccess.lookupOrThrow(Registries.PLACED_FEATURE);
|
|
HolderGetter<Block> holderGetter4 = registryAccess.lookupOrThrow(Registries.BLOCK).filterFeatures(featureFlagSet);
|
|
this.export.setValue(save(this.parent.settings()));
|
|
this.settings = this.parent.settings();
|
|
this.addWidget(this.export);
|
|
this.list = this.addRenderableWidget(new PresetFlatWorldScreen.PresetsList(registryAccess, featureFlagSet));
|
|
this.selectButton = this.addRenderableWidget(
|
|
Button.builder(
|
|
Component.translatable("createWorld.customize.presets.select"),
|
|
button -> {
|
|
FlatLevelGeneratorSettings flatLevelGeneratorSettings = fromString(
|
|
holderGetter4, holderGetter, holderGetter2, holderGetter3, this.export.getValue(), this.settings
|
|
);
|
|
this.parent.setConfig(flatLevelGeneratorSettings);
|
|
this.minecraft.setScreen(this.parent);
|
|
}
|
|
)
|
|
.bounds(this.width / 2 - 155, this.height - 28, 150, 20)
|
|
.build()
|
|
);
|
|
this.addRenderableWidget(
|
|
Button.builder(CommonComponents.GUI_CANCEL, button -> this.minecraft.setScreen(this.parent)).bounds(this.width / 2 + 5, this.height - 28, 150, 20).build()
|
|
);
|
|
this.updateButtonValidity(this.list.getSelected() != null);
|
|
}
|
|
|
|
@Override
|
|
public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
|
|
return this.list.mouseScrolled(mouseX, mouseY, scrollX, scrollY);
|
|
}
|
|
|
|
@Override
|
|
public void resize(Minecraft minecraft, int width, int height) {
|
|
String string = this.export.getValue();
|
|
this.init(minecraft, width, height);
|
|
this.export.setValue(string);
|
|
}
|
|
|
|
@Override
|
|
public void onClose() {
|
|
this.minecraft.setScreen(this.parent);
|
|
}
|
|
|
|
@Override
|
|
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
|
super.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
guiGraphics.pose().pushPose();
|
|
guiGraphics.pose().translate(0.0F, 0.0F, 400.0F);
|
|
guiGraphics.drawCenteredString(this.font, this.title, this.width / 2, 8, 16777215);
|
|
guiGraphics.drawString(this.font, this.shareText, 51, 30, 10526880);
|
|
guiGraphics.drawString(this.font, this.listText, 51, 68, 10526880);
|
|
guiGraphics.pose().popPose();
|
|
this.export.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
}
|
|
|
|
public void updateButtonValidity(boolean valid) {
|
|
this.selectButton.active = valid || this.export.getValue().length() > 1;
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
class PresetsList extends ObjectSelectionList<net.minecraft.client.gui.screens.PresetFlatWorldScreen.PresetsList.Entry> {
|
|
public PresetsList(final RegistryAccess registryAccess, final FeatureFlagSet flags) {
|
|
super(PresetFlatWorldScreen.this.minecraft, PresetFlatWorldScreen.this.width, PresetFlatWorldScreen.this.height - 117, 80, 24);
|
|
|
|
for (Holder<FlatLevelGeneratorPreset> holder : registryAccess.lookupOrThrow(Registries.FLAT_LEVEL_GENERATOR_PRESET)
|
|
.getTagOrEmpty(FlatLevelGeneratorPresetTags.VISIBLE)) {
|
|
Set<Block> set = (Set<Block>)holder.value()
|
|
.settings()
|
|
.getLayersInfo()
|
|
.stream()
|
|
.map(flatLayerInfo -> flatLayerInfo.getBlockState().getBlock())
|
|
.filter(block -> !block.isEnabled(flags))
|
|
.collect(Collectors.toSet());
|
|
if (!set.isEmpty()) {
|
|
PresetFlatWorldScreen.LOGGER
|
|
.info(
|
|
"Discarding flat world preset {} since it contains experimental blocks {}",
|
|
holder.unwrapKey().map(resourceKey -> resourceKey.location().toString()).orElse("<unknown>"),
|
|
set
|
|
);
|
|
} else {
|
|
this.addEntry(new net.minecraft.client.gui.screens.PresetFlatWorldScreen.PresetsList.Entry(this, holder));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setSelected(@Nullable net.minecraft.client.gui.screens.PresetFlatWorldScreen.PresetsList.Entry entry) {
|
|
super.setSelected(entry);
|
|
PresetFlatWorldScreen.this.updateButtonValidity(entry != null);
|
|
}
|
|
|
|
@Override
|
|
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
if (super.keyPressed(keyCode, scanCode, modifiers)) {
|
|
return true;
|
|
} else {
|
|
if (CommonInputs.selected(keyCode) && this.getSelected() != null) {
|
|
this.getSelected().select();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|