From 11724973d799954334d00993c48e66605b7499ce Mon Sep 17 00:00:00 2001 From: UnlikePaladin <36827970+UnlikePaladin@users.noreply.github.com> Date: Sun, 29 Sep 2024 22:13:27 -0600 Subject: [PATCH] Update trashcan collision to match new appearance Add loading overlay, disabled for now. --- .../pfm/blocks/TrashcanBlock.java | 2 +- .../client/screens/PFMGeneratingOverlay.java | 153 +++++++++++++++++- .../screens/widget/PFMOptionListWidget.java | 1 + .../pfm/runtime/PFMAssetGenerator.java | 10 +- .../pfm/runtime/PFMDataGenerator.java | 9 +- .../pfm/runtime/PFMResourceProgress.java | 2 +- .../pfm/runtime/PFMRuntimeResources.java | 11 +- 7 files changed, 174 insertions(+), 14 deletions(-) diff --git a/common/src/main/java/com/unlikepaladin/pfm/blocks/TrashcanBlock.java b/common/src/main/java/com/unlikepaladin/pfm/blocks/TrashcanBlock.java index 7fae5afe4..1502a4145 100644 --- a/common/src/main/java/com/unlikepaladin/pfm/blocks/TrashcanBlock.java +++ b/common/src/main/java/com/unlikepaladin/pfm/blocks/TrashcanBlock.java @@ -40,7 +40,7 @@ public BlockRenderType getRenderType(BlockState state) { return BlockRenderType.MODEL; } - public static final VoxelShape TRASHCAN = VoxelShapes.union(createCuboidShape(2, 0, 2, 13, 13, 13), createCuboidShape(1, 12, 1, 14, 16, 14), createCuboidShape(3.5, 16, 6.5,11.5, 18, 8.5)); + public static final VoxelShape TRASHCAN = VoxelShapes.union(createCuboidShape(2, 0, 2, 13, 13, 13), createCuboidShape(1, 12, 1, 14, 15, 14), createCuboidShape(3.5, 14.9, 6.5,11.5, 16, 8.5)); public static final VoxelShape TRASHCAN_OPEN = VoxelShapes.union(createCuboidShape(2, 0, 2, 13, 13, 13), createCuboidShape(10.5, 0, 0, 19.5, 13, 14)); @Override diff --git a/common/src/main/java/com/unlikepaladin/pfm/client/screens/PFMGeneratingOverlay.java b/common/src/main/java/com/unlikepaladin/pfm/client/screens/PFMGeneratingOverlay.java index 27970a0ab..e868240f8 100644 --- a/common/src/main/java/com/unlikepaladin/pfm/client/screens/PFMGeneratingOverlay.java +++ b/common/src/main/java/com/unlikepaladin/pfm/client/screens/PFMGeneratingOverlay.java @@ -1,19 +1,82 @@ package com.unlikepaladin.pfm.client.screens; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.unlikepaladin.pfm.runtime.PFMGenerator; import com.unlikepaladin.pfm.runtime.PFMResourceProgress; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.hud.BackgroundHelper; import net.minecraft.client.gui.screen.Overlay; -import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.SplashOverlay; +import net.minecraft.client.resource.metadata.TextureResourceMetadata; +import net.minecraft.client.texture.NativeImage; +import net.minecraft.client.texture.ResourceTexture; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.resource.DefaultResourcePack; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourceType; +import net.minecraft.util.Identifier; import net.minecraft.util.Util; +import net.minecraft.util.math.MathHelper; +import org.lwjgl.opengl.GL11; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; public class PFMGeneratingOverlay extends Overlay { private long reloadCompleteTime = -1L; private long reloadStartTime = -1L; private final boolean reloading; + private static final String logo = "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"; + private static final Identifier pfmLogo = new Identifier("pfm", "banner"); + private final PFMResourceProgress resourceProgress; + private float progress; + private final MinecraftClient client; + private final Overlay parent; + private int textureWidth, textureHeight; + private static final int PFM_ORANGE = BackgroundHelper.ColorMixer.getArgb(255, 231, 95, 9); - PFMGeneratingOverlay(Overlay parent, PFMResourceProgress resourceProgress, MinecraftClient client, boolean reloading) { + public PFMGeneratingOverlay(Overlay parent, PFMResourceProgress resourceProgress, MinecraftClient client, boolean reloading) { this.reloading = reloading; + this.resourceProgress = resourceProgress; + this.client = client; + this.parent = parent; + client.getTextureManager().registerTexture(pfmLogo, new PFMGeneratingOverlay.LogoTexture()); + } + + public static BufferedImage decodeBase64ToImage(String base64Image) throws Exception { + byte[] imageBytes = Base64.getDecoder().decode(base64Image); + try (ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes)) { + return ImageIO.read(bais); + } + } + + public NativeImage convertToNativeImage(BufferedImage bufferedImage) { + NativeImage nativeImage = new NativeImage(bufferedImage.getWidth(), bufferedImage.getHeight(), true); + + for (int x = 0; x < bufferedImage.getWidth(); x++) { + for (int y = 0; y < bufferedImage.getHeight(); y++) { + int argb = bufferedImage.getRGB(x, y); + + // Convert ARGB to ABGR format + int alpha = (argb >> 24) & 0xFF; + int red = (argb >> 16) & 0xFF; + int green = (argb >> 8) & 0xFF; + int blue = argb & 0xFF; + int abgr = (alpha << 24) | (blue << 16) | (green << 8) | red; + + nativeImage.setColor(x, y, abgr); + } + } + + return nativeImage; } @Override @@ -22,5 +85,91 @@ public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { if (this.reloading && this.reloadStartTime == -1L) { this.reloadStartTime = l; } + float r = (float)(PFM_ORANGE >> 16 & 0xFF) / 255.0f; + float g = (float)(PFM_ORANGE >> 8 & 0xFF) / 255.0f; + float b = (float)(PFM_ORANGE & 0xFF) / 255.0f; + GlStateManager._clearColor(r, g, b, 1.0f); + GlStateManager._clear(16384, MinecraftClient.IS_SYSTEM_MAC); + + float timeProgress = this.reloadCompleteTime > -1L ? (float)(l - this.reloadCompleteTime) / 1000.0f : -1.0f; + + int width = this.client.getWindow().getScaledWidth(); + int height = this.client.getWindow().getScaledHeight(); + int halfWidth = (int)((double)this.client.getWindow().getScaledWidth() * 0.5); + int halfHeight = (int)((double)this.client.getWindow().getScaledHeight() * 0.5); + + float progress = this.resourceProgress.getProgress(); + double minRes = Math.min((double)this.client.getWindow().getScaledWidth() * 0.75, (double)this.client.getWindow().getScaledHeight()) * 0.25; + + int barHeight = (int)((double)this.client.getWindow().getScaledHeight() * 0.8325); + + if (progress > 0.99f) { + this.progress = progress; + } else { + this.progress = MathHelper.clamp(this.progress * 0.95f + progress * 0.050000012f, 0.0f, 1.0f); + } + double e = minRes * 4.0; + int barWidth = (int)(e * 0.5); + float scaleFactor = (Math.min((float) width / textureWidth, (float) height / textureHeight) * 0.6f); + + int logoWidth = (int) (textureWidth * scaleFactor); + int logoHeight = (int) (textureHeight * scaleFactor); + + int x = (width - logoWidth) / 2; + int y = (height - logoHeight) / 2; + RenderSystem.setShaderTexture(0, pfmLogo); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + drawTexture(matrices, x, y, 0, 0, logoWidth, logoHeight, logoWidth, logoHeight); + + if (timeProgress < 1.0f) { + this.renderProgressBar(matrices, width / 2 - barWidth, barHeight - 5, width / 2 + barWidth, barHeight + 5, 1.0f - MathHelper.clamp(timeProgress, 0.0f, 1.0f)); + } + if (timeProgress >= 2.0f || (!PFMGenerator.areAssetsRunning() && !PFMGenerator.isDataRunning())) { + this.client.setOverlay(parent); + } } + + + private void renderProgressBar(MatrixStack matrices, int minX, int minY, int maxX, int maxY, float opacity) { + int i = MathHelper.ceil((float)(maxX - minX - 2) * this.progress); + int j = Math.round(opacity * 255.0f); + int k = BackgroundHelper.ColorMixer.getArgb(j, 255, 255, 255); + PFMGeneratingOverlay.fill(matrices, minX + 2, minY + 2, minX + i, maxY - 2, k); + PFMGeneratingOverlay.fill(matrices, minX + 1, minY, maxX - 1, minY + 1, k); + PFMGeneratingOverlay.fill(matrices, minX + 1, maxY, maxX - 1, maxY - 1, k); + PFMGeneratingOverlay.fill(matrices, minX, minY, minX + 1, maxY, k); + PFMGeneratingOverlay.fill(matrices, maxX, minY, maxX - 1, maxY, k); + } + + @Environment(value= EnvType.CLIENT) + class LogoTexture + extends ResourceTexture { + public LogoTexture() { + super(pfmLogo); + } + + @Override + protected ResourceTexture.TextureData loadTextureData(ResourceManager resourceManager) { + ResourceTexture.TextureData textureData; + + BufferedImage bufferedImage; + NativeImage nativeImage = null; + try { + bufferedImage = decodeBase64ToImage(logo); + nativeImage = convertToNativeImage(bufferedImage); + textureWidth = nativeImage.getWidth(); + textureHeight = nativeImage.getHeight(); + textureData = new TextureData(new TextureResourceMetadata(true, true), nativeImage); + } catch (Throwable throwable) { + if (nativeImage != null) + nativeImage.close(); + + return new TextureData(new IOException(throwable.getMessage())); + } + + return textureData; + } + } + + } diff --git a/common/src/main/java/com/unlikepaladin/pfm/client/screens/widget/PFMOptionListWidget.java b/common/src/main/java/com/unlikepaladin/pfm/client/screens/widget/PFMOptionListWidget.java index 58ba09649..a9086d84d 100644 --- a/common/src/main/java/com/unlikepaladin/pfm/client/screens/widget/PFMOptionListWidget.java +++ b/common/src/main/java/com/unlikepaladin/pfm/client/screens/widget/PFMOptionListWidget.java @@ -3,6 +3,7 @@ import com.google.common.collect.ImmutableList; import com.unlikepaladin.pfm.PaladinFurnitureMod; import com.unlikepaladin.pfm.client.screens.PFMConfigScreen; +import com.unlikepaladin.pfm.client.screens.PFMGeneratingOverlay; import com.unlikepaladin.pfm.config.option.AbstractConfigOption; import com.unlikepaladin.pfm.config.option.BooleanConfigOption; import com.unlikepaladin.pfm.config.option.Side; diff --git a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMAssetGenerator.java b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMAssetGenerator.java index 896a499e5..b146087f7 100644 --- a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMAssetGenerator.java +++ b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMAssetGenerator.java @@ -3,10 +3,12 @@ import com.google.common.base.Stopwatch; import com.mojang.bridge.game.PackType; import com.unlikepaladin.pfm.PaladinFurnitureMod; +import com.unlikepaladin.pfm.client.screens.PFMGeneratingOverlay; import com.unlikepaladin.pfm.runtime.assets.PFMBlockstateModelProvider; import com.unlikepaladin.pfm.runtime.assets.PFMLangProvider; import com.unlikepaladin.pfm.runtime.data.PFMMCMetaProvider; import com.unlikepaladin.pfm.utilities.PFMFileUtil; +import net.minecraft.client.MinecraftClient; import net.minecraft.data.DataCache; import net.minecraft.resource.ResourcePack; import net.minecraft.resource.ResourceType; @@ -26,11 +28,12 @@ public class PFMAssetGenerator extends PFMGenerator { public PFMAssetGenerator(Path output, boolean logOrDebug) { super(output, logOrDebug, LogManager.getLogger("PFM-Asset-Generation")); - count = 0; + count = 3; } public void run() throws IOException { if (!FROZEN) { + count = 0; setAssetsRunning(true); log("Packs:"); for (ResourcePack pack : PFMRuntimeResources.RESOURCE_PACK_LIST) { @@ -55,6 +58,7 @@ public void run() throws IOException { List oldHash = Files.readAllLines(hashPath); List modList = Files.readAllLines(modListPath); if (!hashToCompare.toString().equals(oldHash.toString()) || !modList.toString().replace("[", "").replace("]", "").equals(PaladinFurnitureMod.getVersionMap().toString())) { + //MinecraftClient.getInstance().setOverlay(new PFMGeneratingOverlay(MinecraftClient.getInstance().getOverlay(), this, MinecraftClient.getInstance(), true)); getLogger().info("Starting PFM Asset Generation"); PFMFileUtil.deleteDir(output.toFile()); PFMRuntimeResources.createDirIfNeeded(output); @@ -105,8 +109,8 @@ public void run() throws IOException { } @Override - public int getProgress() { - return count / 3; + public float getProgress() { + return (float) count / 3; } @Override diff --git a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMDataGenerator.java b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMDataGenerator.java index 7f19c718d..668039d58 100644 --- a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMDataGenerator.java +++ b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMDataGenerator.java @@ -4,6 +4,7 @@ import com.google.common.hash.HashCode; import com.mojang.bridge.game.PackType; import com.unlikepaladin.pfm.PaladinFurnitureMod; +import com.unlikepaladin.pfm.client.screens.PFMGeneratingOverlay; import com.unlikepaladin.pfm.runtime.assets.PFMBlockstateModelProvider; import com.unlikepaladin.pfm.runtime.assets.PFMLangProvider; import com.unlikepaladin.pfm.runtime.data.PFMLootTableProvider; @@ -11,6 +12,7 @@ import com.unlikepaladin.pfm.runtime.data.PFMRecipeProvider; import com.unlikepaladin.pfm.runtime.data.PFMTagProvider; import com.unlikepaladin.pfm.utilities.PFMFileUtil; +import net.minecraft.client.MinecraftClient; import net.minecraft.data.DataCache; import net.minecraft.resource.ResourcePack; import net.minecraft.resource.ResourceType; @@ -29,9 +31,11 @@ public class PFMDataGenerator extends PFMGenerator { public PFMDataGenerator(Path output, boolean logOrDebug) { super(output, logOrDebug, LogManager.getLogger("PFM-DataGen")); + count = 4; } public void run() throws IOException { if (!FROZEN) { + count = 0; setDataRunning(true); log("Packs:"); for (ResourcePack pack : PFMRuntimeResources.RESOURCE_PACK_LIST) { @@ -56,6 +60,7 @@ public void run() throws IOException { List modList = Files.readAllLines(modListPath); if (!hashToCompare.toString().equals(oldHash.toString()) || !modList.toString().replace("[", "").replace("]", "").equals(PaladinFurnitureMod.getVersionMap().toString())) { getLogger().info("Starting PFM Data Generation"); + //MinecraftClient.getInstance().setOverlay(new PFMGeneratingOverlay(MinecraftClient.getInstance().getOverlay(), this, MinecraftClient.getInstance(), true)); PFMFileUtil.deleteDir(output.toFile()); DataCache dataCache = new DataCache(output, "cache"); dataCache.ignore(output.resolve("version.json")); @@ -113,8 +118,8 @@ public void run() throws IOException { } @Override - public int getProgress() { - return count / 4; + public float getProgress() { + return (float) count / 4; } @Override diff --git a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMResourceProgress.java b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMResourceProgress.java index 4d5f33bbf..3628b7f61 100644 --- a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMResourceProgress.java +++ b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMResourceProgress.java @@ -1,7 +1,7 @@ package com.unlikepaladin.pfm.runtime; public interface PFMResourceProgress { - int getProgress(); + float getProgress(); String getProgressString(); } diff --git a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMRuntimeResources.java b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMRuntimeResources.java index c5713dd10..e667f6780 100644 --- a/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMRuntimeResources.java +++ b/common/src/main/java/com/unlikepaladin/pfm/runtime/PFMRuntimeResources.java @@ -1,9 +1,9 @@ package com.unlikepaladin.pfm.runtime; import com.unlikepaladin.pfm.PaladinFurnitureMod; +import com.unlikepaladin.pfm.client.screens.PFMGeneratingOverlay; import com.unlikepaladin.pfm.utilities.PFMFileUtil; -import net.minecraft.client.render.model.BakedModel; -import net.minecraft.client.render.model.ModelBakeSettings; +import net.minecraft.client.MinecraftClient; import net.minecraft.resource.DirectoryResourcePack; import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; @@ -15,12 +15,13 @@ import java.util.Base64; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; public class PFMRuntimeResources { public static final String base64Icon = "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"; + public static final DirectoryResourcePack ASSETS_PACK = new DirectoryResourcePack(getAssetPackDirectory().toFile()); public static final DirectoryResourcePack DATA_PACK = new DirectoryResourcePack(getDataPackDirectory().toFile()); @@ -56,8 +57,8 @@ public static Path createDirIfNeeded(Path path) { private static CompletableFuture future; public static CompletableFuture prepareAsyncDataGen(boolean logOrDebug) { + PFMDataGenerator dataGen = new PFMDataGenerator(PFMRuntimeResources.getDataPackDirectory(), logOrDebug); return future = CompletableFuture.runAsync(() -> { - PFMDataGenerator dataGen = new PFMDataGenerator(PFMRuntimeResources.getDataPackDirectory(), logOrDebug); try { dataGen.run(); } catch (IOException e) { @@ -68,8 +69,8 @@ public static CompletableFuture prepareAsyncDataGen(boolean logOrDebug) { } public static CompletableFuture prepareAsyncAssetGen(boolean logOrDebug) { + PFMAssetGenerator dataGen = new PFMAssetGenerator(PFMRuntimeResources.getAssetPackDirectory(), logOrDebug); return future = CompletableFuture.runAsync(() -> { - PFMAssetGenerator dataGen = new PFMAssetGenerator(PFMRuntimeResources.getAssetPackDirectory(), logOrDebug); try { dataGen.run(); } catch (IOException e) {