345 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			345 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.gui.screens;
 | |
| 
 | |
| import com.google.common.collect.Lists;
 | |
| import com.google.gson.JsonArray;
 | |
| import com.google.gson.JsonElement;
 | |
| import com.google.gson.JsonObject;
 | |
| import com.mojang.logging.LogUtils;
 | |
| import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
 | |
| import it.unimi.dsi.fastutil.ints.IntSet;
 | |
| import java.io.BufferedReader;
 | |
| import java.io.IOException;
 | |
| import java.io.Reader;
 | |
| import java.util.List;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.ChatFormatting;
 | |
| import net.minecraft.client.GameNarrator;
 | |
| import net.minecraft.client.Minecraft;
 | |
| import net.minecraft.client.gui.GuiGraphics;
 | |
| import net.minecraft.client.gui.components.LogoRenderer;
 | |
| import net.minecraft.client.gui.render.TextureSetup;
 | |
| import net.minecraft.client.renderer.RenderPipelines;
 | |
| import net.minecraft.client.renderer.blockentity.TheEndPortalRenderer;
 | |
| import net.minecraft.client.renderer.texture.TextureManager;
 | |
| import net.minecraft.network.chat.CommonComponents;
 | |
| import net.minecraft.network.chat.Component;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import net.minecraft.sounds.Music;
 | |
| import net.minecraft.sounds.Musics;
 | |
| import net.minecraft.util.FormattedCharSequence;
 | |
| import net.minecraft.util.GsonHelper;
 | |
| import net.minecraft.util.RandomSource;
 | |
| import org.apache.commons.lang3.StringUtils;
 | |
