package net.minecraft.client.gui.screens; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.Util; import net.minecraft.client.GameNarrator; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.narration.NarratedElementType; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.network.chat.Component; import net.minecraft.server.level.progress.StoringChunkProgressListener; import net.minecraft.util.ARGB; import net.minecraft.util.Mth; import net.minecraft.world.level.chunk.status.ChunkStatus; @Environment(EnvType.CLIENT) public class LevelLoadingScreen extends Screen { private static final long NARRATION_DELAY_MS = 2000L; private final StoringChunkProgressListener progressListener; private long lastNarration = -1L; private boolean done; private static final Object2IntMap COLORS = Util.make(new Object2IntOpenHashMap<>(), object2IntOpenHashMap -> { object2IntOpenHashMap.defaultReturnValue(0); object2IntOpenHashMap.put(ChunkStatus.EMPTY, 5526612); object2IntOpenHashMap.put(ChunkStatus.STRUCTURE_STARTS, 10066329); object2IntOpenHashMap.put(ChunkStatus.STRUCTURE_REFERENCES, 6250897); object2IntOpenHashMap.put(ChunkStatus.BIOMES, 8434258); object2IntOpenHashMap.put(ChunkStatus.NOISE, 13750737); object2IntOpenHashMap.put(ChunkStatus.SURFACE, 7497737); object2IntOpenHashMap.put(ChunkStatus.CARVERS, 3159410); object2IntOpenHashMap.put(ChunkStatus.FEATURES, 2213376); object2IntOpenHashMap.put(ChunkStatus.INITIALIZE_LIGHT, 13421772); object2IntOpenHashMap.put(ChunkStatus.LIGHT, 16769184); object2IntOpenHashMap.put(ChunkStatus.SPAWN, 15884384); object2IntOpenHashMap.put(ChunkStatus.FULL, 16777215); }); public LevelLoadingScreen(StoringChunkProgressListener progressListener) { super(GameNarrator.NO_TITLE); this.progressListener = progressListener; } @Override public boolean shouldCloseOnEsc() { return false; } @Override protected boolean shouldNarrateNavigation() { return false; } @Override public void removed() { this.done = true; this.triggerImmediateNarration(true); } @Override protected void updateNarratedWidget(NarrationElementOutput narrationElementOutput) { if (this.done) { narrationElementOutput.add(NarratedElementType.TITLE, Component.translatable("narrator.loading.done")); } else { narrationElementOutput.add(NarratedElementType.TITLE, this.getFormattedProgress()); } } private Component getFormattedProgress() { return Component.translatable("loading.progress", Mth.clamp(this.progressListener.getProgress(), 0, 100)); } @Override public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { super.render(guiGraphics, mouseX, mouseY, partialTick); long l = Util.getMillis(); if (l - this.lastNarration > 2000L) { this.lastNarration = l; this.triggerImmediateNarration(true); } int i = this.width / 2; int j = this.height / 2; renderChunks(guiGraphics, this.progressListener, i, j, 2, 0); int k = this.progressListener.getDiameter() + 9 + 2; guiGraphics.drawCenteredString(this.font, this.getFormattedProgress(), i, j - k, 16777215); } public static void renderChunks(GuiGraphics guiGraphics, StoringChunkProgressListener progressListener, int x, int y, int size, int spacing) { int i = size + spacing; int j = progressListener.getFullDiameter(); int k = j * i - spacing; int l = progressListener.getDiameter(); int m = l * i - spacing; int n = x - m / 2; int o = y - m / 2; int p = k / 2 + 1; int q = -16772609; if (spacing != 0) { guiGraphics.fill(x - p, y - p, x - p + 1, y + p, -16772609); guiGraphics.fill(x + p - 1, y - p, x + p, y + p, -16772609); guiGraphics.fill(x - p, y - p, x + p, y - p + 1, -16772609); guiGraphics.fill(x - p, y + p - 1, x + p, y + p, -16772609); } for (int r = 0; r < l; r++) { for (int s = 0; s < l; s++) { ChunkStatus chunkStatus = progressListener.getStatus(r, s); int t = n + r * i; int u = o + s * i; guiGraphics.fill(t, u, t + size, u + size, ARGB.opaque(COLORS.getInt(chunkStatus))); } } } }