diff --git a/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/entity/CamelTransformer.java b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/entity/CamelTransformer.java new file mode 100644 index 0000000..eba30da --- /dev/null +++ b/converter/src/main/java/org/geysermc/pack/converter/type/texture/transformer/type/entity/CamelTransformer.java @@ -0,0 +1,107 @@ +/* + * 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.entity; + +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.geysermc.pack.converter.util.KeyUtil; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Text; +import team.unnamed.creative.texture.Texture; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.IOException; + +@AutoService(TextureTransformer.class) +public class CamelTransformer implements TextureTransformer { + private static final Key CAMEL = KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/camel/camel.png"); + private static final Key CAMEL_SADDLE = KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/equipment/camel_saddle/saddle.png"); + private static final Key CAMEL_HUSK = KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/camel/camel_husk.png"); + private static final Key CAMEL_HUSK_BEDROCK = KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/camel_husk/camel_husk.png"); + private static final Key CAMEL_HUSK_SADDLE = KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/equipment/camel_husk_saddle/saddle.png"); + + @Override + public void transform(@NotNull TransformContext context) throws IOException { + if (context.isTexturePresent(CAMEL) || context.isTexturePresent(CAMEL_SADDLE)) { + Texture camelTexture = context.pollOrPeekVanilla(CAMEL); + Texture saddleTexture = context.pollOrPeekVanilla(CAMEL_SADDLE); + handleCamel(context, camelTexture, saddleTexture, CAMEL); + } + + if (context.isTexturePresent(CAMEL_HUSK) || context.isTexturePresent(CAMEL_HUSK_SADDLE)) { + Texture camelTexture = context.pollOrPeekVanilla(CAMEL_HUSK); + Texture saddleTexture = context.pollOrPeekVanilla(CAMEL_HUSK_SADDLE); + handleCamel(context, camelTexture, saddleTexture, CAMEL_HUSK_BEDROCK); + } + } + + private void handleCamel(@NotNull TransformContext context, Texture camelTexture, Texture saddleTexture, Key bedrockKey) throws IOException { + BufferedImage camelImage = this.readImage(camelTexture); + if (camelImage == null) { + context.error("Unable to read camel image! Skipping..."); + return; + } + + BufferedImage saddleImage = this.readImage(saddleTexture); + if (saddleImage == null) { + context.error("Unable to read camel saddle image! Skipping..."); + return; + } + + float scale = camelImage.getWidth() / 128f; + + float saddlePreScale = scale / (saddleImage.getWidth() / 128f); + + BufferedImage scaledSaddleImage = ImageUtil.scale(saddleImage, saddlePreScale); + + Graphics graphics = camelImage.getGraphics(); + + graphics.drawImage( + ImageUtil.crop( + scaledSaddleImage, + 0, (int) (64 * scale), + (int) (128 * scale), (int) (64 * scale) + ), + 0, (int) (64 * scale), null + ); + + graphics.drawImage( + ImageUtil.crop( + scaledSaddleImage, + (int) (84 * scale), (int) (51 * scale), + (int) (44 * scale), (int) (13 * scale) + ), + (int) (84 * scale), (int) (51 * scale), null + ); + + context.offer(bedrockKey, camelImage, "png"); + } +} diff --git a/converter/src/main/resources/mappings/textures.json b/converter/src/main/resources/mappings/textures.json index d93dfa0..6d0a7f5 100644 --- a/converter/src/main/resources/mappings/textures.json +++ b/converter/src/main/resources/mappings/textures.json @@ -967,6 +967,7 @@ "boat/mangrove": "boat/mangrove_boat", "boat/cherry": "boat/cherry_boat", "boat/pale_oak": "boat/pale_oak_boat", + "camel/camel_husk": "camel_husk/camel_husk", "cat/all_black": "cat/allblackcat", "cat/black": ["cat/blackcat", "cat/tuxedo"], "cat/british_shorthair": "cat/britishshorthair", @@ -1086,6 +1087,7 @@ "signs/hanging/spruce": "spruce_hanging_sign", "signs/hanging/warped": "warped_hanging_sign", "skeleton/bogged_overlay": "skeleton/bogged_clothes", + "skeleton/parched": "parched/parched", "skeleton/skeleton": ["skeleton/skeleton", "skulls/skeleton"], "skeleton/wither_skeleton": ["skeleton/wither_skeleton", "skulls/wither_skeleton"], "strider/strider_cold": "strider/strider_suffocated", @@ -1181,7 +1183,13 @@ "equipment/horse_body/copper": "horse2/armor/horse_armor_copper", "equipment/horse_body/iron": "horse2/armor/horse_armor_iron", "equipment/horse_body/gold": "horse2/armor/horse_armor_gold", - "equipment/horse_body/diamond": "horse2/armor/horse_armor_diamond" + "equipment/horse_body/diamond": "horse2/armor/horse_armor_diamond", + + "equipment/nautilus_body/copper": "nautilus/armor/nautilus_armor_copper", + "equipment/nautilus_body/iron": "nautilus/armor/nautilus_armor_iron", + "equipment/nautilus_body/gold": "nautilus/armor/nautilus_armor_gold", + "equipment/nautilus_body/diamond": "nautilus/armor/nautilus_armor_diamond", + "equipment/nautilus_body/netherite": "nautilus/armor/nautilus_armor_netherite" }, "environment": { "clouds": "clouds", @@ -1720,6 +1728,7 @@ "bogged_spawn_egg": "spawn_eggs/spawn_egg_bogged", "breeze_spawn_egg": "spawn_eggs/spawn_egg_breeze", "camel_spawn_egg": "spawn_eggs/spawn_egg_camel", + "camel_husk_spawn_egg": "spawn_eggs/spawn_egg_camel_husk", "cat_spawn_egg": "spawn_eggs/spawn_egg_cat", "cave_spider_spawn_egg": "spawn_eggs/spawn_egg_cave_spider", "chicken_spawn_egg": "spawn_eggs/spawn_egg_chicken", @@ -1751,8 +1760,10 @@ "magma_cube_spawn_egg": "spawn_eggs/spawn_egg_magma_cube", "mooshroom_spawn_egg": "spawn_eggs/spawn_egg_mooshroom", "mule_spawn_egg": "spawn_eggs/spawn_egg_mule", + "nautilus_spawn_egg": "spawn_eggs/spawn_egg_nautilus", "ocelot_spawn_egg": "spawn_eggs/spawn_egg_ocelot", "panda_spawn_egg": "spawn_eggs/spawn_egg_panda", + "parched_spawn_egg": "spawn_eggs/spawn_egg_parched", "parrot_spawn_egg": "spawn_eggs/spawn_egg_parrot", "phantom_spawn_egg": "spawn_eggs/spawn_egg_phantom", "pig_spawn_egg": "spawn_eggs/spawn_egg_pig", @@ -1792,6 +1803,7 @@ "zoglin_spawn_egg": "spawn_eggs/spawn_egg_zoglin", "zombie_spawn_egg": "spawn_eggs/spawn_egg_zombie", "zombie_horse_spawn_egg": "spawn_eggs/spawn_egg_zombie_horse", + "zombie_nautilus_spawn_egg": "spawn_eggs/spawn_egg_zombie_nautilus", "zombie_villager_spawn_egg": "spawn_eggs/spawn_egg_zombie_villager", "zombified_piglin_spawn_egg": "spawn_eggs/spawn_egg_zombified_piglin" }, @@ -1993,5 +2005,13 @@ "entity/decorated_pot/sheaf_pottery_pattern": "blocks/sheaf_pottery_pattern", "entity/decorated_pot/shelter_pottery_pattern": "blocks/shelter_pottery_pattern", "entity/decorated_pot/skull_pottery_pattern": "blocks/skull_pottery_pattern", - "entity/decorated_pot/snort_pottery_pattern": "blocks/snort_pottery_pattern" + "entity/decorated_pot/snort_pottery_pattern": "blocks/snort_pottery_pattern", + + "item/wooden_spear_in_hand": "entity/spear/wood_spear", + "item/stone_spear_in_hand": "entity/spear/stone_spear", + "item/copper_spear_in_hand": "entity/spear/copper_spear", + "item/iron_spear_in_hand": "entity/spear/iron_spear", + "item/golden_spear_in_hand": "entity/spear/gold_spear", + "item/diamond_spear_in_hand": "entity/spear/diamond_spear", + "item/netherite_spear_in_hand": "entity/spear/netherite_spear" } \ No newline at end of file