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

Start work on TGA image conversion and overlays

This commit is contained in:
RednedEpic
2023-05-29 00:22:01 -05:00
parent d50368fe41
commit 530bd2dd38
6 changed files with 371 additions and 155 deletions

View File

@@ -0,0 +1,202 @@
/*
* Copyright (c) 2019-2023 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", new Mapping(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.converter.texture;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
// TODO: This should really be a JSON file
public final class PngToTgaMappings {
private static final Map<String, TgaMapping> MAPPINGS = new HashMap<>() {
{
put("textures/blocks/cactus_bottom.png", new TgaMapping("textures/blocks/cactus_bottom.tga"));
put("textures/blocks/cactus_side.png", new TgaMapping("textures/blocks/cactus_side.tga"));
put("textures/blocks/cactus_top.png", new TgaMapping("textures/blocks/cactus_top.tga"));
put("textures/blocks/double_plant_fern_bottom.png", new TgaMapping("textures/blocks/double_plant_fern_bottom.tga"));
put("textures/blocks/double_plant_fern_top.png", new TgaMapping("textures/blocks/double_plant_fern_top.tga"));
put("textures/blocks/double_plant_grass_bottom.png", new TgaMapping("textures/blocks/double_plant_grass_bottom.tga"));
put("textures/blocks/double_plant_grass_top.png", new TgaMapping("textures/blocks/double_plant_grass_top.tga"));
put("textures/blocks/double_plant_syringa_bottom.png", new TgaMapping("textures/blocks/double_plant_syringa_bottom.tga"));
put("textures/blocks/double_plant_syringa_top.png", new TgaMapping("textures/blocks/double_plant_syringa_top.tga"));
put("textures/blocks/fern.png", new TgaMapping("textures/blocks/fern.tga"));
put("textures/blocks/fern_carried.png", new TgaMapping("textures/blocks/fern_carried.tga"));
put("textures/blocks/grass_side.png", new TgaMapping("textures/blocks/grass_side.tga"));
put("textures/blocks/grass_side_snowed.png", new TgaMapping("textures/blocks/grass_side_snowed.tga", true));
put("textures/blocks/grindstone_pivot.png", new TgaMapping("textures/blocks/grindstone_pivot.tga"));
put("textures/blocks/grindstone_round.png", new TgaMapping("textures/blocks/grindstone_round.tga"));
put("textures/blocks/grindstone_side.png", new TgaMapping("textures/blocks/grindstone_side.tga"));
put("textures/blocks/kelp_a.png", new TgaMapping("textures/blocks/kelp_a.tga"));
put("textures/blocks/kelp_b.png", new TgaMapping("textures/blocks/kelp_b.tga"));
put("textures/blocks/kelp_c.png", new TgaMapping("textures/blocks/kelp_c.tga"));
put("textures/blocks/kelp_d.png", new TgaMapping("textures/blocks/kelp_d.tga"));
put("textures/blocks/kelp_top.png", new TgaMapping("textures/blocks/kelp_top.tga"));
put("textures/blocks/kelp_top_bulb.png", new TgaMapping("textures/blocks/kelp_top_bulb.tga"));
put("textures/blocks/leaves_acacia.png", new TgaMapping("textures/blocks/leaves_acacia.tga"));
put("textures/blocks/leaves_acacia_carried.png", new TgaMapping("textures/blocks/leaves_acacia_carried.tga"));
put("textures/blocks/leaves_big_oak.png", new TgaMapping("textures/blocks/leaves_big_oak.tga"));
put("textures/blocks/leaves_big_oak_carried.png", new TgaMapping("textures/blocks/leaves_big_oak_carried.tga"));
put("textures/blocks/leaves_birch.png", new TgaMapping("textures/blocks/leaves_birch.tga"));
put("textures/blocks/leaves_birch_carried.png", new TgaMapping("textures/blocks/leaves_birch_carried.tga"));
put("textures/blocks/leaves_jungle.png", new TgaMapping("textures/blocks/leaves_jungle.tga"));
put("textures/blocks/leaves_jungle_carried.png", new TgaMapping("textures/blocks/leaves_jungle_carried.tga"));
put("textures/blocks/leaves_oak.png", new TgaMapping("textures/blocks/leaves_oak.tga"));
put("textures/blocks/leaves_oak_carried.png", new TgaMapping("textures/blocks/leaves_oak_carried.tga"));
put("textures/blocks/leaves_spruce.png", new TgaMapping("textures/blocks/leaves_spruce.tga"));
put("textures/blocks/leaves_spruce_carried.png", new TgaMapping("textures/blocks/leaves_spruce_carried.tga"));
put("textures/blocks/reeds.png", new TgaMapping("textures/blocks/reeds.tga"));
put("textures/blocks/scaffolding_bottom.png", new TgaMapping("textures/blocks/scaffolding_bottom.tga"));
put("textures/blocks/scaffolding_side.png", new TgaMapping("textures/blocks/scaffolding_side.tga"));
put("textures/blocks/scaffolding_top.png", new TgaMapping("textures/blocks/scaffolding_top.tga"));
put("textures/blocks/seagrass_doubletall_bottom_a.png", new TgaMapping("textures/blocks/seagrass_doubletall_bottom_a.tga"));
put("textures/blocks/seagrass_doubletall_bottom_b.png", new TgaMapping("textures/blocks/seagrass_doubletall_bottom_b.tga"));
put("textures/blocks/seagrass_doubletall_top_a.png", new TgaMapping("textures/blocks/seagrass_doubletall_top_a.tga"));
put("textures/blocks/seagrass_doubletall_top_b.png", new TgaMapping("textures/blocks/seagrass_doubletall_top_b.tga"));
put("textures/blocks/stonecutter2_saw.png", new TgaMapping("textures/blocks/stonecutter2_saw.tga"));
put("textures/blocks/tallgrass.png", new TgaMapping("textures/blocks/tallgrass.tga", true));
put("textures/blocks/tallgrass_carried.png", new TgaMapping("textures/blocks/tallgrass_carried.tga"));
put("textures/entity/blaze.png", new TgaMapping("textures/entity/blaze.tga"));
put("textures/entity/phantom.png", new TgaMapping("textures/entity/phantom.tga"));
put("textures/entity/banner/banner.png", new TgaMapping("textures/entity/banner/banner.tga"));
put("textures/entity/banner/banner_pattern_illager.png", new TgaMapping("textures/entity/banner/banner_pattern_illager.tga"));
put("textures/entity/banner_base.png", new TgaMapping("textures/entity/banner/banner_base.tga"));
put("textures/entity/banner/border.png", new TgaMapping("textures/entity/banner/banner_border.tga"));
put("textures/entity/banner/bricks.png", new TgaMapping("textures/entity/banner/banner_bricks.tga"));
put("textures/entity/banner/circle.png", new TgaMapping("textures/entity/banner/banner_circle.tga"));
put("textures/entity/banner/creeper.png", new TgaMapping("textures/entity/banner/banner_creeper.tga"));
put("textures/entity/banner/cross.png", new TgaMapping("textures/entity/banner/banner_cross.tga"));
put("textures/entity/banner/curly_border.png", new TgaMapping("textures/entity/banner/banner_curly_border.tga"));
put("textures/entity/banner/diagonal_left.png", new TgaMapping("textures/entity/banner/banner_diagonal_left.tga"));
put("textures/entity/banner/diagonal_right.png", new TgaMapping("textures/entity/banner/banner_diagonal_right.tga"));
put("textures/entity/banner/diagonal_up_left.png", new TgaMapping("textures/entity/banner/banner_diagonal_up_left.tga"));
put("textures/entity/banner/diagonal_up_right.png", new TgaMapping("textures/entity/banner/banner_diagonal_up_right.tga"));
put("textures/entity/banner/flower.png", new TgaMapping("textures/entity/banner/banner_flower.tga"));
put("textures/entity/banner/gradient.png", new TgaMapping("textures/entity/banner/banner_gradient.tga"));
put("textures/entity/banner/gradient_up.png", new TgaMapping("textures/entity/banner/banner_gradient_up.tga"));
put("textures/entity/banner/half_horizontal.png", new TgaMapping("textures/entity/banner/banner_half_horizontal.tga"));
put("textures/entity/banner/half_horizontal_bottom.png", new TgaMapping("textures/entity/banner/banner_half_horizontal_bottom.tga"));
put("textures/entity/banner/half_vertical.png", new TgaMapping("textures/entity/banner/banner_half_vertical.tga"));
put("textures/entity/banner/half_vertical_right.png", new TgaMapping("textures/entity/banner/banner_half_vertical_right.tga"));
put("textures/entity/banner/mojang.png", new TgaMapping("textures/entity/banner/banner_mojang.tga"));
put("textures/entity/banner/piglin.png", new TgaMapping("textures/entity/banner/banner_piglin.tga"));
put("textures/entity/banner/rhombus.png", new TgaMapping("textures/entity/banner/banner_rhombus.tga"));
put("textures/entity/banner/skull.png", new TgaMapping("textures/entity/banner/banner_skull.tga"));
put("textures/entity/banner/small_stripes.png", new TgaMapping("textures/entity/banner/banner_small_stripes.tga"));
put("textures/entity/banner/square_bottom_left.png", new TgaMapping("textures/entity/banner/banner_square_bottom_left.tga"));
put("textures/entity/banner/square_bottom_right.png", new TgaMapping("textures/entity/banner/banner_square_bottom_right.tga"));
put("textures/entity/banner/square_top_left.png", new TgaMapping("textures/entity/banner/banner_square_top_left.tga"));
put("textures/entity/banner/square_top_right.png", new TgaMapping("textures/entity/banner/banner_square_top_right.tga"));
put("textures/entity/banner/straight_cross.png", new TgaMapping("textures/entity/banner/banner_straight_cross.tga"));
put("textures/entity/banner/stripe_bottom.png", new TgaMapping("textures/entity/banner/banner_stripe_bottom.tga"));
put("textures/entity/banner/stripe_center.png", new TgaMapping("textures/entity/banner/banner_stripe_center.tga"));
put("textures/entity/banner/stripe_downleft.png", new TgaMapping("textures/entity/banner/banner_stripe_downleft.tga"));
put("textures/entity/banner/stripe_downright.png", new TgaMapping("textures/entity/banner/banner_stripe_downright.tga"));
put("textures/entity/banner/stripe_left.png", new TgaMapping("textures/entity/banner/banner_stripe_left.tga"));
put("textures/entity/banner/stripe_middle.png", new TgaMapping("textures/entity/banner/banner_stripe_middle.tga"));
put("textures/entity/banner/stripe_right.png", new TgaMapping("textures/entity/banner/banner_stripe_right.tga"));
put("textures/entity/banner/stripe_top.png", new TgaMapping("textures/entity/banner/banner_stripe_top.tga"));
put("textures/entity/banner/triangle_bottom.png", new TgaMapping("textures/entity/banner/banner_triangle_bottom.tga"));
put("textures/entity/banner/triangle_top.png", new TgaMapping("textures/entity/banner/banner_triangle_top.tga"));
put("textures/entity/banner/triangles_bottom.png", new TgaMapping("textures/entity/banner/banner_triangles_bottom.tga"));
put("textures/entity/banner/triangles_top.png", new TgaMapping("textures/entity/banner/banner_triangles_top.tga"));
put("textures/entity/cat/allblackcat_tame.png", new TgaMapping("textures/entity/cat/allblackcat_tame.tga"));
put("textures/entity/cat/britishshorthair_tame.png", new TgaMapping("textures/entity/cat/britishshorthair_tame.tga"));
put("textures/entity/cat/calico_tame.png", new TgaMapping("textures/entity/cat/calico_tame.tga"));
put("textures/entity/cat/graytabby_tame.png", new TgaMapping("textures/entity/cat/graytabby_tame.tga"));
put("textures/entity/cat/jellie_tame.png", new TgaMapping("textures/entity/cat/jellie_tame.tga"));
put("textures/entity/cat/ocelot_tame.png", new TgaMapping("textures/entity/cat/ocelot_tame.tga"));
put("textures/entity/cat/persian_tame.png", new TgaMapping("textures/entity/cat/persian_tame.tga"));
put("textures/entity/cat/ragdoll_tame.png", new TgaMapping("textures/entity/cat/ragdoll_tame.tga"));
put("textures/entity/cat/redtabby_tame.png", new TgaMapping("textures/entity/cat/redtabby_tame.tga"));
put("textures/entity/cat/siamesecat_tame.png", new TgaMapping("textures/entity/cat/siamesecat_tame.tga"));
put("textures/entity/cat/tabby_tame.png", new TgaMapping("textures/entity/cat/tabby_tame.tga"));
put("textures/entity/cat/tuxedo_tame.png", new TgaMapping("textures/entity/cat/tuxedo_tame.tga"));
put("textures/entity/cat/white_tame.png", new TgaMapping("textures/entity/cat/white_tame.tga"));
put("textures/entity/dragon/dragon.png", new TgaMapping("textures/entity/dragon/dragon.tga"));
put("textures/entity/enderman/enderman.png", new TgaMapping("textures/entity/enderman/enderman.tga"));
put("textures/entity/ghast/ghast_shooting.png", new TgaMapping("textures/entity/ghast/ghast_shooting.tga"));
put("textures/entity/horse/armor/horse_armor_leather.png", new TgaMapping("textures/entity/horse/armor/horse_armor_leather.tga"));
put("textures/entity/horse2/armor/horse_armor_leather.png", new TgaMapping("textures/entity/horse2/armor/horse_armor_leather.tga"));
put("textures/entity/sheep/sheep.png", new TgaMapping("textures/entity/sheep/sheep.tga"));
put("textures/entity/slime/magmacube.png", new TgaMapping("textures/entity/slime/magmacube.tga"));
put("textures/entity/spider/cave_spider.png", new TgaMapping("textures/entity/spider/cave_spider.tga"));
put("textures/entity/spider/spider.png", new TgaMapping("textures/entity/spider/spider.tga"));
put("textures/entity/villager2/professions/armorer.png", new TgaMapping("textures/entity/villager2/professions/armorer.tga"));
put("textures/entity/villager2/professions/butcher.png", new TgaMapping("textures/entity/villager2/professions/butcher.tga"));
put("textures/entity/villager2/professions/cartographer.png", new TgaMapping("textures/entity/villager2/professions/cartographer.tga"));
put("textures/entity/villager2/professions/cleric.png", new TgaMapping("textures/entity/villager2/professions/cleric.tga"));
put("textures/entity/villager2/professions/farmer.png", new TgaMapping("textures/entity/villager2/professions/farmer.tga"));
put("textures/entity/villager2/professions/fisherman.png", new TgaMapping("textures/entity/villager2/professions/fisherman.tga"));
put("textures/entity/villager2/professions/fletcher.png", new TgaMapping("textures/entity/villager2/professions/fletcher.tga"));
put("textures/entity/villager2/professions/leatherworker.png", new TgaMapping("textures/entity/villager2/professions/leatherworker.tga"));
put("textures/entity/villager2/professions/librarian.png", new TgaMapping("textures/entity/villager2/professions/librarian.tga"));
put("textures/entity/villager2/professions/nitwit.png", new TgaMapping("textures/entity/villager2/professions/nitwit.tga"));
put("textures/entity/villager2/professions/shepherd.png", new TgaMapping("textures/entity/villager2/professions/shepherd.tga"));
put("textures/entity/villager2/professions/stonemason.png", new TgaMapping("textures/entity/villager2/professions/stonemason.tga"));
put("textures/entity/villager2/professions/toolsmith.png", new TgaMapping("textures/entity/villager2/professions/toolsmith.tga"));
put("textures/entity/villager2/professions/unskilled.png", new TgaMapping("textures/entity/villager2/professions/unskilled.tga"));
put("textures/entity/villager2/professions/weaponsmith.png", new TgaMapping("textures/entity/villager2/professions/weaponsmith.tga"));
put("textures/entity/wolf/wolf_tame.png", new TgaMapping("textures/entity/wolf/wolf_tame.tga"));
put("textures/entity/zombie/drowned.png", new TgaMapping("textures/entity/zombie/drowned.tga"));
put("textures/entity/zombie_villager2/professions/armorer.png", new TgaMapping("textures/entity/zombie_villager2/professions/armorer.tga"));
put("textures/entity/zombie_villager2/professions/butcher.png", new TgaMapping("textures/entity/zombie_villager2/professions/butcher.tga"));
put("textures/entity/zombie_villager2/professions/cartographer.png", new TgaMapping("textures/entity/zombie_villager2/professions/cartographer.tga"));
put("textures/entity/zombie_villager2/professions/cleric.png", new TgaMapping("textures/entity/zombie_villager2/professions/cleric.tga"));
put("textures/entity/zombie_villager2/professions/farmer.png", new TgaMapping("textures/entity/zombie_villager2/professions/farmer.tga"));
put("textures/entity/zombie_villager2/professions/fisherman.png", new TgaMapping("textures/entity/zombie_villager2/professions/fisherman.tga"));
put("textures/entity/zombie_villager2/professions/fletcher.png", new TgaMapping("textures/entity/zombie_villager2/professions/fletcher.tga"));
put("textures/entity/zombie_villager2/professions/leatherworker.png", new TgaMapping("textures/entity/zombie_villager2/professions/leatherworker.tga"));
put("textures/entity/zombie_villager2/professions/librarian.png", new TgaMapping("textures/entity/zombie_villager2/professions/librarian.tga"));
put("textures/entity/zombie_villager2/professions/nitwit.png", new TgaMapping("textures/entity/zombie_villager2/professions/nitwit.tga"));
put("textures/entity/zombie_villager2/professions/shepherd.png", new TgaMapping("textures/entity/zombie_villager2/professions/shepherd.tga"));
put("textures/entity/zombie_villager2/professions/stonemason.png", new TgaMapping("textures/entity/zombie_villager2/professions/stonemason.tga"));
put("textures/entity/zombie_villager2/professions/toolsmith.png", new TgaMapping("textures/entity/zombie_villager2/professions/toolsmith.tga"));
put("textures/entity/zombie_villager2/professions/weaponsmith.png", new TgaMapping("textures/entity/zombie_villager2/professions/weaponsmith.tga"));
put("textures/items/fireworks_charge.png", new TgaMapping("textures/items/fireworks_charge.tga"));
put("textures/items/leather_boots.png", new TgaMapping("textures/items/leather_boots.tga"));
put("textures/items/leather_helmet.png", new TgaMapping("textures/items/leather_helmet.tga"));
put("textures/items/leather_horse_armor.png", new TgaMapping("textures/items/leather_horse_armor.tga"));
put("textures/items/leather_leggings.png", new TgaMapping("textures/items/leather_leggings.tga"));
put("textures/models/armor/leather_1.png", new TgaMapping("textures/models/armor/leather_1.tga"));
put("textures/models/armor/leather_2.png", new TgaMapping("textures/models/armor/leather_2.tga"));
}
};
@Nullable
public static TgaMapping mapping(@NotNull String key) {
return MAPPINGS.get(key);
}
record TgaMapping(String value, boolean keep) {
public TgaMapping(String value) {
this(value, false);
}
}
}

View File

@@ -100,21 +100,39 @@ public class TextureConverter implements Converter<TextureConversionData> {
Files.createDirectories(textureOutput.getParent()); Files.createDirectories(textureOutput.getParent());
} }
try (OutputStream stream = Files.newOutputStream(textureOutput)) { byte[] bytes = texture.data().toByteArray();
byte[] bytes = texture.data().toByteArray();
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
if (!image.getColorModel().hasAlpha()) {
BufferedImage newImage = new BufferedImage(
image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = newImage.createGraphics(); String pngKey = "textures/" + texture.key().value();
g.drawImage(image, 0, 0, null); PngToTgaMappings.TgaMapping mapping = PngToTgaMappings.mapping(pngKey);
g.dispose(); if (mapping != null) {
Path tgaPath = context.outputDirectory().resolve(mapping.value());
image = newImage; if (Files.notExists(tgaPath.getParent())) {
Files.createDirectories(tgaPath.getParent());
} }
try (OutputStream tgaStream = Files.newOutputStream(tgaPath)) {
ImageIO.write(image, "tga", tgaStream);
if (!mapping.keep()) {
Files.deleteIfExists(textureOutput);
continue;
}
}
}
if (!image.getColorModel().hasAlpha()) {
BufferedImage newImage = new BufferedImage(
image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
image = newImage;
}
try (OutputStream stream = Files.newOutputStream(textureOutput)) {
ImageIO.write(image, "png", stream); ImageIO.write(image, "png", stream);
} }

View File

@@ -260,7 +260,7 @@ public class ColorizeTransformer implements BulkTextureTransformer {
Key key = Key.key(Key.MINECRAFT_NAMESPACE, overlayPath); Key key = Key.key(Key.MINECRAFT_NAMESPACE, overlayPath);
Texture texture = deleteOverlay ? context.poll(key) : context.peek(key); Texture texture = deleteOverlay ? context.poll(key) : context.peek(key);
if (texture == null) { if (texture == null) {
context.warn("Missing overlay texture: " + overlayPath); context.info("Missing overlay texture: " + overlayPath);
continue; continue;
} }

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2019-2023 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.converter.texture.transformer.bulk.type;
import com.google.auto.service.AutoService;
import net.kyori.adventure.key.Key;
import org.geysermc.pack.converter.converter.texture.transformer.bulk.BulkTextureTransformer;
import org.geysermc.pack.converter.converter.texture.transformer.bulk.BulkTransformContext;
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.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
@AutoService(BulkTextureTransformer.class)
public class OverlayTransformer implements BulkTextureTransformer {
private static final List<OverlayData> OVERLAYS = List.of(
// Cat
new OverlayData("entity/cat/cat_collar.png", "entity/cat/all_black.png", "entity/cat/allblackcat_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/british_shorthair.png", "entity/cat/britishshorthair_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/calico.png", "entity/cat/calico_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/jellie.png", "entity/cat/jellie_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/ocelot.png", "entity/cat/ocelot_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/persian.png", "entity/cat/persian_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/ragdoll.png", "entity/cat/ragdoll_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/red.png", "entity/cat/redtabby_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/siamese.png", "entity/cat/siamesecat_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/tabby.png", "entity/cat/tabby_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/black.png", "entity/cat/tuxedo_tame.png", false, true),
new OverlayData("entity/cat/cat_collar.png", "entity/cat/white.png", "entity/cat/white_tame.png", false, true),
// Enderman
new OverlayData("entity/enderman/enderman.png", "entity/enderman/enderman_eyes.png", "entity/enderman/enderman.png", true),
// Firework
new OverlayData("item/firework_star_overlay.png", "item/firework_star.png", "items/fireworks_charge.png", false),
// Grass
new OverlayData("block/grass_block_side_overlay.png", "block/grass_block_side.png", "blocks/grass_side.png", false, true),
// Leather
new OverlayData("item/leather_boots.png", "item/leather_boots_overlay.png", "items/leather_boots.png", true),
new OverlayData("item/leather_chestplate.png", "item/leather_chestplate_overlay.png", "items/leather_chestplate.png", true),
new OverlayData("item/leather_helmet.png", "item/leather_helmet_overlay.png", "items/leather_helmet.png", true),
new OverlayData("item/leather_leggings.png", "item/leather_leggings_overlay.png", "items/leather_leggings.png", true),
new OverlayData("models/armor/leather_layer_1.png", "models/armor/leather_layer_1_overlay.png", "models/armor/leather_1.png", true),
new OverlayData("models/armor/leather_layer_2.png", "models/armor/leather_layer_2_overlay.png", "models/armor/leather_2.png", true),
// Phantom
new OverlayData("entity/phantom.png", "entity/phantom_eyes.png", "entity/phantom.png", true),
// Spider
new OverlayData("entity/spider/cave_spider.png", "entity/spider_eyes.png", "entity/spider/cave_spider.png", true, true),
new OverlayData("entity/spider/spider.png", "entity/spider_eyes.png", "entity/spider/spider.png", true),
// Wolf
new OverlayData("entity/wolf/wolf_collar.png", "entity/wolf/wolf_tame.png", "entity/wolf/wolf_tame.png", false, true)
);
@Override
public void transform(@NotNull BulkTransformContext context) throws IOException {
for (OverlayData overlay : OVERLAYS) {
String javaName = overlay.javaName();
String overlayName = overlay.overlay();
String bedrockName = overlay.bedrockName();
boolean reverse = overlay.reverse();
boolean keep = overlay.keep();
Texture texture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, javaName));
if (texture == null) {
context.info(String.format("Base overlay texture %s not found", javaName));
continue;
}
Texture overlayTexture = keep ? context.peek(Key.key(Key.MINECRAFT_NAMESPACE, overlayName)) : context.poll(Key.key(Key.MINECRAFT_NAMESPACE, overlayName));
if (overlayTexture == null) {
context.info(String.format("Overlay texture %s not found", overlayName));
continue;
}
context.info(String.format("Overlaying %s and %s onto %s", overlayName, javaName, bedrockName));
BufferedImage image = ImageIO.read(new ByteArrayInputStream(texture.data().toByteArray()));
BufferedImage imageOverlay = ImageIO.read(new ByteArrayInputStream(overlayTexture.data().toByteArray()));
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
Color c = new Color(image.getRGB(x, y), true);
if (reverse ? c.getAlpha() > 0 : c.getAlpha() < 255) {
Color newCol = new Color(imageOverlay.getRGB(x, y), true);
newCol = new Color(newCol.getRed(), newCol.getGreen(), newCol.getBlue(), 2);
image.setRGB(x, y, ImageUtil.colorToARGB(newCol));
}
}
}
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, bedrockName), image, "png");
}
}
record OverlayData(@NotNull String javaName, @NotNull String overlay, @NotNull String bedrockName, boolean reverse, boolean keep) {
public OverlayData(@NotNull String javaName, @NotNull String overlay, @NotNull String bedrockName, boolean reverse) {
this(javaName, overlay, bedrockName, reverse, false);
}
}
}

View File

@@ -132,7 +132,8 @@
"yellow_glazed_terracotta": "glazed_terracotta_yellow", "yellow_glazed_terracotta": "glazed_terracotta_yellow",
"grass_block_snow": "grass_side_snowed", "grass_block_snow": "grass_side_snowed",
"grass": "tallgrass", "grass": "tallgrass",
"grass_block_side": "grass_side", "grass_block_side": "grass_side_carried",
"grass_block_side_overlay": "grass_side",
"grass_block_top": "grass_top", "grass_block_top": "grass_top",
"terracotta": "hardened_clay", "terracotta": "hardened_clay",
"black_terracotta": "hardened_clay_stained_black", "black_terracotta": "hardened_clay_stained_black",

View File

@@ -1,142 +0,0 @@
/*
* Copyright (c) 2019-2023 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.packconverter.converters;
import com.google.auto.service.AutoService;
import lombok.Getter;
import org.geysermc.packconverter.PackConversionContext;
import org.geysermc.packconverter.PackConverter;
import org.geysermc.packconverter.utils.ImageUtils;
import org.jetbrains.annotations.NotNull;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@AutoService(Converter.class)
public class OverlayToTranslateConverter extends AbstractConverter {
@Getter
public static final List<Object[]> defaultData = new ArrayList<>();
static {
// Cat
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/allblackcat.png", "textures/entity/cat/allblackcat_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/britishshorthair.png", "textures/entity/cat/britishshorthair_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/calico.png", "textures/entity/cat/calico_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/jellie.png", "textures/entity/cat/jellie_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/ocelot.png", "textures/entity/cat/ocelot_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/persian.png", "textures/entity/cat/persian_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/ragdoll.png", "textures/entity/cat/ragdoll_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/redtabby.png", "textures/entity/cat/redtabby_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/siamesecat.png", "textures/entity/cat/siamesecat_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/tabby.png", "textures/entity/cat/tabby_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/tuxedo.png", "textures/entity/cat/tuxedo_tame.png", false, true});
defaultData.add(new Object[] {"textures/entity/cat/graytabby_tame.png", "textures/entity/cat/white.png", "textures/entity/cat/white_tame.png", false, true});
// Enderman
defaultData.add(new Object[] {"textures/entity/enderman/enderman.png", "textures/entity/enderman/enderman_eyes.png", "textures/entity/enderman/enderman.png", true});
// Firework
defaultData.add(new Object[] {"textures/items/fireworks_charge.png", "textures/items/firework_star.png", "textures/items/fireworks_charge.png", false});
// Grass
defaultData.add(new Object[] {"textures/blocks/grass_side.png", "textures/blocks/grass_side_carried.png", "textures/blocks/grass_side.png", false, true});
// Leather
defaultData.add(new Object[] {"textures/items/leather_boots.png", "textures/items/leather_boots_overlay.png", "textures/items/leather_boots.png", true});
defaultData.add(new Object[] {"textures/items/leather_chestplate.png", "textures/items/leather_chestplate_overlay.png", "textures/items/leather_chestplate.png", true});
defaultData.add(new Object[] {"textures/items/leather_helmet.png", "textures/items/leather_helmet_overlay.png", "textures/items/leather_helmet.png", true});
defaultData.add(new Object[] {"textures/items/leather_leggings.png", "textures/items/leather_leggings_overlay.png", "textures/items/leather_leggings.png", true});
defaultData.add(new Object[] {"textures/models/armor/leather_1.png", "textures/models/armor/leather_1_overlay.png", "textures/models/armor/leather_1.png", true});
defaultData.add(new Object[] {"textures/models/armor/leather_2.png", "textures/models/armor/leather_2_overlay.png", "textures/models/armor/leather_2.png", true});
// Phantom
defaultData.add(new Object[] {"textures/entity/phantom.png", "textures/entity/phantom_eyes.png", "textures/entity/phantom.png", true});
// Spider
defaultData.add(new Object[] {"textures/entity/spider/cave_spider.png", "textures/entity/spider_eyes.png", "textures/entity/spider/cave_spider.png", true, true});
defaultData.add(new Object[] {"textures/entity/spider/spider.png", "textures/entity/spider_eyes.png", "textures/entity/spider/spider.png", true});
// Wolf
defaultData.add(new Object[] {"textures/entity/wolf/wolf_collar.png", "textures/entity/wolf/wolf_tame.png", "textures/entity/wolf/wolf_tame.png", false, true});
}
public OverlayToTranslateConverter(PackConverter packConverter, Path storage, Object[] data) {
super(packConverter, storage, data);
}
@Override
public List<AbstractConverter> convert(@NotNull PackConversionContext context) {
List<AbstractConverter> delete = new ArrayList<>();
try {
String from = (String) context.data()[0];
String overlay = (String) context.data()[1];
String to = (String) context.data()[2];
boolean reverse = (boolean) context.data()[3];
boolean dontDelete = context.data().length > 4 && (boolean) context.data()[4];
File fromFile = storage.resolve(from).toFile();
File overlayFile = storage.resolve(overlay).toFile();
if (!fromFile.exists() || !overlayFile.exists()) {
return delete;
}
context.log(String.format("Create translated overlay %s", to));
BufferedImage image = ImageIO.read(fromFile);
BufferedImage imageOverlay = ImageIO.read(overlayFile);
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
Color c = new Color(image.getRGB(x, y), true);
if (reverse ? c.getAlpha() > 0 : c.getAlpha() < 255) {
Color newCol = new Color(imageOverlay.getRGB(x, y), true);
newCol = new Color(newCol.getRed(), newCol.getGreen(), newCol.getBlue(), 2);
image.setRGB(x, y, ImageUtils.colorToARGB(newCol));
}
}
}
ImageUtils.write(image, "png", storage.resolve(to).toFile());
if (!dontDelete) {
delete.add(new DeleteConverter(packConverter, storage, new Object[] {overlay}));
}
} catch (IOException e) { }
return delete;
}
}