package de.shiewk.bedrockdeathscreen.client.screen; import de.shiewk.bedrockdeathscreen.client.screen.components.BedrockDeathScreenButton; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.DeathScreen; import net.minecraft.client.gui.screen.MessageScreen; import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.render.RenderLayer; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; import java.awt.*; public class BedrockDeathScreen extends DeathScreen { public static final long CURSOR_HAND = GLFW.glfwCreateStandardCursor(GLFW.GLFW_POINTING_HAND_CURSOR); public static final Identifier VIGNETTE = Identifier.of("bedrockdeathscreen", "textures/gui/death_vignette.png"); private final long screenCreationTime; private final Text message; private Text scoreText = Text.empty(); private static final Text menuMessage = Text.translatable("deathScreen.titleScreen"); private static final MutableText confirmQuitText = Text.translatable("deathScreen.quit.confirm"); private final boolean hardcore; private final int deg = (int) (Math.random() * 360); private boolean confirmingExit = false; private boolean wasHoveringButtons = false; private BedrockDeathScreenButton respawnButton; private BedrockDeathScreenButton menuButton; public BedrockDeathScreen(@Nullable Text message, boolean isHardcore) { super(message, isHardcore); this.message = message; this.hardcore = isHardcore; screenCreationTime = Util.getMeasuringTimeNano(); } public float getTotalScreenTime(){ return (Util.getMeasuringTimeNano() - screenCreationTime) / 1000000f; } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { final float totalScreenTime = getTotalScreenTime(); context.fill(0, 0, width, height, new Color(0, 0, 0, (int) Math.min(80, totalScreenTime/4f)).getRGB()); if (totalScreenTime > 750.0f){ final int backOpacity = (int) Math.min(255, (totalScreenTime - 750f) / 10f); context.drawTexture( RenderLayer::getGuiTextured, VIGNETTE, 0, 0, 0.0F, 0.0F, context.getScaledWindowWidth(), context.getScaledWindowHeight(), context.getScaledWindowWidth(), context.getScaledWindowHeight(), 0xffffff + (backOpacity << 24) ); context.fill(0, 0, width, height, new Color(50, 0, 0, (int) (backOpacity/2.5)).getRGB()); final int textOpacity = (int) Math.min(255, (totalScreenTime - 750f) / 3f); if (textOpacity > 3){ context.getMatrices().push(); context.getMatrices().scale(2F, 2F, 2F); context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2 / 2, (int) (this.height / 3.5 / 2 - 10), new Color(255, 255, 255, textOpacity).getRGB()); context.getMatrices().pop(); if (message != null) { context.drawCenteredTextWithShadow(this.textRenderer, this.message, this.width / 2, (int) (this.height / 3.5), new Color(255, 255, 255, textOpacity).getRGB()); } } final int scoreTextOpacity = (int) Math.min(255, (totalScreenTime - 1250f) / 3f); if (scoreTextOpacity > 3){ context.drawCenteredTextWithShadow(this.textRenderer, this.scoreText, this.width / 2, (int) (this.height / 3.5) + 12, new Color(255, 255, 255, scoreTextOpacity).getRGB()); } } if (confirmingExit){ context.drawCenteredTextWithShadow(this.textRenderer, BedrockDeathScreen.confirmQuitText, this.width / 2, this.height - this.height / 3 - 24, new Color(255, 255, 255, 255).getRGB()); } respawnButton.render(context, mouseX, mouseY, delta); menuButton.render(context, mouseX, mouseY, delta); boolean hoveringButton = menuButton.isHovered() || respawnButton.isHovered(); if (hoveringButton != wasHoveringButtons){ wasHoveringButtons = hoveringButton; assert client != null; long window = client.getWindow().getHandle(); if (hoveringButton){ GLFW.glfwSetCursor(window, CURSOR_HAND); } else { GLFW.glfwSetCursor(window, 0); } } } @Override protected void init() { Text respawnMessage = this.hardcore ? Text.translatable("deathScreen.spectate") : Text.translatable("deathScreen.respawn"); if (this.client != null && this.client.player != null) { this.scoreText = Text.translatable("deathScreen.score.value", Text.literal(Integer.toString(this.client.player.getScore())).formatted(Formatting.YELLOW)); } respawnButton = new BedrockDeathScreenButton( width / 2 - 75, height - height / 3 - 9, 150, 22, respawnMessage, textRenderer, 0x3c8527, 0x1d4d13, 0x4f913c, 0x1d4d13, 0xffffff, 0x1d4d13, 0x4a7142, true, () -> (int) Math.min(255, (getTotalScreenTime() - 1250f) / 3f), this::respawn ); menuButton = new BedrockDeathScreenButton( width / 2 - 75, height - height / 3 + 21, 150, 22, menuMessage, textRenderer, 0xd0d1d4, 0x58585a, 0xe3e3e5, 0xb1b2b5, 0x1e1e1e, 0xb1b2b5, 0xe0e0e1, false, () -> (int) Math.min(255, (getTotalScreenTime() - 1750f) / 3f), this::clickQuitButton ); } private void respawn(){ if (this.client != null && this.client.player != null) { this.client.player.requestRespawn(); } } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (respawnButton.mouseClicked(mouseX, mouseY, button)) return true; return menuButton.mouseClicked(mouseX, mouseY, button); } @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { respawnButton.mouseReleased(mouseX, mouseY, button); menuButton.mouseReleased(mouseX, mouseY, button); return true; } private void quitLevel(){ if (this.client != null && this.client.world != null) { this.client.world.disconnect(); } if (this.client != null) { this.client.disconnect(new MessageScreen(Text.translatable("menu.savingLevel"))); this.client.setScreen(new TitleScreen()); } } public float calcCamPitch() { return 20; } public float calcCamYaw(){ return deg < 180 ? deg : deg-360; } public float calcCameraOffset(){ final double e = Math.E; final double del = getTotalScreenTime() / 600d; final double ep = Math.pow(e, del); return (float) (ep / (1d + ep) * 7d + 2d); } @Override public void close() { assert client != null; long window = client.getWindow().getHandle(); GLFW.glfwSetCursor(window, 0); super.close(); } @Override public void removed() { assert client != null; long window = client.getWindow().getHandle(); GLFW.glfwSetCursor(window, 0); super.removed(); } private void clickQuitButton() { if (confirmingExit) { this.quitLevel(); } else { confirmingExit = true; int y = menuButton.getY(); menuButton.setY(respawnButton.getY()); respawnButton.setY(y); menuButton.resetClickedState(); respawnButton.resetClickedState(); } } }