From 20a5332921172c3a958874a3afdc56ff63d52389 Mon Sep 17 00:00:00 2001 From: linyuzhe Date: Sat, 2 Mar 2024 00:29:43 +0800 Subject: [PATCH] //Add Entity spawn egg support --- .../definition/ItemTextureDefinition.kt | 15 +++++ .../deserializer/BedrockResourceContext.kt | 10 +++ .../BedrockResourceDeserializer.kt | 9 ++- .../loader/BedrockResourcePackLoader.kt | 64 +++++++++++++++++++ 4 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/net/easecation/bedrockloader/bedrock/definition/ItemTextureDefinition.kt diff --git a/src/main/kotlin/net/easecation/bedrockloader/bedrock/definition/ItemTextureDefinition.kt b/src/main/kotlin/net/easecation/bedrockloader/bedrock/definition/ItemTextureDefinition.kt new file mode 100644 index 0000000..c0a25f2 --- /dev/null +++ b/src/main/kotlin/net/easecation/bedrockloader/bedrock/definition/ItemTextureDefinition.kt @@ -0,0 +1,15 @@ +package net.easecation.bedrockloader.bedrock.definition + +import net.easecation.bedrockloader.bedrock.BedrockTexturePath + +data class ItemTextureDefinition( + val resource_pack_name: String?, + val texture_name: String?, + val padding: Int?, + val num_mip_levels: Int?, + val texture_data: Map +) { + data class TextureData( + val textures: BedrockTexturePath + ) +} diff --git a/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceContext.kt b/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceContext.kt index 283c5d1..4ba1ef5 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceContext.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceContext.kt @@ -10,6 +10,7 @@ import net.minecraft.util.Identifier class BedrockResourceContext { val terrainTexture: MutableMap = mutableMapOf() + val itemTexture: MutableMap = mutableMapOf() val blocks: MutableMap = mutableMapOf() val entities: MutableMap = mutableMapOf() val geometries: MutableMap = mutableMapOf() @@ -23,6 +24,7 @@ class BedrockResourceContext { geometries.putAll(other.geometries) renderControllers.putAll(other.renderControllers) textureImages.putAll(other.textureImages) + itemTexture.putAll(other.itemTexture) } fun terrainTextureToJava(textureKey: String, namespace: String) : JavaTexturePath? { @@ -34,4 +36,12 @@ class BedrockResourceContext { return Identifier(namespace, texture.replace("textures/", "")) } + fun itemTextureToJava(textureKey: String, namespace: String) : JavaTexturePath? { + val texture = itemTexture[textureKey]?.textures + if (texture == null || !texture.contains("textures/")) { + BedrockLoader.logger.warn("[BedrockResourcePackLoader] Item texture not found: $textureKey") + return null + } + return Identifier(namespace, texture.replace("textures/", "")) + } } \ No newline at end of file diff --git a/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceDeserializer.kt b/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceDeserializer.kt index 4d060d3..aebc431 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceDeserializer.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/deserializer/BedrockResourceDeserializer.kt @@ -4,7 +4,6 @@ import net.easecation.bedrockloader.BedrockLoader import net.easecation.bedrockloader.bedrock.data.TextureImage import net.easecation.bedrockloader.bedrock.definition.* import net.easecation.bedrockloader.util.GsonUtil -import net.minecraft.util.Identifier import java.io.InputStreamReader import java.util.zip.ZipFile import javax.imageio.ImageIO @@ -20,6 +19,12 @@ object BedrockResourceDeserializer : PackDeserializer { context.terrainTexture.putAll(terrainTextureDefinition.texture_data) } } + zip.getEntry("textures/item_texture.json")?.let { entry -> + zip.getInputStream(entry).use { stream -> + val itemTextureDefinition = GsonUtil.GSON.fromJson(InputStreamReader(stream), ItemTextureDefinition::class.java) + context.itemTexture.putAll(itemTextureDefinition.texture_data) + } + } zip.getEntry("blocks.json")?.let { entry -> zip.getInputStream(entry).use { stream -> val blockResourceDefinition = GsonUtil.GSON.fromJson(InputStreamReader(stream), BlockResourceDefinition::class.java) @@ -31,7 +36,7 @@ object BedrockResourceDeserializer : PackDeserializer { val entry = entries.nextElement() val name = entry.name // texture - if (name.startsWith("textures/") && (name.endsWith(".png") || name.endsWith(".jpg"))) { + if (name.startsWith("textures/") && (name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".tga"))) { try { val ext = name.substring(name.lastIndexOf('.') + 1) val withoutExt = name.substring(0, name.lastIndexOf('.')) diff --git a/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt b/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt index 5be392f..4314c1b 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt @@ -16,11 +16,14 @@ import net.easecation.bedrockloader.render.BedrockGeometryModel import net.easecation.bedrockloader.util.GsonUtil import net.fabricmc.api.EnvType import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry +import net.fabricmc.fabric.api.item.v1.FabricItemSettings import net.fabricmc.loader.api.FabricLoader import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.util.SpriteIdentifier import net.minecraft.entity.EntityType +import net.minecraft.item.SpawnEggItem import net.minecraft.util.Identifier +import net.minecraft.util.registry.Registry import java.io.File import java.io.FileWriter import javax.imageio.ImageIO @@ -63,9 +66,15 @@ class BedrockResourcePackLoader( for (entity in context.resource.entities) { val identifier = entity.key val clientEntity = entity.value.description + val dir = namespaceDir(identifier.namespace) val entityType = BedrockAddonsRegistry.getOrRegisterEntityType(identifier) // textures createEntityTextures(identifier, clientEntity) + createSpawnEggItem( + dir.resolve("models/item/${identifier.path + "_spawn_egg"}.json"), + identifier, + clientEntity + ) // renderer if (env == EnvType.CLIENT) { registerRenderController(clientEntity, identifier, entityType) @@ -344,6 +353,61 @@ class BedrockResourcePackLoader( } } + /** + * 直接创建一个继承于对应实体的生物蛋物品 + */ + @OptIn(ExperimentalStdlibApi::class) + private fun createSpawnEggItem(file: File, identifier: Identifier, clientEntity: EntityResourceDefinition.ClientEntityDescription, primaryColor: Int = 0xffffff, secondaryColor: Int = 0xffffff) { + context.behavior.entities[identifier]?.description?.is_spawnable?.let { + val entityType = BedrockAddonsRegistry.getOrRegisterEntityType(identifier) + clientEntity.spawn_egg?.let { + val entityName = context.resource.entities[identifier]?.description?.identifier?.path + val id = Identifier(identifier.namespace, "${entityName}_spawn_egg") + val spawnEggItem: SpawnEggItem = if (it.base_color != null && it.overlay_color != null) { + SpawnEggItem(entityType, it.base_color.replace("#", "").hexToInt(HexFormat.Default), it.overlay_color.replace("#", "").hexToInt(HexFormat.Default), FabricItemSettings()) + } else if (it.base_color != null){ + SpawnEggItem(entityType, it.base_color.replace("#", "").hexToInt(HexFormat.Default), secondaryColor, FabricItemSettings()) + } else if (it.overlay_color != null) { + SpawnEggItem(entityType, primaryColor, it.overlay_color.replace("#", "").hexToInt(HexFormat.Default), FabricItemSettings()) + } else { + SpawnEggItem(entityType, primaryColor, secondaryColor, FabricItemSettings()) + } + val model: JavaModelDefinition + if (it.texture != null) { + model = JavaModelDefinition( + parent = Identifier("minecraft", "item/generated").toString(), + textures = context.resource.itemTextureToJava(it.texture, identifier.namespace)?.let { + mapOf("layer0" to it) + } + ) + val spawnEggTexture = it.texture + context.resource.itemTexture[spawnEggTexture]?.textures?.let { + val bedrockTexture = context.resource.textureImages[it] + if (bedrockTexture == null) { + BedrockLoader.logger.warn("[BedrockResourcePackLoader] Entity spawn egg texture not found: ${spawnEggTexture}") + return + } + val namespaceDir = this.namespaceDir(identifier.namespace) + val bedrockTextureFile = namespaceDir.resolve("textures/" + model.textures!!["layer0"]!!.path + "." + bedrockTexture.type.getExtension()) + bedrockTextureFile.parentFile.mkdirs() + bedrockTexture.image.let { image -> + ImageIO.write(image, bedrockTextureFile.extension, bedrockTextureFile) + } + } + } else { + model = JavaModelDefinition( + parent = Identifier("", "item/template_spawn_egg").toString() + ) + } + Registry.register(Registry.ITEM, id, spawnEggItem) + BedrockAddonsRegistry.items[id] = spawnEggItem + FileWriter(file).use { writer -> + GsonUtil.GSON.toJson(model, writer) + } + } + } + } + /** * 从ClientEntity读取需要的贴图,然后将对应的贴图文件保存到java材质包中(对应命名空间) */