194 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.gui.screens;
 | |
| 
 | |
| import com.google.common.collect.Lists;
 | |
| import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
 | |
| import java.util.List;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.ChatFormatting;
 | |
| import net.minecraft.client.gui.GuiGraphics;
 | |
| import net.minecraft.client.gui.components.Button;
 | |
| import net.minecraft.client.multiplayer.ClientLevel;
 | |
| import net.minecraft.client.renderer.RenderPipelines;
 | |
| import net.minecraft.network.chat.ClickEvent;
 | |
| import net.minecraft.network.chat.CommonComponents;
 | |
| import net.minecraft.network.chat.Component;
 | |
| import net.minecraft.network.chat.Style;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class DeathScreen extends Screen {
 | |
| 	private static final ResourceLocation DRAFT_REPORT_SPRITE = ResourceLocation.withDefaultNamespace("icon/draft_report");
 | |
| 	/**
 | |
| 	 * The integer value containing the number of ticks that have passed since the player's death
 | |
| 	 */
 | |
| 	private int delayTicker;
 | |
| 	private final Component causeOfDeath;
 | |
| 	private final boolean hardcore;
 | |
| 	private Component deathScore;
 | |
| 	private final List<Button> exitButtons = Lists.<Button>newArrayList();
 | |
| 	@Nullable
 | |
| 	private Button exitToTitleButton;
 | |
| 
 | |
| 	public DeathScreen(@Nullable Component causeOfDeath, boolean hardcore) {
 | |
| 		super(Component.translatable(hardcore ? "deathScreen.title.hardcore" : "deathScreen.title"));
 | |
| 		this.causeOfDeath = causeOfDeath;
 | |
| 		this.hardcore = hardcore;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void init() {
 | |
| 		this.delayTicker = 0;
 | |
| 		this.exitButtons.clear();
 | |
| 		Component component = this.hardcore ? Component.translatable("deathScreen.spectate") : Component.translatable("deathScreen.respawn");
 | |
| 		this.exitButtons.add(this.addRenderableWidget(Button.builder(component, button -> {
 | |
| 			this.minecraft.player.respawn();
 | |
| 			button.active = false;
 | |
| 		}).bounds(this.width / 2 - 100, this.height / 4 + 72, 200, 20).build()));
 | |
| 		this.exitToTitleButton = this.addRenderableWidget(
 | |
| 			Button.builder(
 | |
| 					Component.translatable("deathScreen.titleScreen"),
 | |
| 					button -> this.minecraft.getReportingContext().draftReportHandled(this.minecraft, this, this::handleExitToTitleScreen, true)
 | |
| 				)
 | |
| 				.bounds(this.width / 2 - 100, this.height / 4 + 96, 200, 20)
 | |
| 				.build()
 | |
| 		);
 | |
| 		this.exitButtons.add(this.exitToTitleButton);
 | |
| 		this.setButtonsActive(false);
 | |
| 		this.deathScore = Component.translatable(
 | |
| 			"deathScreen.score.value", Component.literal(Integer.toString(this.minecraft.player.getScore())).withStyle(ChatFormatting.YELLOW)
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean shouldCloseOnEsc() {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	private void handleExitToTitleScreen() {
 | |
| 		if (this.hardcore) {
 | |
| 			this.exitToTitleScreen();
 | |
| 		} else {
 | |
| 			ConfirmScreen confirmScreen = new DeathScreen.TitleConfirmScreen(
 | |
| 				bl -> {
 | |
| 					if (bl) {
 | |
| 						this.exitToTitleScreen();
 | |
| 					} else {
 | |
| 						this.minecraft.player.respawn();
 | |
| 						this.minecraft.setScreen(null);
 | |
| 					}
 | |
| 				},
 | |
| 				Component.translatable("deathScreen.quit.confirm"),
 | |
| 				CommonComponents.EMPTY,
 | |
| 				Component.translatable("deathScreen.titleScreen"),
 | |
| 				Component.translatable("deathScreen.respawn")
 | |
| 			);
 | |
| 			this.minecraft.setScreen(confirmScreen);
 | |
| 			confirmScreen.setDelay(20);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private void exitToTitleScreen() {
 | |
| 		if (this.minecraft.level != null) {
 | |
| 			this.minecraft.level.disconnect(ClientLevel.DEFAULT_QUIT_MESSAGE);
 | |
| 		}
 | |
| 
 | |
| 		this.minecraft.disconnectWithSavingScreen();
 | |
| 		this.minecraft.setScreen(new TitleScreen());
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
 | |
| 		super.render(guiGraphics, mouseX, mouseY, partialTick);
 | |
| 		guiGraphics.pose().pushMatrix();
 | |
| 		guiGraphics.pose().scale(2.0F, 2.0F);
 | |
| 		guiGraphics.drawCenteredString(this.font, this.title, this.width / 2 / 2, 30, -1);
 | |
| 		guiGraphics.pose().popMatrix();
 | |
| 		if (this.causeOfDeath != null) {
 | |
| 			guiGraphics.drawCenteredString(this.font, this.causeOfDeath, this.width / 2, 85, -1);
 | |
| 		}
 | |
| 
 | |
| 		guiGraphics.drawCenteredString(this.font, this.deathScore, this.width / 2, 100, -1);
 | |
| 		if (this.causeOfDeath != null && mouseY > 85 && mouseY < 85 + 9) {
 | |
| 			Style style = this.getClickedComponentStyleAt(mouseX);
 | |
| 			guiGraphics.renderComponentHoverEffect(this.font, style, mouseX, mouseY);
 | |
| 		}
 | |
| 
 | |
| 		if (this.exitToTitleButton != null && this.minecraft.getReportingContext().hasDraftReport()) {
 | |
| 			guiGraphics.blitSprite(
 | |
| 				RenderPipelines.GUI_TEXTURED,
 | |
| 				DRAFT_REPORT_SPRITE,
 | |
| 				this.exitToTitleButton.getX() + this.exitToTitleButton.getWidth() - 17,
 | |
| 				this.exitToTitleButton.getY() + 3,
 | |
| 				15,
 | |
| 				15
 | |
| 			);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
 | |
| 		renderDeathBackground(guiGraphics, this.width, this.height);
 | |
| 	}
 | |
| 
 | |
| 	static void renderDeathBackground(GuiGraphics guiGraphics, int width, int height) {
 | |
| 		guiGraphics.fillGradient(0, 0, width, height, 1615855616, -1602211792);
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	private Style getClickedComponentStyleAt(int x) {
 | |
| 		if (this.causeOfDeath == null) {
 | |
| 			return null;
 | |
| 		} else {
 | |
| 			int i = this.minecraft.font.width(this.causeOfDeath);
 | |
| 			int j = this.width / 2 - i / 2;
 | |
| 			int k = this.width / 2 + i / 2;
 | |
| 			return x >= j && x <= k ? this.minecraft.font.getSplitter().componentStyleAtWidth(this.causeOfDeath, x - j) : null;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean mouseClicked(double mouseX, double mouseY, int button) {
 | |
| 		if (this.causeOfDeath != null && mouseY > 85.0 && mouseY < 85 + 9) {
 | |
| 			Style style = this.getClickedComponentStyleAt((int)mouseX);
 | |
| 			if (style != null && style.getClickEvent() instanceof ClickEvent.OpenUrl openUrl) {
 | |
| 				return clickUrlAction(this.minecraft, this, openUrl.uri());
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return super.mouseClicked(mouseX, mouseY, button);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean isPauseScreen() {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void tick() {
 | |
| 		super.tick();
 | |
| 		this.delayTicker++;
 | |
| 		if (this.delayTicker == 20) {
 | |
| 			this.setButtonsActive(true);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private void setButtonsActive(boolean active) {
 | |
| 		for (Button button : this.exitButtons) {
 | |
| 			button.active = active;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	public static class TitleConfirmScreen extends ConfirmScreen {
 | |
| 		public TitleConfirmScreen(BooleanConsumer booleanConsumer, Component component, Component component2, Component component3, Component component4) {
 | |
| 			super(booleanConsumer, component, component2, component3, component4);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
 | |
| 			DeathScreen.renderDeathBackground(guiGraphics, this.width, this.height);
 | |
| 		}
 | |
| 	}
 | |
| }
 |