generated from MrSphay/codex-agent-repository-kit
167 lines
7.3 KiB
Java
167 lines
7.3 KiB
Java
package com.vinlanx.explosionoverhaul.client;
|
|
|
|
import com.vinlanx.explosionoverhaul.Config;
|
|
import net.minecraft.client.gui.GuiGraphics;
|
|
import net.minecraft.client.gui.screens.Screen;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
|
|
public class FirstTimeScreen extends Screen {
|
|
private static final int FRAME_WIDTH = 768;
|
|
private static final int FRAME_HEIGHT = 432;
|
|
private static final int COLUMNS = 10;
|
|
private static final int ROWS = 10;
|
|
private static final int FRAME_COUNT = COLUMNS * ROWS;
|
|
private static final int BORDER = 0xFFFF7A70;
|
|
private static final int BORDER_HOVER = 0xFFFF9B91;
|
|
private static final Choice[] CHOICES = new Choice[] {
|
|
new Choice("gui_screen_1.png", 10, 18, "REALISTIC", Config.Client.ParticleRenderMode.REALISTIC),
|
|
new Choice("gui_screen_2.png", 8, 18, "VANILLA-LIKE", Config.Client.ParticleRenderMode.VANILA),
|
|
new Choice("gui_screen_3.png", 28, 35, "REALISTIC 2", Config.Client.ParticleRenderMode.REALISTIC_2)
|
|
};
|
|
|
|
private final Rect[] cardRects = new Rect[] { Rect.empty(), Rect.empty(), Rect.empty() };
|
|
private long animationStartedAt;
|
|
private boolean resetAnimationTimer = true;
|
|
|
|
public FirstTimeScreen() {
|
|
super(Component.literal("Explosion Overhaul Setup"));
|
|
}
|
|
|
|
@Override
|
|
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
|
graphics.fill(0, 0, this.width, this.height, 0xFF050506);
|
|
this.drawAmbient(graphics);
|
|
|
|
int top = Math.max(18, this.height / 14);
|
|
graphics.drawCenteredString(this.font, Component.literal("Choose Your Explosion Style."), this.width / 2, top, 0xFFFF9900);
|
|
graphics.drawCenteredString(this.font, Component.literal("You can change this anytime in the config"), this.width / 2, top + 25, 0xFFE5E5E5);
|
|
graphics.drawCenteredString(this.font, Component.literal("The game may differ from the animations because compression has altered them."), this.width / 2, top + 48, 0xFF9C9C9C);
|
|
|
|
int availableCardH = Math.max(54, (this.height - top - 150) / 2);
|
|
int cardW = Math.min(300, Math.max(120, (this.width - 190) / 2));
|
|
cardW = Math.min(cardW, availableCardH * FRAME_WIDTH / FRAME_HEIGHT);
|
|
int cardH = cardW * FRAME_HEIGHT / FRAME_WIDTH;
|
|
int gap = Math.max(34, this.width / 28);
|
|
int firstX = this.width / 2 - cardW - gap / 2;
|
|
int secondX = this.width / 2 + gap / 2;
|
|
int firstRowY = top + 70;
|
|
int secondRowY = firstRowY + cardH + 40;
|
|
|
|
this.cardRects[0] = new Rect(firstX, firstRowY, cardW, cardH + 34);
|
|
this.cardRects[1] = new Rect(secondX, firstRowY, cardW, cardH + 34);
|
|
this.cardRects[2] = new Rect((this.width - cardW) / 2, secondRowY, cardW, cardH + 34);
|
|
|
|
long elapsed = this.resetAnimationTimer ? 0L : Math.max(0L, System.currentTimeMillis() - this.animationStartedAt);
|
|
for (int i = 0; i < CHOICES.length; ++i) {
|
|
this.drawChoice(graphics, CHOICES[i], this.cardRects[i], this.cardRects[i].contains(mouseX, mouseY), elapsed);
|
|
}
|
|
if (this.resetAnimationTimer) {
|
|
this.animationStartedAt = System.currentTimeMillis();
|
|
this.resetAnimationTimer = false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
|
if (button == 0) {
|
|
for (int i = 0; i < this.cardRects.length; ++i) {
|
|
if (this.cardRects[i].contains(mouseX, mouseY)) {
|
|
this.finish(CHOICES[i]);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return super.mouseClicked(mouseX, mouseY, button);
|
|
}
|
|
|
|
private void finish(Choice choice) {
|
|
Config.CLIENT.particleRenderMode.set(choice.mode);
|
|
Config.CLIENT.glowTextureQuality.set(Config.Client.GlowTextureQuality.QUALITY_256);
|
|
Config.CLIENT.firstLaunchComplete.set(true);
|
|
Config.CLIENT.introSetupComplete.set(true);
|
|
Config.CLIENT_SPEC.save();
|
|
this.onClose();
|
|
}
|
|
|
|
private void drawChoice(GuiGraphics graphics, Choice choice, Rect rect, boolean hovered, long elapsedMillis) {
|
|
int imageX = rect.x;
|
|
int imageY = rect.y;
|
|
int imageW = rect.w;
|
|
int imageH = rect.w * FRAME_HEIGHT / FRAME_WIDTH;
|
|
graphics.fill(imageX - 6, imageY - 6, imageX + imageW + 6, imageY + imageH + 6, hovered ? BORDER_HOVER : BORDER);
|
|
this.drawSheetFrame(graphics, choice, choice.currentFrame(elapsedMillis, 65L), imageX, imageY, imageW, imageH);
|
|
graphics.drawCenteredString(this.font, Component.literal(choice.label), imageX + imageW / 2, imageY + imageH + 16, 0xFFFFFFFF);
|
|
}
|
|
|
|
private void drawSheetFrame(GuiGraphics graphics, Choice choice, int frame, int x, int y, int width, int height) {
|
|
int clamped = Math.max(0, Math.min(frame, FRAME_COUNT - 1));
|
|
int u = clamped % COLUMNS * FRAME_WIDTH;
|
|
int v = clamped / COLUMNS * FRAME_HEIGHT;
|
|
float scaleX = (float)width / (float)FRAME_WIDTH;
|
|
float scaleY = (float)height / (float)FRAME_HEIGHT;
|
|
graphics.pose().pushPose();
|
|
graphics.pose().translate(x, y, 0.0F);
|
|
graphics.pose().scale(scaleX, scaleY, 1.0F);
|
|
graphics.blit(choice.texture, 0, 0, (float)u, (float)v, FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH * COLUMNS, FRAME_HEIGHT * ROWS);
|
|
graphics.pose().popPose();
|
|
}
|
|
|
|
private void drawAmbient(GuiGraphics graphics) {
|
|
for (int i = 0; i < 48; ++i) {
|
|
int x = Math.floorMod(i * 173 + 19, Math.max(1, this.width));
|
|
int y = Math.floorMod(i * 97 + 53, Math.max(1, this.height));
|
|
int color = i % 7 == 0 ? 0xFFFFB347 : 0xFF414141;
|
|
graphics.fill(x, y, x + 1, y + 1, color);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldCloseOnEsc() {
|
|
return false;
|
|
}
|
|
|
|
private static final class Choice {
|
|
private final ResourceLocation texture;
|
|
private final int firstFrame;
|
|
private final int lastFrameExclusive;
|
|
private final String label;
|
|
private final Config.Client.ParticleRenderMode mode;
|
|
|
|
private Choice(String fileName, int firstFrame, int lastFrameExclusive, String label, Config.Client.ParticleRenderMode mode) {
|
|
this.texture = ResourceLocation.fromNamespaceAndPath("explosionoverhaul", "intro_gui/preview/" + fileName);
|
|
this.firstFrame = firstFrame;
|
|
this.lastFrameExclusive = lastFrameExclusive;
|
|
this.label = label;
|
|
this.mode = mode;
|
|
}
|
|
|
|
private int currentFrame(long elapsedMillis, long frameTimeMillis) {
|
|
int span = Math.max(1, this.lastFrameExclusive - this.firstFrame);
|
|
return this.firstFrame + (int)((elapsedMillis / frameTimeMillis) % span);
|
|
}
|
|
}
|
|
|
|
private static final class Rect {
|
|
private final int x;
|
|
private final int y;
|
|
private final int w;
|
|
private final int h;
|
|
|
|
private Rect(int x, int y, int w, int h) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.w = w;
|
|
this.h = h;
|
|
}
|
|
|
|
private static Rect empty() {
|
|
return new Rect(0, 0, 0, 0);
|
|
}
|
|
|
|
private boolean contains(double mouseX, double mouseY) {
|
|
return mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.w && mouseY < this.y + this.h;
|
|
}
|
|
}
|
|
}
|