From 5d96129df0094a8fe81b95976b26af8d5fb128ee Mon Sep 17 00:00:00 2001 From: Aurora Date: Fri, 7 Nov 2025 16:44:39 +0000 Subject: [PATCH] Add EnvironmentTransformer for the moon phase changes --- .../transformer/TextureTransformer.java | 59 ++++++++++++++++ .../type/EnvironmentTransformer.java | 57 +++++++++++++++ .../transformer/type/ui/IconTransformer.java | 69 +++---------------- .../src/main/resources/mappings/textures.json | 2 +- 4 files changed, 125 insertions(+), 62 deletions(-) create mode 100644 converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/EnvironmentTransformer.java diff --git a/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/TextureTransformer.java b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/TextureTransformer.java index cf5bb01..c672251 100644 --- a/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/TextureTransformer.java +++ b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/TextureTransformer.java @@ -26,14 +26,20 @@ package org.geysermc.pack.converter.type.texture.transformer; +import net.kyori.adventure.key.Key; import org.geysermc.pack.converter.util.ImageUtil; import org.jetbrains.annotations.NotNull; import team.unnamed.creative.texture.Texture; import javax.imageio.ImageIO; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.DoubleStream; public interface TextureTransformer { int ORDER_FIRST = 0; @@ -51,4 +57,57 @@ public interface TextureTransformer { default int order() { return ORDER_NORMAL; } + + // Adds images in rows and columns + default void gridTransform(@NotNull TransformContext context, boolean poll, int rows, int columns, Key bedrockOutput, Key... javaInputs) throws IOException { + if (rows * columns != javaInputs.length) { + throw new IllegalStateException("Images do not match row and column count."); + } + + boolean exists = false; + + for (Key javaInput : javaInputs) { + if (context.isTexturePresent(javaInput)) { + exists = true; + break; + } + } + + if (!exists) return; + + List textures = Arrays.stream(javaInputs) + .map(key -> poll ? context.pollOrPeekVanilla(key) : context.peekOrVanilla(key)).toList(); + + List images = new ArrayList<>(textures.size()); + + for (Texture texture : textures) { + if (texture == null) images.add(null); + else images.add(this.readImage(texture)); + } + + float maxScale = (float) images.stream() + .flatMapToDouble(img -> DoubleStream.of(img == null ? 1f : img.getWidth() / 16f)) + .max().orElseThrow(); + + BufferedImage bedrockOutputImage = new BufferedImage((int) (maxScale * 16 * images.size()), (int) (maxScale * 16), BufferedImage.TYPE_INT_ARGB); + + Graphics graphics = bedrockOutputImage.getGraphics(); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + BufferedImage image = images.get(i); + if (image != null) { + float scale = maxScale / (image.getWidth() / 16f); + + graphics.drawImage( + ImageUtil.scale(image, scale), + (int) (maxScale * 16 * j), + (int) (maxScale * 16 * i), null + ); + } + } + } + + context.offer(bedrockOutput, bedrockOutputImage, "png"); + } } diff --git a/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/EnvironmentTransformer.java b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/EnvironmentTransformer.java new file mode 100644 index 0000000..eb503e7 --- /dev/null +++ b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/EnvironmentTransformer.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/PackConverter + * + */ + +package org.geysermc.pack.converter.type.texture.transformer.type; + +import com.google.auto.service.AutoService; +import net.kyori.adventure.key.Key; +import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer; +import org.geysermc.pack.converter.type.texture.transformer.TransformContext; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +@AutoService(TextureTransformer.class) +public class EnvironmentTransformer implements TextureTransformer { + private static final Key NEW_MOON = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/new_moon.png"); + private static final Key WAXING_CRESCENT = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/waxing_crescent.png"); + private static final Key FIRST_QUARTER = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/first_quarter.png"); + private static final Key WAXING_GIBBOUS = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/waxing_gibbous.png"); + private static final Key FULL_MOON = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/full_moon.png"); + private static final Key WANING_GIBBOUS = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/waning_gibbous.png"); + private static final Key THIRD_QUARTER = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/third_quarter.png"); + private static final Key WANING_CRESCENT = Key.key(Key.MINECRAFT_NAMESPACE, "environment/celestial/moon/waning_crescent.png"); + private static final Key MOON_PHASES = Key.key(Key.MINECRAFT_NAMESPACE, "environment/moon_phases.png"); + + @Override + public void transform(@NotNull TransformContext context) throws IOException { + gridTransform( + context, true, 2, 4, MOON_PHASES, + FULL_MOON, WANING_GIBBOUS, THIRD_QUARTER, WANING_CRESCENT, + NEW_MOON, WAXING_CRESCENT, FIRST_QUARTER, WAXING_GIBBOUS + ); + } +} diff --git a/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/ui/IconTransformer.java b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/ui/IconTransformer.java index ac595e9..e84c4f5 100644 --- a/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/ui/IconTransformer.java +++ b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/ui/IconTransformer.java @@ -30,18 +30,11 @@ import com.google.auto.service.AutoService; import net.kyori.adventure.key.Key; import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer; import org.geysermc.pack.converter.type.texture.transformer.TransformContext; -import org.geysermc.pack.converter.util.ImageUtil; import org.jetbrains.annotations.NotNull; -import team.unnamed.creative.texture.Texture; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.stream.DoubleStream; @AutoService(TextureTransformer.class) public class IconTransformer implements TextureTransformer { @@ -91,12 +84,12 @@ public class IconTransformer implements TextureTransformer { @Override public void transform(@NotNull TransformContext context) throws IOException { - horizontalTransform( - context, false, BEDROCK_ARMOR, + gridTransform( + context, false, 1, 4, BEDROCK_ARMOR, HELMET, CHESTPLATE, LEGGINGS, BOOTS ); - horizontalTransform( - context, true, BEDROCK_ARMOR_TOOLS, + gridTransform( + context, true, 1, 12, BEDROCK_ARMOR_TOOLS, HELMET, SWORD, CHESTPLATE, PICKAXE, LEGGINGS, AXE, BOOTS, HOE, SPEAR, SHOVEL, HORSE_ARMOR, NAUTILUS_ARMOR ); @@ -104,16 +97,16 @@ public class IconTransformer implements TextureTransformer { context, false, BEDROCK_LAPIS_LAZULI, BEDROCK_IMAGE_LAPIS_LAZULI, LAPIS_LAZULI ); - horizontalTransform( - context, true, BEDROCK_MATERIALS, + gridTransform( + context, true, 1, 7, BEDROCK_MATERIALS, INGOT, REDSTONE_DUST, LAPIS_LAZULI, QUARTZ, DIAMOND, EMERALD, AMETHYST_SHARD ); passThroughTransform(context, true, BEDROCK_BANNER, BANNER); passThroughTransform(context, true, BEDROCK_DYE, DYE); passThroughTransform(context, true, BEDROCK_BANNER_PATTERN, BANNER_PATTERN); - horizontalTransform( - context, true, BEDROCK_TEMPLATES, + gridTransform( + context, true, 1, 2, BEDROCK_TEMPLATES, NETHERITE_UPGRADE, ARMOR_TRIM ); passThroughTransform(context, true, BEDROCK_BREWING_FUEL, BREWING_FUEL); @@ -144,50 +137,4 @@ public class IconTransformer implements TextureTransformer { context.offer(bedrockImageOutput, img2, "png"); } - - private void horizontalTransform(@NotNull TransformContext context, boolean poll, Key bedrockOutput, Key... javaInputs) throws IOException { - boolean exists = false; - - for (Key javaInput : javaInputs) { - if (context.isTexturePresent(javaInput)) { - exists = true; - break; - } - } - - if (!exists) return; - - List textures = Arrays.stream(javaInputs) - .map(key -> poll ? context.pollOrPeekVanilla(key) : context.peekOrVanilla(key)).toList(); - - List images = new ArrayList<>(textures.size()); - - for (Texture texture : textures) { - if (texture == null) images.add(null); - else images.add(this.readImage(texture)); - } - - float maxScale = (float) images.stream() - .flatMapToDouble(img -> DoubleStream.of(img == null ? 1f : img.getWidth() / 16f)) - .max().orElseThrow(); - - BufferedImage bedrockOutputImage = new BufferedImage((int) (maxScale * 16 * images.size()), (int) (maxScale * 16), BufferedImage.TYPE_INT_ARGB); - - Graphics graphics = bedrockOutputImage.getGraphics(); - - for (int i = 0; i < images.size(); i++) { - BufferedImage image = images.get(i); - if (image != null) { - float scale = maxScale / (image.getWidth() / 16f); - - graphics.drawImage( - ImageUtil.scale(image, scale), - (int) (maxScale * 16 * i), - 0, null - ); - } - } - - context.offer(bedrockOutput, bedrockOutputImage, "png"); - } } diff --git a/converter/src/main/resources/mappings/textures.json b/converter/src/main/resources/mappings/textures.json index c29b25c..ce5b405 100644 --- a/converter/src/main/resources/mappings/textures.json +++ b/converter/src/main/resources/mappings/textures.json @@ -1194,7 +1194,7 @@ }, "environment": { "clouds": "clouds", - "moon_phases": "moon_phases" + "celestial/sun": "sun" }, "font": {