1
0
mirror of https://github.com/GeyserMC/PackConverter.git synced 2025-12-19 14:59:21 +00:00

Add EnvironmentTransformer for the moon phase changes

This commit is contained in:
Aurora
2025-11-07 16:44:39 +00:00
parent e11e718c69
commit 5d96129df0
4 changed files with 125 additions and 62 deletions

View File

@@ -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<Texture> textures = Arrays.stream(javaInputs)
.map(key -> poll ? context.pollOrPeekVanilla(key) : context.peekOrVanilla(key)).toList();
List<BufferedImage> 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");
}
}

View File

@@ -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
);
}
}

View File

@@ -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<Texture> textures = Arrays.stream(javaInputs)
.map(key -> poll ? context.pollOrPeekVanilla(key) : context.peekOrVanilla(key)).toList();
List<BufferedImage> 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");
}
}

View File

@@ -1194,7 +1194,7 @@
},
"environment": {
"clouds": "clouds",
"moon_phases": "moon_phases"
"celestial/sun": "sun"
},
"font": {