| import org.slf4j.Logger;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class WinScreen extends Screen {
 | |
| 	private static final ResourceLocation VIGNETTE_LOCATION = ResourceLocation.withDefaultNamespace("textures/misc/credits_vignette.png");
 | |
| 	private static final Logger LOGGER = LogUtils.getLogger();
 | |
| 	private static final Component SECTION_HEADING = Component.literal("============").withStyle(ChatFormatting.WHITE);
 | |
| 	private static final String NAME_PREFIX = "           ";
 | |
| 	private static final String OBFUSCATE_TOKEN = "" + ChatFormatting.WHITE + ChatFormatting.OBFUSCATED + ChatFormatting.GREEN + ChatFormatting.AQUA;
 | |
| 	private static final float SPEEDUP_FACTOR = 5.0F;
 | |
| 	private static final float SPEEDUP_FACTOR_FAST = 15.0F;
 | |
| 	private static final ResourceLocation END_POEM_LOCATION = ResourceLocation.withDefaultNamespace("texts/end.txt");
 | |
| 	private static final ResourceLocation CREDITS_LOCATION = ResourceLocation.withDefaultNamespace("texts/credits.json");
 | |
| 	private static final ResourceLocation POSTCREDITS_LOCATION = ResourceLocation.withDefaultNamespace("texts/postcredits.txt");
 | |
| 	private final boolean poem;
 | |
| 	private final Runnable onFinished;
 | |
| 	private float scroll;
 | |
| 	private List<FormattedCharSequence> lines;
 | |
| 	private List<Component> narratorComponents;
 | |
| 	private IntSet centeredLines;
 | |
| 	private int totalScrollLength;
 | |
| 	private boolean speedupActive;
 | |
| 	private final IntSet speedupModifiers = new IntOpenHashSet();
 | |
| 	private float scrollSpeed;
 | |
| 	private final float unmodifiedScrollSpeed;
 | |
| 	private int direction;
 | |
| 	private final LogoRenderer logoRenderer = new LogoRenderer(false);
 | |
| 
 | |
| 	public WinScreen(boolean poem, Runnable onFinished) {
 | |
| 		super(GameNarrator.NO_TITLE);
 | |
| 		this.poem = poem;
 | |
| 		this.onFinished = onFinished;
 | |
| 		if (!poem) {
 | |
| 			this.unmodifiedScrollSpeed = 0.75F;
 | |
| 		} else {
 | |
| 			this.unmodifiedScrollSpeed = 0.5F;
 | |
| 		}
 | |
| 
 | |
| 		this.direction = 1;
 | |
| 		this.scrollSpeed = this.unmodifiedScrollSpeed;
 | |
| 	}
 | |
| 
 | |
| 	private float calculateScrollSpeed() {
 | |
| 		return this.speedupActive
 | |
| 			? this.unmodifiedScrollSpeed * (5.0F + this.speedupModifiers.size() * 15.0F) * this.direction
 | |
| 			: this.unmodifiedScrollSpeed * this.direction;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void tick() {
 | |
| 		this.minecraft.getMusicManager().tick();
 | |
| 		this.minecraft.getSoundManager().tick(false);
 | |
| 		float f = this.totalScrollLength + this.height + this.height + 24;
 | |
| 		if (this.scroll > f) {
 | |
| 			this.respawn();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
 | |
| 		if (keyCode == 265) {
 | |
| 			this.direction = -1;
 | |
| 		} else if (keyCode == 341 || keyCode == 345) {
 | |
| 			this.speedupModifiers.add(keyCode);
 | |
| 		} else if (keyCode == 32) {
 | |
| 			this.speedupActive = true;
 | |
| 		}
 | |
| 
 | |
| 		this.scrollSpeed = this.calculateScrollSpeed();
 | |
| 		return super.keyPressed(keyCode, scanCode, modifiers);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
 | |
| 		if (keyCode == 265) {
 | |
| 			this.direction = 1;
 | |
| 		}
 | |
| 
 | |
| 		if (keyCode == 32) {
 | |
| 			this.speedupActive = false;
 | |
| 		} else if (keyCode == 341 || keyCode == 345) {
 | |
| 			this.speedupModifiers.remove(keyCode);
 | |
| 		}
 | |
| 
 | |
| 		this.scrollSpeed = this.calculateScrollSpeed();
 | |
| 		return super.keyReleased(keyCode, scanCode, modifiers);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void onClose() {
 | |
| 		this.respawn();
 | |
| 	}
 | |
| 
 | |
| 	private void respawn() {
 | |
| 		this.onFinished.run();
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void init() {
 | |
| 		if (this.lines == null) {
 | |
| 			this.lines = Lists.<FormattedCharSequence>newArrayList();
 | |
| 			this.narratorComponents = Lists.<Component>newArrayList();
 | |
| 			this.centeredLines = new IntOpenHashSet();
 | |
| 			if (this.poem) {
 | |
| 				this.wrapCreditsIO(END_POEM_LOCATION, this::addPoemFile);
 | |
| 			}
 | |
| 
 | |
| 			this.wrapCreditsIO(CREDITS_LOCATION, this::addCreditsFile);
 | |
| 			if (this.poem) {
 | |
| 				this.wrapCreditsIO(POSTCREDITS_LOCATION, this::addPoemFile);
 | |
| 			}
 | |
| 
 | |
| 			this.totalScrollLength = this.lines.size() * 12;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public Component getNarrationMessage() {
 | |
| 		return CommonComponents.joinForNarration((Component[])this.narratorComponents.toArray(Component[]::new));
 | |
| 	}
 | |
| 
 | |
| 	private void wrapCreditsIO(ResourceLocation location, WinScreen.CreditsReader reader) {
 | |
| 		try {
 | |
| 			Reader reader2 = this.minecraft.getResourceManager().openAsReader(location);
 | |
| 
 | |
| 			try {
 | |
| 				reader.read(reader2);
 | |
| 			} catch (Throwable var7) {
 | |
| 				if (reader2 != null) {
 | |
| 					try {
 | |
| 						reader2.close();
 | |
| 					} catch (Throwable var6) {
 | |
| 						var7.addSuppressed(var6);
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				throw var7;
 | |
| 			}
 | |
| 
 | |
| 			if (reader2 != null) {
 | |
| 				reader2.close();
 | |
| 			}
 | |
| 		} catch (Exception var8) {
 | |
| 			LOGGER.error("Couldn't load credits from file {}", location, var8);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private void addPoemFile(Reader reader) throws IOException {
 | |
| 		BufferedReader bufferedReader = new BufferedReader(reader);
 | |
| 		RandomSource randomSource = RandomSource.create(8124371L);
 | |
| 
 | |
| 		String string;
 | |
| 		while ((string = bufferedReader.readLine()) != null) {
 | |
| 			string = string.replaceAll("PLAYERNAME", this.minecraft.getUser().getName());
 | |
| 
 | |
| 			int i;
 | |
| 			while ((i = string.indexOf(OBFUSCATE_TOKEN)) != -1) {
 | |
| 				String string2 = string.substring(0, i);
 | |
| 				String string3 = string.substring(i + OBFUSCATE_TOKEN.length());
 | |
| 				string = string2 + ChatFormatting.WHITE + ChatFormatting.OBFUSCATED + "XXXXXXXX".substring(0, randomSource.nextInt(4) + 3) + string3;
 | |
| 			}
 | |
| 
 | |
| 			this.addPoemLines(string);
 | |
| 			this.addEmptyLine();
 | |
| 		}
 | |
| 
 | |
| 		for (int i = 0; i < 8; i++) {
 | |
| 			this.addEmptyLine();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private void addCreditsFile(Reader reader) {
 | |
| 		for (JsonElement jsonElement : GsonHelper.parseArray(reader)) {
 | |
| 			JsonObject jsonObject = jsonElement.getAsJsonObject();
 | |
| 			String string = jsonObject.get("section").getAsString();
 | |
| 			this.addCreditsLine(SECTION_HEADING, true, false);
 | |
| 			this.addCreditsLine(Component.literal(string).withStyle(ChatFormatting.YELLOW), true, true);
 | |
| 			this.addCreditsLine(SECTION_HEADING, true, false);
 | |
| 			this.addEmptyLine();
 | |
| 			this.addEmptyLine();
 | |
| 
 | |
| 			for (JsonElement jsonElement2 : jsonObject.getAsJsonArray("disciplines")) {
 | |
| 				JsonObject jsonObject2 = jsonElement2.getAsJsonObject();
 | |
| 				String string2 = jsonObject2.get("discipline").getAsString();
 | |
| 				if (StringUtils.isNotEmpty(string2)) {
 | |
| 					this.addCreditsLine(Component.literal(string2).withStyle(ChatFormatting.YELLOW), true, true);
 | |
| 					this.addEmptyLine();
 | |
| 					this.addEmptyLine();
 | |
| 				}
 | |
| 
 | |
| 				for (JsonElement jsonElement3 : jsonObject2.getAsJsonArray("titles")) {
 | |
| 					JsonObject jsonObject3 = jsonElement3.getAsJsonObject();
 | |
| 					String string3 = jsonObject3.get("title").getAsString();
 | |
| 					JsonArray jsonArray4 = jsonObject3.getAsJsonArray("names");
 | |
| 					this.addCreditsLine(Component.literal(string3).withStyle(ChatFormatting.GRAY), false, true);
 | |
| 
 | |
| 					for (JsonElement jsonElement4 : jsonArray4) {
 | |
| 						String string4 = jsonElement4.getAsString();
 | |
| 						this.addCreditsLine(Component.literal("           ").append(string4).withStyle(ChatFormatting.WHITE), false, true);
 | |
| 					}
 | |
| 
 | |
| 					this.addEmptyLine();
 | |
| 					this.addEmptyLine();
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private void addEmptyLine() {
 | |
| 		this.lines.add(FormattedCharSequence.EMPTY);
 | |
| 		this.narratorComponents.add(CommonComponents.EMPTY);
 | |
| 	}
 | |
| 
 | |
| 	private void addPoemLines(String text) {
 | |
| 		Component component = Component.literal(text);
 | |
| 		this.lines.addAll(this.minecraft.font.split(component, 256));
 | |
| 		this.narratorComponents.add(component);
 | |
| 	}
 | |
| 
 | |
| 	private void addCreditsLine(Component text, boolean centered, boolean narrate) {
 | |
| 		if (centered) {
 | |
| 			this.centeredLines.add(this.lines.size());
 | |
| 		}
 | |
| 
 | |
| 		this.lines.add(text.getVisualOrderText());
 | |
| 		if (narrate) {
 | |
| 			this.narratorComponents.add(text);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
 | |
| 		super.render(guiGraphics, mouseX, mouseY, partialTick);
 | |
| 		this.renderVignette(guiGraphics);
 | |
| 		this.scroll = Math.max(0.0F, this.scroll + partialTick * this.scrollSpeed);
 | |
| 		int i = this.width / 2 - 128;
 | |
| 		int j = this.height + 50;
 | |
| 		float f = -this.scroll;
 | |
| 		guiGraphics.pose().pushMatrix();
 | |
| 		guiGraphics.pose().translate(0.0F, f);
 | |
| 		guiGraphics.nextStratum();
 | |
| 		this.logoRenderer.renderLogo(guiGraphics, this.width, 1.0F, j);
 | |
| 		int k = j + 100;
 | |
| 
 | |
| 		for (int l = 0; l < this.lines.size(); l++) {
 | |
| 			if (l == this.lines.size() - 1) {
 | |
| 				float g = k + f - (this.height / 2 - 6);
 | |
| 				if (g < 0.0F) {
 | |
| 					guiGraphics.pose().translate(0.0F, -g);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (k + f + 12.0F + 8.0F > 0.0F && k + f < this.height) {
 | |
| 				FormattedCharSequence formattedCharSequence = (FormattedCharSequence)this.lines.get(l);
 | |
| 				if (this.centeredLines.contains(l)) {
 | |
| 					guiGraphics.drawCenteredString(this.font, formattedCharSequence, i + 128, k, -1);
 | |
| 				} else {
 | |
| 					guiGraphics.drawString(this.font, formattedCharSequence, i, k, -1);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			k += 12;
 | |
| 		}
 | |
| 
 | |
| 		guiGraphics.pose().popMatrix();
 | |
| 	}
 | |
| 
 | |
| 	private void renderVignette(GuiGraphics guiGraphics) {
 | |
| 		guiGraphics.blit(RenderPipelines.VIGNETTE, VIGNETTE_LOCATION, 0, 0, 0.0F, 0.0F, this.width, this.height, this.width, this.height);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
 | |
| 		if (this.poem) {
 | |
| 			TextureManager textureManager = Minecraft.getInstance().getTextureManager();
 | |
| 			TextureSetup textureSetup = TextureSetup.doubleTexture(
 | |
| 				textureManager.getTexture(TheEndPortalRenderer.END_SKY_LOCATION).getTextureView(),
 | |
| 				textureManager.getTexture(TheEndPortalRenderer.END_PORTAL_LOCATION).getTextureView()
 | |
| 			);
 | |
| 			guiGraphics.fill(RenderPipelines.END_PORTAL, textureSetup, 0, 0, this.width, this.height);
 | |
| 		} else {
 | |
| 			super.renderBackground(guiGraphics, mouseX, mouseY, partialTick);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void renderMenuBackground(GuiGraphics guiGraphics, int x, int y, int width, int height) {
 | |
| 		float f = this.scroll * 0.5F;
 | |
| 		Screen.renderMenuBackgroundTexture(guiGraphics, Screen.MENU_BACKGROUND, 0, 0, 0.0F, f, width, height);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean isPauseScreen() {
 | |
| 		return !this.poem;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void removed() {
 | |
| 		this.minecraft.getMusicManager().stopPlaying(Musics.CREDITS);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public Music getBackgroundMusic() {
 | |
| 		return Musics.CREDITS;
 | |
| 	}
 | |
| 
 | |
| 	@FunctionalInterface
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	interface CreditsReader {
 | |
| 		void read(Reader reader) throws IOException;
 | |
| 	}
 | |
| }
 |