/* * Decompiled with CFR 0.152. */ package com.vinlanx.explosionoverhaul.client; import com.mojang.blaze3d.platform.NativeImage; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; public class SpriteSheetAnimator { private final ResourceLocation spriteSheetLocation; private final int frameWidth; private final int frameHeight; private final int columns; private final int rows; private final int totalFrames; private final float frameTime; private NativeImage spriteSheet; private DynamicTexture dynamicTexture; private ResourceLocation dynamicTextureLocation; private int currentFrame = 0; private float animationTime = 0.0f; private boolean isPlaying = false; private Map frameCallbacks = new HashMap(); private Map frameCallbacksTriggered = new HashMap(); public SpriteSheetAnimator(ResourceLocation spriteSheetLocation, int frameWidth, int frameHeight, int columns, int rows, int totalFrames, int fps) { this.spriteSheetLocation = spriteSheetLocation; this.frameWidth = frameWidth; this.frameHeight = frameHeight; this.columns = columns; this.rows = rows; this.totalFrames = totalFrames; this.frameTime = 1.0f / (float)fps; } public void load() { Minecraft mc = Minecraft.m_91087_(); try { InputStream stream = ((Resource)mc.m_91098_().m_213713_(this.spriteSheetLocation).orElseThrow()).m_215507_(); this.spriteSheet = NativeImage.m_85058_((InputStream)stream); stream.close(); NativeImage frameImage = new NativeImage(this.frameWidth, this.frameHeight, false); this.dynamicTexture = new DynamicTexture(frameImage); this.dynamicTextureLocation = mc.m_91097_().m_118490_("explosionoverhaul_anim", this.dynamicTexture); this.updateTexture(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { System.err.println("Failed to load sprite sheet: " + this.spriteSheetLocation); e.printStackTrace(); this.spriteSheet = null; this.dynamicTexture = null; } } public void tick(float deltaTime) { if (!this.isPlaying || this.spriteSheet == null) { return; } this.animationTime += deltaTime; if (this.animationTime >= this.frameTime) { Boolean wasTriggered; this.animationTime = 0.0f; ++this.currentFrame; if (this.currentFrame >= this.totalFrames) { this.currentFrame = 0; this.frameCallbacksTriggered.clear(); } this.updateTexture(); if (this.frameCallbacks.containsKey(this.currentFrame) && !(wasTriggered = this.frameCallbacksTriggered.getOrDefault(this.currentFrame, false)).booleanValue()) { this.frameCallbacks.get(this.currentFrame).run(); this.frameCallbacksTriggered.put(this.currentFrame, true); } } } private void updateTexture() { if (this.spriteSheet == null || this.dynamicTexture == null) { return; } if (this.currentFrame < 0) { this.currentFrame = 0; } if (this.currentFrame >= this.totalFrames) { this.currentFrame = this.totalFrames - 1; } int col = this.currentFrame % this.columns; int row = this.currentFrame / this.columns; int srcX = col * this.frameWidth; int srcY = row * this.frameHeight; NativeImage frameImage = this.dynamicTexture.m_117991_(); if (frameImage == null) { return; } for (int y = 0; y < this.frameHeight; ++y) { for (int x = 0; x < this.frameWidth; ++x) { if (srcX + x < this.spriteSheet.m_84982_() && srcY + y < this.spriteSheet.m_85084_()) { int pixel = this.spriteSheet.m_84985_(srcX + x, srcY + y); frameImage.m_84988_(x, y, pixel); continue; } frameImage.m_84988_(x, y, 0); } } this.dynamicTexture.m_117985_(); } public void play() { this.isPlaying = true; } public void pause() { this.isPlaying = false; } public void reset() { this.currentFrame = 0; this.animationTime = 0.0f; this.isPlaying = false; this.frameCallbacksTriggered.clear(); this.updateTexture(); } public ResourceLocation getTextureLocation() { return this.dynamicTextureLocation; } public int getFrameWidth() { return this.frameWidth; } public int getFrameHeight() { return this.frameHeight; } public int getCurrentFrame() { return this.currentFrame; } public void registerFrameCallback(int frameNumber, Runnable callback) { if (frameNumber >= 0 && frameNumber < this.totalFrames) { this.frameCallbacks.put(frameNumber, callback); } } public void unregisterFrameCallback(int frameNumber) { this.frameCallbacks.remove(frameNumber); this.frameCallbacksTriggered.remove(frameNumber); } public void clearFrameCallbacks() { this.frameCallbacks.clear(); this.frameCallbacksTriggered.clear(); } public void close() { if (this.dynamicTexture != null) { this.dynamicTexture.close(); } if (this.spriteSheet != null) { this.spriteSheet.close(); } } }