generated from MrSphay/codex-agent-repository-kit
635 lines
31 KiB
Java
635 lines
31 KiB
Java
/*
|
|
* 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;
|
|
}
|
|
}
|
|
}
|
|
|