376 lines
13 KiB
Java
376 lines
13 KiB
Java
package net.minecraft.client.gui.screens;
|
|
|
|
import com.mojang.authlib.minecraft.BanDetails;
|
|
import com.mojang.logging.LogUtils;
|
|
import com.mojang.realmsclient.RealmsMainScreen;
|
|
import com.mojang.realmsclient.gui.screens.RealmsNotificationsScreen;
|
|
import java.io.IOException;
|
|
import java.util.Objects;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.SharedConstants;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.GuiGraphics;
|
|
import net.minecraft.client.gui.components.AbstractWidget;
|
|
import net.minecraft.client.gui.components.Button;
|
|
import net.minecraft.client.gui.components.CommonButtons;
|
|
import net.minecraft.client.gui.components.LogoRenderer;
|
|
import net.minecraft.client.gui.components.PlainTextButton;
|
|
import net.minecraft.client.gui.components.SplashRenderer;
|
|
import net.minecraft.client.gui.components.SpriteIconButton;
|
|
import net.minecraft.client.gui.components.Tooltip;
|
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
|
import net.minecraft.client.gui.components.toasts.SystemToast;
|
|
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
|
|
import net.minecraft.client.gui.screens.multiplayer.SafetyScreen;
|
|
import net.minecraft.client.gui.screens.options.AccessibilityOptionsScreen;
|
|
import net.minecraft.client.gui.screens.options.LanguageSelectScreen;
|
|
import net.minecraft.client.gui.screens.options.OptionsScreen;
|
|
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
|
|
import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen;
|
|
import net.minecraft.client.renderer.PanoramaRenderer;
|
|
import net.minecraft.client.renderer.texture.TextureManager;
|
|
import net.minecraft.client.resources.language.I18n;
|
|
import net.minecraft.network.chat.CommonComponents;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.level.levelgen.WorldOptions;
|
|
import net.minecraft.world.level.levelgen.presets.WorldPresets;
|
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.slf4j.Logger;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class TitleScreen extends Screen {
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
private static final Component TITLE = Component.translatable("narrator.screen.title");
|
|
private static final Component COPYRIGHT_TEXT = Component.translatable("title.credits");
|
|
private static final String DEMO_LEVEL_ID = "Demo_World";
|
|
private static final float FADE_IN_TIME = 2000.0F;
|
|
@Nullable
|
|
private SplashRenderer splash;
|
|
private Button resetDemoButton;
|
|
/**
|
|
* A screen generated by realms for notifications drawn in addition to the main menu (buttons and such from both are drawn at the same time). May be null.
|
|
*/
|
|
@Nullable
|
|
private RealmsNotificationsScreen realmsNotificationsScreen;
|
|
private float panoramaFade = 1.0F;
|
|
private boolean fading;
|
|
private long fadeInStart;
|
|
private final LogoRenderer logoRenderer;
|
|
|
|
public TitleScreen() {
|
|
this(false);
|
|
}
|
|
|
|
public TitleScreen(boolean fading) {
|
|
this(fading, null);
|
|
}
|
|
|
|
public TitleScreen(boolean fading, @Nullable LogoRenderer logoRenderer) {
|
|
super(TITLE);
|
|
this.fading = fading;
|
|
this.logoRenderer = (LogoRenderer)Objects.requireNonNullElseGet(logoRenderer, () -> new LogoRenderer(false));
|
|
}
|
|
|
|
/**
|
|
* Is there currently a realms notification screen, and are realms notifications enabled?
|
|
*/
|
|
private boolean realmsNotificationsEnabled() {
|
|
return this.realmsNotificationsScreen != null;
|
|
}
|
|
|
|
@Override
|
|
public void tick() {
|
|
if (this.realmsNotificationsEnabled()) {
|
|
this.realmsNotificationsScreen.tick();
|
|
}
|
|
}
|
|
|
|
public static void registerTextures(TextureManager textureManager) {
|
|
textureManager.registerForNextReload(LogoRenderer.MINECRAFT_LOGO);
|
|
textureManager.registerForNextReload(LogoRenderer.MINECRAFT_EDITION);
|
|
textureManager.registerForNextReload(PanoramaRenderer.PANORAMA_OVERLAY);
|
|
CUBE_MAP.registerTextures(textureManager);
|
|
}
|
|
|
|
@Override
|
|
public boolean isPauseScreen() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldCloseOnEsc() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected void init() {
|
|
if (this.splash == null) {
|
|
this.splash = this.minecraft.getSplashManager().getSplash();
|
|
}
|
|
|
|
int i = this.font.width(COPYRIGHT_TEXT);
|
|
int j = this.width - i - 2;
|
|
int k = 24;
|
|
int l = this.height / 4 + 48;
|
|
if (this.minecraft.isDemo()) {
|
|
l = this.createDemoMenuOptions(l, 24);
|
|
} else {
|
|
l = this.createNormalMenuOptions(l, 24);
|
|
}
|
|
|
|
l = this.createTestWorldButton(l, 24);
|
|
SpriteIconButton spriteIconButton = this.addRenderableWidget(
|
|
CommonButtons.language(
|
|
20, button -> this.minecraft.setScreen(new LanguageSelectScreen(this, this.minecraft.options, this.minecraft.getLanguageManager())), true
|
|
)
|
|
);
|
|
int var10001 = this.width / 2 - 124;
|
|
l += 36;
|
|
spriteIconButton.setPosition(var10001, l);
|
|
this.addRenderableWidget(
|
|
Button.builder(Component.translatable("menu.options"), button -> this.minecraft.setScreen(new OptionsScreen(this, this.minecraft.options)))
|
|
.bounds(this.width / 2 - 100, l, 98, 20)
|
|
.build()
|
|
);
|
|
this.addRenderableWidget(Button.builder(Component.translatable("menu.quit"), button -> this.minecraft.stop()).bounds(this.width / 2 + 2, l, 98, 20).build());
|
|
SpriteIconButton spriteIconButton2 = this.addRenderableWidget(
|
|
CommonButtons.accessibility(20, button -> this.minecraft.setScreen(new AccessibilityOptionsScreen(this, this.minecraft.options)), true)
|
|
);
|
|
spriteIconButton2.setPosition(this.width / 2 + 104, l);
|
|
this.addRenderableWidget(
|
|
new PlainTextButton(j, this.height - 10, i, 10, COPYRIGHT_TEXT, button -> this.minecraft.setScreen(new CreditsAndAttributionScreen(this)), this.font)
|
|
);
|
|
if (this.realmsNotificationsScreen == null) {
|
|
this.realmsNotificationsScreen = new RealmsNotificationsScreen();
|
|
}
|
|
|
|
if (this.realmsNotificationsEnabled()) {
|
|
this.realmsNotificationsScreen.init(this.minecraft, this.width, this.height);
|
|
}
|
|
}
|
|
|
|
private int createTestWorldButton(int y, int rowHeight) {
|
|
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
|
this.addRenderableWidget(
|
|
Button.builder(Component.literal("Create Test World"), button -> CreateWorldScreen.testWorld(this.minecraft, this))
|
|
.bounds(this.width / 2 - 100, y += rowHeight, 200, 20)
|
|
.build()
|
|
);
|
|
}
|
|
|
|
return y;
|
|
}
|
|
|
|
private int createNormalMenuOptions(int y, int rowHeight) {
|
|
this.addRenderableWidget(
|
|
Button.builder(Component.translatable("menu.singleplayer"), button -> this.minecraft.setScreen(new SelectWorldScreen(this)))
|
|
.bounds(this.width / 2 - 100, y, 200, 20)
|
|
.build()
|
|
);
|
|
Component component = this.getMultiplayerDisabledReason();
|
|
boolean bl = component == null;
|
|
Tooltip tooltip = component != null ? Tooltip.create(component) : null;
|
|
int var6;
|
|
this.addRenderableWidget(Button.builder(Component.translatable("menu.multiplayer"), button -> {
|
|
Screen screen = (Screen)(this.minecraft.options.skipMultiplayerWarning ? new JoinMultiplayerScreen(this) : new SafetyScreen(this));
|
|
this.minecraft.setScreen(screen);
|
|
}).bounds(this.width / 2 - 100, var6 = y + rowHeight, 200, 20).tooltip(tooltip).build()).active = bl;
|
|
this.addRenderableWidget(
|
|
Button.builder(Component.translatable("menu.online"), button -> this.minecraft.setScreen(new RealmsMainScreen(this)))
|
|
.bounds(this.width / 2 - 100, y = var6 + rowHeight, 200, 20)
|
|
.tooltip(tooltip)
|
|
.build()
|
|
)
|
|
.active = bl;
|
|
return y;
|
|
}
|
|
|
|
@Nullable
|
|
private Component getMultiplayerDisabledReason() {
|
|
if (this.minecraft.allowsMultiplayer()) {
|
|
return null;
|
|
} else if (this.minecraft.isNameBanned()) {
|
|
return Component.translatable("title.multiplayer.disabled.banned.name");
|
|
} else {
|
|
BanDetails banDetails = this.minecraft.multiplayerBan();
|
|
if (banDetails != null) {
|
|
return banDetails.expires() != null
|
|
? Component.translatable("title.multiplayer.disabled.banned.temporary")
|
|
: Component.translatable("title.multiplayer.disabled.banned.permanent");
|
|
} else {
|
|
return Component.translatable("title.multiplayer.disabled");
|
|
}
|
|
}
|
|
}
|
|
|
|
private int createDemoMenuOptions(int y, int rowHeight) {
|
|
boolean bl = this.checkDemoWorldPresence();
|
|
this.addRenderableWidget(
|
|
Button.builder(
|
|
Component.translatable("menu.playdemo"),
|
|
button -> {
|
|
if (bl) {
|
|
this.minecraft.createWorldOpenFlows().openWorld("Demo_World", () -> this.minecraft.setScreen(this));
|
|
} else {
|
|
this.minecraft
|
|
.createWorldOpenFlows()
|
|
.createFreshLevel("Demo_World", MinecraftServer.DEMO_SETTINGS, WorldOptions.DEMO_OPTIONS, WorldPresets::createNormalWorldDimensions, this);
|
|
}
|
|
}
|
|
)
|
|
.bounds(this.width / 2 - 100, y, 200, 20)
|
|
.build()
|
|
);
|
|
int var4;
|
|
this.resetDemoButton = this.addRenderableWidget(
|
|
Button.builder(
|
|
Component.translatable("menu.resetdemo"),
|
|
button -> {
|
|
LevelStorageSource levelStorageSource = this.minecraft.getLevelSource();
|
|
|
|
try (LevelStorageSource.LevelStorageAccess levelStorageAccess = levelStorageSource.createAccess("Demo_World")) {
|
|
if (levelStorageAccess.hasWorldData()) {
|
|
this.minecraft
|
|
.setScreen(
|
|
new ConfirmScreen(
|
|
this::confirmDemo,
|
|
Component.translatable("selectWorld.deleteQuestion"),
|
|
Component.translatable("selectWorld.deleteWarning", MinecraftServer.DEMO_SETTINGS.levelName()),
|
|
Component.translatable("selectWorld.deleteButton"),
|
|
CommonComponents.GUI_CANCEL
|
|
)
|
|
);
|
|
}
|
|
} catch (IOException var8) {
|
|
SystemToast.onWorldAccessFailure(this.minecraft, "Demo_World");
|
|
LOGGER.warn("Failed to access demo world", (Throwable)var8);
|
|
}
|
|
}
|
|
)
|
|
.bounds(this.width / 2 - 100, var4 = y + rowHeight, 200, 20)
|
|
.build()
|
|
);
|
|
this.resetDemoButton.active = bl;
|
|
return var4;
|
|
}
|
|
|
|
private boolean checkDemoWorldPresence() {
|
|
try {
|
|
boolean var2;
|
|
try (LevelStorageSource.LevelStorageAccess levelStorageAccess = this.minecraft.getLevelSource().createAccess("Demo_World")) {
|
|
var2 = levelStorageAccess.hasWorldData();
|
|
}
|
|
|
|
return var2;
|
|
} catch (IOException var6) {
|
|
SystemToast.onWorldAccessFailure(this.minecraft, "Demo_World");
|
|
LOGGER.warn("Failed to read demo world data", (Throwable)var6);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
|
if (this.fadeInStart == 0L && this.fading) {
|
|
this.fadeInStart = Util.getMillis();
|
|
}
|
|
|
|
float f = 1.0F;
|
|
if (this.fading) {
|
|
float g = (float)(Util.getMillis() - this.fadeInStart) / 2000.0F;
|
|
if (g > 1.0F) {
|
|
this.fading = false;
|
|
this.panoramaFade = 1.0F;
|
|
} else {
|
|
g = Mth.clamp(g, 0.0F, 1.0F);
|
|
f = Mth.clampedMap(g, 0.5F, 1.0F, 0.0F, 1.0F);
|
|
this.panoramaFade = Mth.clampedMap(g, 0.0F, 0.5F, 0.0F, 1.0F);
|
|
}
|
|
|
|
this.fadeWidgets(f);
|
|
}
|
|
|
|
this.renderPanorama(guiGraphics, partialTick);
|
|
int i = Mth.ceil(f * 255.0F) << 24;
|
|
if ((i & -67108864) != 0) {
|
|
super.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
this.logoRenderer.renderLogo(guiGraphics, this.width, f);
|
|
if (this.splash != null && !this.minecraft.options.hideSplashTexts().get()) {
|
|
this.splash.render(guiGraphics, this.width, this.font, i);
|
|
}
|
|
|
|
String string = "Minecraft " + SharedConstants.getCurrentVersion().getName();
|
|
if (this.minecraft.isDemo()) {
|
|
string = string + " Demo";
|
|
} else {
|
|
string = string + ("release".equalsIgnoreCase(this.minecraft.getVersionType()) ? "" : "/" + this.minecraft.getVersionType());
|
|
}
|
|
|
|
if (Minecraft.checkModStatus().shouldReportAsModified()) {
|
|
string = string + I18n.get("menu.modded");
|
|
}
|
|
|
|
guiGraphics.drawString(this.font, string, 2, this.height - 10, 16777215 | i);
|
|
if (this.realmsNotificationsEnabled() && f >= 1.0F) {
|
|
this.realmsNotificationsScreen.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void fadeWidgets(float alpha) {
|
|
for (GuiEventListener guiEventListener : this.children()) {
|
|
if (guiEventListener instanceof AbstractWidget abstractWidget) {
|
|
abstractWidget.setAlpha(alpha);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
|
}
|
|
|
|
@Override
|
|
protected void renderPanorama(GuiGraphics guiGraphics, float partialTick) {
|
|
PANORAMA.render(guiGraphics, this.width, this.height, this.panoramaFade, partialTick);
|
|
}
|
|
|
|
@Override
|
|
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
|
return super.mouseClicked(mouseX, mouseY, button)
|
|
? true
|
|
: this.realmsNotificationsEnabled() && this.realmsNotificationsScreen.mouseClicked(mouseX, mouseY, button);
|
|
}
|
|
|
|
@Override
|
|
public void removed() {
|
|
if (this.realmsNotificationsScreen != null) {
|
|
this.realmsNotificationsScreen.removed();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void added() {
|
|
super.added();
|
|
if (this.realmsNotificationsScreen != null) {
|
|
this.realmsNotificationsScreen.added();
|
|
}
|
|
}
|
|
|
|
private void confirmDemo(boolean confirmed) {
|
|
if (confirmed) {
|
|
try (LevelStorageSource.LevelStorageAccess levelStorageAccess = this.minecraft.getLevelSource().createAccess("Demo_World")) {
|
|
levelStorageAccess.deleteLevel();
|
|
} catch (IOException var7) {
|
|
SystemToast.onWorldDeleteFailure(this.minecraft, "Demo_World");
|
|
LOGGER.warn("Failed to delete demo world", (Throwable)var7);
|
|
}
|
|
}
|
|
|
|
this.minecraft.setScreen(this);
|
|
}
|
|
}
|