Decompile upstream Explosion Overhaul 0.2.3.0

This commit is contained in:
Gitea Runner
2026-05-04 10:03:58 +00:00
commit a8b3d372d7
212 changed files with 31516 additions and 0 deletions

View File

@@ -0,0 +1,634 @@
/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul.client;
import com.mojang.blaze3d.systems.RenderSystem;
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
import com.vinlanx.explosionoverhaul.ModSounds;
import com.vinlanx.explosionoverhaul.client.AnimationSoundManager;
import com.vinlanx.explosionoverhaul.client.BackgroundParticle;
import com.vinlanx.explosionoverhaul.client.FirstTimeScreen;
import com.vinlanx.explosionoverhaul.client.IntroMusicManager;
import com.vinlanx.explosionoverhaul.client.SpriteSheetAnimator;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
public class GuideSlidesScreen
extends Screen {
private static final SlideData[] SLIDES = new SlideData[]{new SlideData("claster_slide.png", 177, "Cluster TNT \u2013 If you place more than two TNT blocks next to each other, the explosion will be much stronger!"), new SlideData("cave_slide.png", 121, "Caves \u2013 If an explosion happens on the surface while you're underground, you'll hear a terrifying rumble, and the ground and dripstones will start to crumble!"), new SlideData("glass_slide.png", 98, "Glass Shattering \u2013 Explosions create shockwaves! Be careful when working with explosives near settlements."), new SlideData("lamp_slide.png", 154, "Lamp Flickering \u2013 If an explosion happens near lamps, the lights will start to flicker."), new SlideData("speed_of_sound_slide.png", 140, "Speed of Sound \u2013 Explosions travel at the speed of sound. You can also enable \"Epic Mode\" in the settings!")};
private static final int FRAME_WIDTH = 854;
private static final int FRAME_HEIGHT = 480;
private static final int COLUMNS = 14;
private static final int ROWS = 14;
private static final int FPS = 24;
private static final int COLOR_BG = -15921907;
private static final int COLOR_ACCENT_ORANGE = -881908;
private static final int COLOR_ACCENT_RED = -4250588;
private static final int COLOR_ACCENT_ROSE = -2529701;
private static final int COLOR_ACCENT_DARK_RED = -10939115;
private static final int COLOR_TEXT = -1;
private static final int COLOR_PROGRESS_BG = Integer.MIN_VALUE;
private static final int COLOR_PROGRESS_FILL = -881908;
private static final float FADE_IN_DURATION = 1.5f;
private static final float SLIDE_TRANSITION_DURATION = 1.0f;
private static final float AUTO_ADVANCE_DELAY = 0.5f;
private int currentSlideIndex = 0;
private SpriteSheetAnimator currentAnimator;
private float fadeAlpha = 0.0f;
private boolean fadingIn = true;
private float fadeTime = 0.0f;
private boolean isTransitioning = false;
private float transitionTime = 0.0f;
private int transitionToIndex = -1;
private float transitionAlpha = 0.0f;
private SpriteSheetAnimator nextAnimator;
private float autoAdvanceTimer = 0.0f;
private boolean waitingForAutoAdvance = false;
private Queue<Integer> transitionQueue = new LinkedList<Integer>();
private int animationX;
private int animationY;
private int animationWidth;
private int animationHeight;
private int progressBarX;
private int progressBarY;
private int progressBarWidth;
private int progressBarHeight;
private int leftArrowX;
private int leftArrowY;
private int arrowSize;
private int rightArrowX;
private int rightArrowY;
private boolean leftArrowHovered = false;
private boolean rightArrowHovered = false;
private float leftArrowScale = 1.0f;
private float rightArrowScale = 1.0f;
private int continueButtonX;
private int continueButtonY;
private int continueButtonWidth;
private int continueButtonHeight;
private boolean continueButtonHovered = false;
private float continueButtonScale = 1.0f;
private List<BackgroundParticle> particles = new ArrayList<BackgroundParticle>();
private RandomSource random = RandomSource.m_216327_();
private long lastFrameTime = System.currentTimeMillis();
private IntroMusicManager musicManager;
public GuideSlidesScreen() {
super((Component)Component.m_237113_((String)"Guide Slides"));
}
protected void m_7856_() {
int i;
super.m_7856_();
this.fadingIn = true;
this.fadeTime = 0.0f;
this.fadeAlpha = 0.0f;
this.isTransitioning = false;
this.waitingForAutoAdvance = false;
this.autoAdvanceTimer = 0.0f;
this.lastFrameTime = System.currentTimeMillis();
this.musicManager = IntroMusicManager.getInstance();
this.loadSlide(this.currentSlideIndex);
int maxWidth = (int)((float)this.f_96543_ * 0.76f);
int maxHeight = (int)((float)this.f_96544_ * 0.65f);
float aspectRatio = 1.7791667f;
if ((float)maxWidth / aspectRatio <= (float)maxHeight) {
this.animationWidth = maxWidth;
this.animationHeight = (int)((float)maxWidth / aspectRatio);
} else {
this.animationHeight = maxHeight;
this.animationWidth = (int)((float)maxHeight * aspectRatio);
}
this.animationX = (this.f_96543_ - this.animationWidth) / 2;
this.animationY = (int)((float)this.f_96544_ * 0.12f);
this.progressBarWidth = this.animationWidth;
this.progressBarHeight = (int)((float)this.f_96544_ * 0.025f);
this.progressBarX = this.animationX;
this.progressBarY = this.animationY + this.animationHeight + (int)((float)this.f_96544_ * 0.03f);
this.arrowSize = (int)((float)this.f_96544_ * 0.08f);
int arrowGap = (int)((float)this.f_96543_ * 0.02f);
this.leftArrowX = this.animationX - this.arrowSize - arrowGap;
this.leftArrowY = this.animationY + (this.animationHeight - this.arrowSize) / 2;
this.rightArrowX = this.animationX + this.animationWidth + arrowGap;
this.rightArrowY = this.animationY + (this.animationHeight - this.arrowSize) / 2;
this.continueButtonWidth = (int)((float)this.f_96543_ * 0.15f);
this.continueButtonHeight = (int)((float)this.f_96544_ * 0.06f);
this.continueButtonX = (this.f_96543_ - this.continueButtonWidth) / 2;
this.continueButtonY = (int)((float)this.f_96544_ * 0.88f);
for (i = 0; i < 30; ++i) {
this.particles.add(BackgroundParticle.createSpark(this.random, this.f_96543_, this.f_96544_));
}
for (i = 0; i < 10; ++i) {
this.particles.add(BackgroundParticle.createEmber(this.random, this.f_96543_, this.f_96544_));
}
for (i = 0; i < 5; ++i) {
this.particles.add(BackgroundParticle.createSmoke(this.random, this.f_96543_, this.f_96544_));
}
}
private void loadSlide(int index) {
if (index < 0 || index >= SLIDES.length) {
return;
}
if (this.currentAnimator != null) {
this.currentAnimator.close();
}
SlideData slide = SLIDES[index];
this.currentAnimator = new SpriteSheetAnimator(slide.spriteSheet, 854, 480, 14, 14, slide.totalFrames, 24);
this.currentAnimator.load();
this.registerSoundCallbacks(index, this.currentAnimator);
this.currentAnimator.play();
ExplosionOverhaul.LOGGER.info("Loaded guide slide {} - texture created fresh", (Object)index);
}
private void registerSoundCallbacks(int slideIndex, SpriteSheetAnimator animator) {
switch (slideIndex) {
case 0: {
animator.registerFrameCallback(43, AnimationSoundManager::playRandomFarPower2Sound);
animator.registerFrameCallback(132, AnimationSoundManager::playRandomSuperfar4Sound);
break;
}
case 1: {
animator.registerFrameCallback(43, AnimationSoundManager::playRandomMediumCavePower4Sound);
break;
}
case 2: {
animator.registerFrameCallback(30, AnimationSoundManager::playRandomFarPower3Sound);
break;
}
case 3: {
animator.registerFrameCallback(34, AnimationSoundManager::playRandomFarPower2Sound);
break;
}
case 4: {
animator.registerFrameCallback(30, AnimationSoundManager::playRandomFarPower2Sound);
}
}
}
public void m_86600_() {
float progress;
super.m_86600_();
long currentTime = System.currentTimeMillis();
float deltaTime = Math.min((float)(currentTime - this.lastFrameTime) / 1000.0f, 0.1f);
this.lastFrameTime = currentTime;
if (this.fadingIn) {
this.fadeTime += deltaTime;
progress = Math.min(1.0f, this.fadeTime / 1.5f);
this.fadeAlpha = this.easeOutCubic(progress);
if (this.fadeTime >= 1.5f) {
this.fadingIn = false;
this.fadeAlpha = 1.0f;
}
}
if (this.isTransitioning) {
this.transitionTime += deltaTime;
progress = Math.min(1.0f, this.transitionTime / 1.0f);
this.transitionAlpha = this.easeInOutCubic(progress);
if (this.transitionTime >= 1.0f) {
this.isTransitioning = false;
this.currentSlideIndex = this.transitionToIndex;
if (this.currentAnimator != null) {
this.currentAnimator.close();
}
this.currentAnimator = this.nextAnimator;
this.nextAnimator = null;
this.transitionToIndex = -1;
this.waitingForAutoAdvance = false;
this.autoAdvanceTimer = 0.0f;
ExplosionOverhaul.LOGGER.info("Transition complete to slide {}", (Object)this.currentSlideIndex);
if (!this.transitionQueue.isEmpty()) {
int nextIndex = this.transitionQueue.poll();
ExplosionOverhaul.LOGGER.info("Processing queued transition to slide {}", (Object)nextIndex);
this.startTransition(nextIndex);
}
} else if (this.transitionAlpha >= 0.5f && this.nextAnimator == null && this.transitionToIndex >= 0 && this.transitionToIndex < SLIDES.length) {
SlideData slide = SLIDES[this.transitionToIndex];
this.nextAnimator = new SpriteSheetAnimator(slide.spriteSheet, 854, 480, 14, 14, slide.totalFrames, 24);
this.nextAnimator.load();
this.registerSoundCallbacks(this.transitionToIndex, this.nextAnimator);
this.nextAnimator.play();
ExplosionOverhaul.LOGGER.info("Created next slide {} animator at transition midpoint", (Object)this.transitionToIndex);
}
}
if (this.currentAnimator != null && !this.isTransitioning) {
this.currentAnimator.tick(deltaTime);
}
float scaleSpeed = 0.2f;
float targetScale = 1.1f;
this.leftArrowScale = Mth.m_14179_((float)scaleSpeed, (float)this.leftArrowScale, (float)(this.leftArrowHovered ? targetScale : 1.0f));
this.rightArrowScale = Mth.m_14179_((float)scaleSpeed, (float)this.rightArrowScale, (float)(this.rightArrowHovered ? targetScale : 1.0f));
this.continueButtonScale = Mth.m_14179_((float)scaleSpeed, (float)this.continueButtonScale, (float)(this.continueButtonHovered ? targetScale : 1.0f));
this.particles.removeIf(p -> {
p.tick(deltaTime);
return p.isDead() || p.x < -50.0f || p.x > (float)(this.f_96543_ + 50) || p.y < -50.0f || p.y > (float)(this.f_96544_ + 50);
});
if (this.random.m_188501_() < 0.1f) {
this.particles.add(BackgroundParticle.createSpark(this.random, this.f_96543_, this.f_96544_));
}
if (this.random.m_188501_() < 0.03f) {
this.particles.add(BackgroundParticle.createEmber(this.random, this.f_96543_, this.f_96544_));
}
if (this.random.m_188501_() < 0.01f) {
this.particles.add(BackgroundParticle.createSmoke(this.random, this.f_96543_, this.f_96544_));
}
if (this.musicManager != null) {
this.musicManager.tick(deltaTime);
}
}
private void startTransition(int toIndex) {
if (toIndex < 0 || toIndex >= SLIDES.length || this.isTransitioning) {
return;
}
this.isTransitioning = true;
this.transitionTime = 0.0f;
this.transitionAlpha = 0.0f;
this.transitionToIndex = toIndex;
this.waitingForAutoAdvance = false;
this.autoAdvanceTimer = 0.0f;
ExplosionOverhaul.LOGGER.info("Starting transition from slide {} to {}", (Object)this.currentSlideIndex, (Object)toIndex);
}
public void m_88315_(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
graphics.m_280509_(0, 0, this.f_96543_, this.f_96544_, -15921907);
if (this.fadeAlpha < 0.01f) {
return;
}
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
this.renderBackgroundParticles(graphics, this.fadeAlpha * 0.6f);
if (this.isTransitioning) {
float currentAlpha = 1.0f - this.transitionAlpha;
float nextAlpha = this.transitionAlpha;
if (this.currentAnimator != null && currentAlpha > 0.01f) {
this.renderAnimation(graphics, this.currentAnimator, this.fadeAlpha * currentAlpha);
}
if (this.nextAnimator != null && nextAlpha > 0.01f) {
this.renderAnimation(graphics, this.nextAnimator, this.fadeAlpha * nextAlpha);
}
} else if (this.currentAnimator != null) {
this.renderAnimation(graphics, this.currentAnimator, this.fadeAlpha);
}
this.renderGuideText(graphics, this.fadeAlpha);
this.renderArrows(graphics, mouseX, mouseY, this.fadeAlpha);
this.renderContinueButton(graphics, mouseX, mouseY, this.fadeAlpha);
RenderSystem.disableBlend();
}
private void renderBackgroundParticles(GuiGraphics graphics, float alpha) {
for (BackgroundParticle p : this.particles) {
float particleAlpha = p.getAlpha();
float finalAlpha = particleAlpha * alpha;
int colorWithAlpha = p.color & 0xFFFFFF | (int)(finalAlpha * 255.0f) << 24;
switch (p.type) {
case SPARK: {
float sparkLen = p.size * 3.0f;
float sparkAngle = (float)Math.atan2(p.vy, p.vx);
int ex = (int)((double)p.x + Math.cos(sparkAngle) * (double)sparkLen);
int ey = (int)((double)p.y + Math.sin(sparkAngle) * (double)sparkLen);
this.drawLine(graphics, (int)p.x, (int)p.y, ex, ey, colorWithAlpha);
break;
}
case EMBER: {
int emberSize = (int)p.size;
graphics.m_280509_((int)p.x - emberSize, (int)p.y - emberSize, (int)p.x + emberSize, (int)p.y + emberSize, colorWithAlpha);
break;
}
case FLASH: {
int flashSize = (int)(p.size * 0.7f);
int flashColor = colorWithAlpha & 0xFFFFFF | (int)(finalAlpha * 180.0f) << 24;
graphics.m_280509_((int)p.x - flashSize, (int)p.y - flashSize, (int)p.x + flashSize, (int)p.y + flashSize, flashColor);
break;
}
case SMOKE: {
int smokeSize = (int)p.size;
int smokeColor = colorWithAlpha & 0xFFFFFF | (int)(finalAlpha * 60.0f) << 24;
graphics.m_280509_((int)p.x - smokeSize, (int)p.y - smokeSize, (int)p.x + smokeSize, (int)p.y + smokeSize, smokeColor);
}
}
}
}
private void renderAnimation(GuiGraphics graphics, SpriteSheetAnimator animator, float alpha) {
ResourceLocation texture = animator.getTextureLocation();
if (texture == null) {
return;
}
RenderSystem.setShader(GameRenderer::m_172817_);
RenderSystem.setShaderTexture((int)0, (ResourceLocation)texture);
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)alpha);
graphics.m_280411_(texture, this.animationX, this.animationY, this.animationWidth, this.animationHeight, 0.0f, 0.0f, 854, 480, 854, 480);
int glowColor = (int)(alpha * 32.0f) << 24 | 0xF28B0C;
int borderThickness = 2;
graphics.m_280509_(this.animationX - borderThickness, this.animationY - borderThickness, this.animationX + this.animationWidth + borderThickness, this.animationY, glowColor);
graphics.m_280509_(this.animationX - borderThickness, this.animationY + this.animationHeight, this.animationX + this.animationWidth + borderThickness, this.animationY + this.animationHeight + borderThickness, glowColor);
graphics.m_280509_(this.animationX - borderThickness, this.animationY, this.animationX, this.animationY + this.animationHeight, glowColor);
graphics.m_280509_(this.animationX + this.animationWidth, this.animationY, this.animationX + this.animationWidth + borderThickness, this.animationY + this.animationHeight, glowColor);
}
private void renderProgressBar(GuiGraphics graphics, float alpha) {
if (this.currentAnimator == null) {
return;
}
int currentFrame = this.currentAnimator.getCurrentFrame();
int totalFrames = GuideSlidesScreen.SLIDES[this.currentSlideIndex].totalFrames;
float progress = (float)currentFrame / (float)totalFrames;
int bgColor = (int)(alpha * 128.0f) << 24 | 0;
graphics.m_280509_(this.progressBarX, this.progressBarY, this.progressBarX + this.progressBarWidth, this.progressBarY + this.progressBarHeight, bgColor);
int fillWidth = (int)((float)this.progressBarWidth * progress);
int fillColor = (int)(alpha * 255.0f) << 24 | 0xF28B0C;
graphics.m_280509_(this.progressBarX, this.progressBarY, this.progressBarX + fillWidth, this.progressBarY + this.progressBarHeight, fillColor);
if (fillWidth > 0) {
int glowColor = (int)(alpha * 64.0f) << 24 | 0xF28B0C;
graphics.m_280509_(this.progressBarX + fillWidth - 4, this.progressBarY - 1, this.progressBarX + fillWidth, this.progressBarY + this.progressBarHeight + 1, glowColor);
}
}
private void renderGuideText(GuiGraphics graphics, float alpha) {
String text = GuideSlidesScreen.SLIDES[this.currentSlideIndex].guideText;
int textColor = (int)(alpha * 255.0f) << 24 | 0xFFFFFF;
int textY = this.animationY + this.animationHeight + (int)((float)this.f_96544_ * 0.04f);
int maxLineWidth = this.animationWidth;
List<String> lines = this.wrapText(text, maxLineWidth);
Objects.requireNonNull(this.f_96547_);
int lineHeight = 9 + 4;
int totalTextHeight = lines.size() * lineHeight;
int startY = textY;
for (int i = 0; i < lines.size(); ++i) {
String line = lines.get(i);
int lineWidth = this.f_96547_.m_92895_(line);
int x = this.animationX + (this.animationWidth - lineWidth) / 2;
graphics.m_280056_(this.f_96547_, line, x, startY + i * lineHeight, textColor, true);
}
}
private List<String> wrapText(String text, int maxWidth) {
ArrayList<String> lines = new ArrayList<String>();
String[] words = text.split(" ");
StringBuilder currentLine = new StringBuilder();
for (String word : words) {
Object testLine = currentLine.length() > 0 ? currentLine + " " + word : word;
int width = this.f_96547_.m_92895_((String)testLine);
if (width > maxWidth && currentLine.length() > 0) {
lines.add(currentLine.toString());
currentLine = new StringBuilder(word);
continue;
}
if (currentLine.length() > 0) {
currentLine.append(" ");
}
currentLine.append(word);
}
if (currentLine.length() > 0) {
lines.add(currentLine.toString());
}
return lines;
}
private void renderArrows(GuiGraphics graphics, int mouseX, int mouseY, float alpha) {
this.leftArrowHovered = this.isPointInArrow(mouseX, mouseY, this.leftArrowX, this.leftArrowY, this.arrowSize);
this.rightArrowHovered = this.isPointInArrow(mouseX, mouseY, this.rightArrowX, this.rightArrowY, this.arrowSize);
if (this.currentSlideIndex > 0) {
this.renderArrow(graphics, this.leftArrowX, this.leftArrowY, this.arrowSize, true, this.leftArrowScale, this.leftArrowHovered, alpha);
}
if (this.currentSlideIndex < SLIDES.length - 1) {
this.renderArrow(graphics, this.rightArrowX, this.rightArrowY, this.arrowSize, false, this.rightArrowScale, this.rightArrowHovered, alpha);
}
}
private void renderArrow(GuiGraphics graphics, int x, int y, int size, boolean pointLeft, float scale, boolean hovered, float alpha) {
int scaledSize = (int)((float)size * scale);
int offset = (scaledSize - size) / 2;
int drawX = x - offset;
int drawY = y - offset;
int bgColor = hovered ? (int)(alpha * 192.0f) << 24 | 0xF28B0C : (int)(alpha * 128.0f) << 24 | 0x591515;
this.fillCircle(graphics, drawX + scaledSize / 2, drawY + scaledSize / 2, scaledSize / 2, bgColor);
int arrowColor = (int)(alpha * 255.0f) << 24 | 0xFFFFFF;
int centerX = drawX + scaledSize / 2;
int centerY = drawY + scaledSize / 2;
int arrowWidth = scaledSize / 3;
int arrowHeight = scaledSize / 4;
if (pointLeft) {
this.fillTriangle(graphics, centerX + arrowWidth / 2, centerY - arrowHeight, centerX + arrowWidth / 2, centerY + arrowHeight, centerX - arrowWidth / 2, centerY, arrowColor);
} else {
this.fillTriangle(graphics, centerX - arrowWidth / 2, centerY - arrowHeight, centerX - arrowWidth / 2, centerY + arrowHeight, centerX + arrowWidth / 2, centerY, arrowColor);
}
if (hovered) {
int glowColor = (int)(alpha * 64.0f) << 24 | 0xF28B0C;
this.fillCircle(graphics, drawX + scaledSize / 2, drawY + scaledSize / 2, scaledSize / 2 + 4, glowColor);
}
}
private boolean isPointInArrow(int px, int py, int arrowX, int arrowY, int size) {
int centerX = arrowX + size / 2;
int dx = px - centerX;
int centerY = arrowY + size / 2;
int dy = py - centerY;
int radius = size / 2;
return dx * dx + dy * dy <= radius * radius;
}
private void fillCircle(GuiGraphics graphics, int centerX, int centerY, int radius, int color) {
for (int y = -radius; y <= radius; ++y) {
for (int x = -radius; x <= radius; ++x) {
if (x * x + y * y > radius * radius) continue;
graphics.m_280509_(centerX + x, centerY + y, centerX + x + 1, centerY + y + 1, color);
}
}
}
private void fillTriangle(GuiGraphics graphics, int x1, int y1, int x2, int y2, int x3, int y3, int color) {
int minY = Math.min(y1, Math.min(y2, y3));
int maxY = Math.max(y1, Math.max(y2, y3));
for (int y = minY; y <= maxY; ++y) {
int x;
int minX = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
if (this.checkIntersection(y, y1, y2, x1, x2)) {
x = this.interpolate(y, y1, y2, x1, x2);
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
}
if (this.checkIntersection(y, y2, y3, x2, x3)) {
x = this.interpolate(y, y2, y3, x2, x3);
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
}
if (this.checkIntersection(y, y3, y1, x3, x1)) {
x = this.interpolate(y, y3, y1, x3, x1);
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
}
if (minX == Integer.MAX_VALUE || maxX == Integer.MIN_VALUE) continue;
graphics.m_280509_(minX, y, maxX + 1, y + 1, color);
}
}
private boolean checkIntersection(int y, int y1, int y2, int x1, int x2) {
return y >= Math.min(y1, y2) && y <= Math.max(y1, y2) && y1 != y2;
}
private int interpolate(int y, int y1, int y2, int x1, int x2) {
return x1 + (y - y1) * (x2 - x1) / (y2 - y1);
}
public boolean m_6375_(double mouseX, double mouseY, int button) {
if (button == 0) {
if (this.isPointInButton((int)mouseX, (int)mouseY)) {
this.playButtonSound();
this.transitionToFirstTimeScreen();
return true;
}
if (this.currentSlideIndex > 0 && this.isPointInArrow((int)mouseX, (int)mouseY, this.leftArrowX, this.leftArrowY, this.arrowSize)) {
Integer nextTransition;
this.playButtonSound();
int targetIndex = this.currentSlideIndex - 1;
this.transitionQueue.offer(targetIndex);
if (!this.isTransitioning && (nextTransition = this.transitionQueue.poll()) != null) {
this.startTransition(nextTransition);
}
ExplosionOverhaul.LOGGER.info("Queued left arrow transition to {}, queue size: {}", (Object)targetIndex, (Object)this.transitionQueue.size());
return true;
}
if (this.currentSlideIndex < SLIDES.length - 1 && this.isPointInArrow((int)mouseX, (int)mouseY, this.rightArrowX, this.rightArrowY, this.arrowSize)) {
Integer nextTransition;
this.playButtonSound();
int targetIndex = this.currentSlideIndex + 1;
this.transitionQueue.offer(targetIndex);
if (!this.isTransitioning && (nextTransition = this.transitionQueue.poll()) != null) {
this.startTransition(nextTransition);
}
ExplosionOverhaul.LOGGER.info("Queued right arrow transition to {}, queue size: {}", (Object)targetIndex, (Object)this.transitionQueue.size());
return true;
}
}
return super.m_6375_(mouseX, mouseY, button);
}
private boolean isPointInButton(int px, int py) {
return px >= this.continueButtonX && px <= this.continueButtonX + this.continueButtonWidth && py >= this.continueButtonY && py <= this.continueButtonY + this.continueButtonHeight;
}
private void renderContinueButton(GuiGraphics graphics, int mouseX, int mouseY, float alpha) {
this.continueButtonHovered = this.isPointInButton(mouseX, mouseY);
int scaledWidth = (int)((float)this.continueButtonWidth * this.continueButtonScale);
int scaledHeight = (int)((float)this.continueButtonHeight * this.continueButtonScale);
int offsetX = (scaledWidth - this.continueButtonWidth) / 2;
int offsetY = (scaledHeight - this.continueButtonHeight) / 2;
int drawX = this.continueButtonX - offsetX;
int drawY = this.continueButtonY - offsetY;
int bgColor = this.continueButtonHovered ? (int)(alpha * 220.0f) << 24 | 0xF28B0C : (int)(alpha * 160.0f) << 24 | 0x591515;
graphics.m_280509_(drawX, drawY, drawX + scaledWidth, drawY + scaledHeight, bgColor);
if (this.continueButtonHovered) {
int glowColor = (int)(alpha * 80.0f) << 24 | 0xF28B0C;
int border = 3;
graphics.m_280509_(drawX - border, drawY - border, drawX + scaledWidth + border, drawY, glowColor);
graphics.m_280509_(drawX - border, drawY + scaledHeight, drawX + scaledWidth + border, drawY + scaledHeight + border, glowColor);
graphics.m_280509_(drawX - border, drawY, drawX, drawY + scaledHeight, glowColor);
graphics.m_280509_(drawX + scaledWidth, drawY, drawX + scaledWidth + border, drawY + scaledHeight, glowColor);
}
String text = "Skip Guide";
int textColor = (int)(alpha * 255.0f) << 24 | 0xFFFFFF;
int textX = drawX + (scaledWidth - this.f_96547_.m_92895_(text)) / 2;
Objects.requireNonNull(this.f_96547_);
int textY = drawY + (scaledHeight - 9) / 2;
graphics.m_280056_(this.f_96547_, text, textX, textY, textColor, true);
}
public boolean m_6913_() {
return false;
}
public boolean m_7043_() {
return false;
}
public void m_7861_() {
super.m_7861_();
this.transitionQueue.clear();
if (this.currentAnimator != null) {
this.currentAnimator.close();
}
if (this.nextAnimator != null) {
this.nextAnimator.close();
}
}
private void transitionToFirstTimeScreen() {
ExplosionOverhaul.LOGGER.info("All guide slides complete. Transitioning to FirstTimeScreen.");
Minecraft.m_91087_().m_91152_((Screen)new FirstTimeScreen());
}
private void drawLine(GuiGraphics graphics, int x1, int y1, int x2, int y2, int color) {
int dx = Math.abs(x2 - x1);
int dy = Math.abs(y2 - y1);
int sx = x1 < x2 ? 1 : -1;
int sy = y1 < y2 ? 1 : -1;
int err = dx - dy;
for (int steps = 0; steps < 200; ++steps) {
graphics.m_280509_(x1, y1, x1 + 1, y1 + 1, color);
if (x1 == x2 && y1 == y2) break;
int e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x1 += sx;
}
if (e2 >= dx) continue;
err += dx;
y1 += sy;
}
}
private float easeOutCubic(float t) {
return 1.0f - (float)Math.pow(1.0f - t, 3.0);
}
private float easeInCubic(float t) {
return t * t * t;
}
private float easeInOutCubic(float t) {
return t < 0.5f ? 4.0f * t * t * t : 1.0f - (float)Math.pow(-2.0f * t + 2.0f, 3.0) / 2.0f;
}
private void playButtonSound() {
try {
Minecraft minecraft = Minecraft.m_91087_();
if (minecraft.m_91106_() != null) {
minecraft.m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.BUTTON_SOUND.get()), (float)1.0f, (float)1.0f));
}
}
catch (Exception e) {
ExplosionOverhaul.LOGGER.warn("Failed to play button sound", (Throwable)e);
}
}
private static class SlideData {
final ResourceLocation spriteSheet;
final int totalFrames;
final String guideText;
SlideData(String filename, int frames, String text) {
this.spriteSheet = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)("intro_gui/" + filename));
this.totalFrames = frames;
this.guideText = text;
}
}
}