Code/net/minecraft/client/gui/screens/TitleScreen.java

363 lines
15 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 javax.annotation.Nullable;
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 net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.slf4j.Logger;
@OnlyIn(Dist.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;
@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 p_96733_) {
this(p_96733_, null);
}
public TitleScreen(boolean p_265779_, @Nullable LogoRenderer p_265067_) {
super(TITLE);
this.fading = p_265779_;
this.logoRenderer = Objects.requireNonNullElseGet(p_265067_, () -> new LogoRenderer(false));
}
private boolean realmsNotificationsEnabled() {
return this.realmsNotificationsScreen != null;
}
@Override
public void tick() {
if (this.realmsNotificationsEnabled()) {
this.realmsNotificationsScreen.tick();
}
}
public static void registerTextures(TextureManager p_378459_) {
p_378459_.registerForNextReload(LogoRenderer.MINECRAFT_LOGO);
p_378459_.registerForNextReload(LogoRenderer.MINECRAFT_EDITION);
p_378459_.registerForNextReload(PanoramaRenderer.PANORAMA_OVERLAY);
CUBE_MAP.registerTextures(p_378459_);
}
@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, p_340809_ -> this.minecraft.setScreen(new LanguageSelectScreen(this, this.minecraft.options, this.minecraft.getLanguageManager())), true
)
);
int i1 = this.width / 2 - 124;
l += 36;
spriteiconbutton.setPosition(i1, l);
this.addRenderableWidget(
Button.builder(Component.translatable("menu.options"), p_340808_ -> 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"), p_280831_ -> this.minecraft.stop()).bounds(this.width / 2 + 2, l, 98, 20).build()
);
SpriteIconButton spriteiconbutton1 = this.addRenderableWidget(
CommonButtons.accessibility(20, p_340810_ -> this.minecraft.setScreen(new AccessibilityOptionsScreen(this, this.minecraft.options)), true)
);
spriteiconbutton1.setPosition(this.width / 2 + 104, l);
this.addRenderableWidget(
new PlainTextButton(
j, this.height - 10, i, 10, COPYRIGHT_TEXT, p_280834_ -> 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 p_368793_, int p_361481_) {
if (SharedConstants.IS_RUNNING_IN_IDE) {
this.addRenderableWidget(
Button.builder(Component.literal("Create Test World"), p_357674_ -> CreateWorldScreen.testWorld(this.minecraft, this))
.bounds(this.width / 2 - 100, p_368793_ += p_361481_, 200, 20)
.build()
);
}
return p_368793_;
}
private int createNormalMenuOptions(int p_96764_, int p_96765_) {
this.addRenderableWidget(
Button.builder(Component.translatable("menu.singleplayer"), p_280832_ -> this.minecraft.setScreen(new SelectWorldScreen(this)))
.bounds(this.width / 2 - 100, p_96764_, 200, 20)
.build()
);
Component component = this.getMultiplayerDisabledReason();
boolean flag = component == null;
Tooltip tooltip = component != null ? Tooltip.create(component) : null;
int i;
this.addRenderableWidget(Button.builder(Component.translatable("menu.multiplayer"), p_280833_ -> {
Screen screen = (Screen)(this.minecraft.options.skipMultiplayerWarning ? new JoinMultiplayerScreen(this) : new SafetyScreen(this));
this.minecraft.setScreen(screen);
}).bounds(this.width / 2 - 100, i = p_96764_ + p_96765_, 200, 20).tooltip(tooltip).build()).active = flag;
this.addRenderableWidget(
Button.builder(Component.translatable("menu.online"), p_325369_ -> this.minecraft.setScreen(new RealmsMainScreen(this)))
.bounds(this.width / 2 - 100, p_96764_ = i + p_96765_, 200, 20)
.tooltip(tooltip)
.build()
)
.active = flag;
return p_96764_;
}
@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 p_96773_, int p_96774_) {
boolean flag = this.checkDemoWorldPresence();
this.addRenderableWidget(Button.builder(Component.translatable("menu.playdemo"), p_325371_ -> {
if (flag) {
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, p_96773_, 200, 20).build());
int i;
this.resetDemoButton = this.addRenderableWidget(
Button.builder(
Component.translatable("menu.resetdemo"),
p_308197_ -> {
LevelStorageSource levelstoragesource = this.minecraft.getLevelSource();
try (LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = levelstoragesource.createAccess("Demo_World")) {
if (levelstoragesource$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 ioexception) {
SystemToast.onWorldAccessFailure(this.minecraft, "Demo_World");
LOGGER.warn("Failed to access demo world", (Throwable)ioexception);
}
}
)
.bounds(this.width / 2 - 100, i = p_96773_ + p_96774_, 200, 20)
.build()
);
this.resetDemoButton.active = flag;
return i;
}
private boolean checkDemoWorldPresence() {
try {
boolean flag;
try (LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = this.minecraft.getLevelSource().createAccess("Demo_World")) {
flag = levelstoragesource$levelstorageaccess.hasWorldData();
}
return flag;
} catch (IOException ioexception) {
SystemToast.onWorldAccessFailure(this.minecraft, "Demo_World");
LOGGER.warn("Failed to read demo world data", (Throwable)ioexception);
return false;
}
}
@Override
public void render(GuiGraphics p_282860_, int p_281753_, int p_283539_, float p_282628_) {
if (this.fadeInStart == 0L && this.fading) {
this.fadeInStart = Util.getMillis();
}
float f = 1.0F;
if (this.fading) {
float f1 = (float)(Util.getMillis() - this.fadeInStart) / 2000.0F;
if (f1 > 1.0F) {
this.fading = false;
this.panoramaFade = 1.0F;
} else {
f1 = Mth.clamp(f1, 0.0F, 1.0F);
f = Mth.clampedMap(f1, 0.5F, 1.0F, 0.0F, 1.0F);
this.panoramaFade = Mth.clampedMap(f1, 0.0F, 0.5F, 0.0F, 1.0F);
}
this.fadeWidgets(f);
}
this.renderPanorama(p_282860_, p_282628_);
int i = Mth.ceil(f * 255.0F) << 24;
if ((i & -67108864) != 0) {
super.render(p_282860_, p_281753_, p_283539_, p_282628_);
this.logoRenderer.renderLogo(p_282860_, this.width, f);
if (this.splash != null && !this.minecraft.options.hideSplashTexts().get()) {
this.splash.render(p_282860_, this.width, this.font, i);
}
String s = "Minecraft " + SharedConstants.getCurrentVersion().getName();
if (this.minecraft.isDemo()) {
s = s + " Demo";
} else {
s = s + ("release".equalsIgnoreCase(this.minecraft.getVersionType()) ? "" : "/" + this.minecraft.getVersionType());
}
if (Minecraft.checkModStatus().shouldReportAsModified()) {
s = s + I18n.get("menu.modded");
}
p_282860_.drawString(this.font, s, 2, this.height - 10, 16777215 | i);
if (this.realmsNotificationsEnabled() && f >= 1.0F) {
this.realmsNotificationsScreen.render(p_282860_, p_281753_, p_283539_, p_282628_);
}
}
}
private void fadeWidgets(float p_335005_) {
for (GuiEventListener guieventlistener : this.children()) {
if (guieventlistener instanceof AbstractWidget abstractwidget) {
abstractwidget.setAlpha(p_335005_);
}
}
}
@Override
public void renderBackground(GuiGraphics p_301363_, int p_300303_, int p_299762_, float p_300311_) {
}
@Override
protected void renderPanorama(GuiGraphics p_335595_, float p_331154_) {
PANORAMA.render(p_335595_, this.width, this.height, this.panoramaFade, p_331154_);
}
@Override
public boolean mouseClicked(double p_96735_, double p_96736_, int p_96737_) {
return super.mouseClicked(p_96735_, p_96736_, p_96737_) ? true : this.realmsNotificationsEnabled() && this.realmsNotificationsScreen.mouseClicked(p_96735_, p_96736_, p_96737_);
}
@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 p_96778_) {
if (p_96778_) {
try (LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = this.minecraft.getLevelSource().createAccess("Demo_World")) {
levelstoragesource$levelstorageaccess.deleteLevel();
} catch (IOException ioexception) {
SystemToast.onWorldDeleteFailure(this.minecraft, "Demo_World");
LOGGER.warn("Failed to delete demo world", (Throwable)ioexception);
}
}
this.minecraft.setScreen(this);
}
}