diff --git a/libs/geyserutils-geyser-1.0-SNAPSHOT.jar b/libs/geyserutils-geyser-1.0-SNAPSHOT.jar index e5aeb05..6981883 100644 Binary files a/libs/geyserutils-geyser-1.0-SNAPSHOT.jar and b/libs/geyserutils-geyser-1.0-SNAPSHOT.jar differ diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/ExtensionMain.java b/src/main/java/re/imc/geysermodelenginepackgenerator/ExtensionMain.java index c8c8a6a..19c02d6 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/ExtensionMain.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/ExtensionMain.java @@ -6,6 +6,7 @@ import org.geysermc.geyser.api.event.lifecycle.GeyserLoadResourcePacksEvent; import org.geysermc.geyser.api.event.lifecycle.GeyserPreInitializeEvent; import org.geysermc.geyser.api.extension.Extension; import re.imc.geysermodelenginepackgenerator.generator.Entity; +import re.imc.geysermodelenginepackgenerator.generator.Geometry; import re.imc.geysermodelenginepackgenerator.util.ZipUtil; import java.io.File; @@ -35,7 +36,7 @@ public class ExtensionMain implements Extension { try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(generatedPackZip))) { // 压缩文件夹 - ZipUtil.compressFolder(generatedPack, generatedPack.getName(), zipOutputStream); + ZipUtil.compressFolder(generatedPack, null, zipOutputStream); } catch (IOException e) { e.printStackTrace(); @@ -44,6 +45,18 @@ public class ExtensionMain implements Extension { for (String entity : GeneratorMain.entityMap.keySet()) { String id = "modelengine:" + entity; GeyserUtils.addCustomEntity(id); + + Geometry geometry = GeneratorMain.geometryMap.get(entity); + geometry.getBones().forEach(bone -> { + GeyserUtils.addProperty(id, entity + ":" + bone, Boolean.class); + }); + + GeyserUtils.addProperty(id, "modelengine:anim_idle", Boolean.class); + GeyserUtils.addProperty(id, "modelengine:anim_spawn", Boolean.class); + GeyserUtils.addProperty(id, "modelengine:anim_walk", Boolean.class); + GeyserUtils.addProperty(id, "modelengine:anim_stop", Boolean.class); + + GeyserUtils.registerProperties(id); } } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java b/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java index b2d4b98..9b3bc99 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/GeneratorMain.java @@ -102,6 +102,7 @@ public class GeneratorMain { File modelsFolder = new File(output, "models/entity"); File texturesFolder = new File(output, "textures/entity"); File animationControllersFolder = new File(output, "animation_controllers"); + File renderControllersFolder = new File(output, "render_controllers"); File manifestFile = new File(output, "manifest.json"); @@ -140,6 +141,7 @@ public class GeneratorMain { modelsFolder.mkdirs(); texturesFolder.mkdirs(); animationControllersFolder.mkdirs(); + renderControllersFolder.mkdirs(); for (Map.Entry entry : animationMap.entrySet()) { entry.getValue().modify(); @@ -190,14 +192,33 @@ public class GeneratorMain { } for (Map.Entry entry : entityMap.entrySet()) { - entry.getValue().modify(); - Path path = entityFolder.toPath().resolve(entry.getValue().getPath() + entry.getKey() + ".entity.json"); - path.toFile().getParentFile().mkdirs(); - if (path.toFile().exists()) { + Entity entity = entry.getValue(); + entity.getProperties().setProperty("render_controller", "controller.render." + entry.getKey()); + entity.modify(); + + Path entityPath = entityFolder.toPath().resolve(entity.getPath() + entry.getKey() + ".entity.json"); + entityPath.toFile().getParentFile().mkdirs(); + if (entityPath.toFile().exists()) { continue; } try { - Files.writeString(path, entry.getValue().getJson(), StandardCharsets.UTF_8); + Files.writeString(entityPath, entity.getJson(), StandardCharsets.UTF_8); + } catch (IOException e) { + e.printStackTrace(); + } + + // render controller part + + String id = entity.getModelId(); + if (!geometryMap.containsKey(id)) continue; + RenderController controller = new RenderController(id, geometryMap.get(id).getBones()); + + Path renderPath = new File(renderControllersFolder, "controller.render." + id + ".json").toPath(); + if (renderPath.toFile().exists()) { + continue; + } + try { + Files.writeString(renderPath, controller.generate(), StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/AnimationController.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/AnimationController.java index 3e43047..4117f29 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/AnimationController.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/AnimationController.java @@ -15,7 +15,7 @@ public class AnimationController { ], "transitions": [ { - "idle": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:stone')" + "idle": "query.property('modelengine:anim_idle')" } ] }, @@ -25,13 +25,13 @@ public class AnimationController { ], "transitions": [ { - "spawn": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:iron_block')" + "spawn": "query.property('modelengine:anim_spawn')" }, { - "walk": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:redstone')" + "walk": "query.property('modelengine:anim_walk')" }, { - "stop": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:air')" + "stop": "query.property('modelengine:anim_stop')" } ] }, @@ -41,26 +41,26 @@ public class AnimationController { ], "transitions": [ { - "spawn": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:iron_block')" + "spawn": "query.property('modelengine:anim_spawn')" }, { - "stop": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:air')" + "stop": "query.property('modelengine:anim_stop')" }, { - "idle": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:stone')" + "idle": "query.property('modelengine:anim_idle')" } ] }, "stop": { "transitions": [ { - "idle": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:stone')" + "idle": "query.property('modelengine:anim_idle')" }, { - "spawn": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:iron_block')" + "spawn": "query.property('modelengine:anim_spawn')" }, { - "walk": "q.is_item_name_any('slot.armor.head', 0, 'minecraft:redstone')" + "walk": "query.property('modelengine:anim_walk')" } ] } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java index a403066..72fc3bf 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Entity.java @@ -80,7 +80,7 @@ public class Entity { .replace("%look_at_target%", "animation." + modelId + ".look_at_target") .replace("%walk%", walk) .replace("%spawn%", spawn) - .replace("%material%", properties.getProperty("material", "entity_alphatest")) + .replace("%material%", properties.getProperty("material", "entity_alphatest_change_color")) .replace("%render_controller%", properties.getProperty("render_controller", "controller.render.default")); diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java index 927095a..aac919a 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/Geometry.java @@ -1,15 +1,15 @@ package re.imc.geysermodelenginepackgenerator.generator; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import com.google.gson.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import java.util.Locale; @Getter @Setter @@ -19,6 +19,7 @@ public class Geometry { String modelId; JsonObject json; + List bones = new ArrayList<>(); String path; public void load(String json) { @@ -40,15 +41,21 @@ public class Geometry { while (iterator.hasNext()) { JsonElement element = iterator.next(); if (element.isJsonObject()) { - String name = element.getAsJsonObject().get("name").getAsString(); + String name = element.getAsJsonObject().get("name").getAsString().toLowerCase(Locale.ROOT); + + element.getAsJsonObject().remove("name"); + element.getAsJsonObject().addProperty("name", name); + if (name.equals("hitbox") || + name.equals("mount") || name.startsWith("p_") || name.startsWith("b_") || name.startsWith("ob_")) { iterator.remove(); - } + } else bones.add(name); } } setId("geometry.modelengine_" + modelId); } + } diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java new file mode 100644 index 0000000..8e368f5 --- /dev/null +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/generator/RenderController.java @@ -0,0 +1,56 @@ +package re.imc.geysermodelenginepackgenerator.generator; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import java.util.List; + +public class RenderController { + + String modelId; + List bones; + + public RenderController(String modelId, List bones) { + this.modelId = modelId; + this.bones = bones; + } + + // look, I'm fine with your other code and stuff, but I ain't using templates for JSON lmao + public String generate() { + JsonObject root = new JsonObject(); + root.addProperty("format_version", "1.8.0"); + + JsonObject renderControllers = new JsonObject(); + root.add("render_controllers", renderControllers); + + JsonObject controller = new JsonObject(); + renderControllers.add("controller.render." + modelId, controller); + + controller.addProperty("geometry", "Geometry.default"); + + JsonArray materials = new JsonArray(); + JsonObject materialItem = new JsonObject(); + materialItem.addProperty("*", "Material.default"); + materials.add(materialItem); + controller.add("materials", materials); + + JsonArray textures = new JsonArray(); + textures.add("Texture.default"); + controller.add("textures", textures); + + JsonArray partVisibility = new JsonArray(); + JsonObject visibilityDefault = new JsonObject(); + visibilityDefault.addProperty("*", true); + partVisibility.add(visibilityDefault); + + for (String bone : bones) { + JsonObject visibilityItem = new JsonObject(); + visibilityItem.addProperty(bone, "query.property('" + modelId + ":" + bone + "')"); + partVisibility.add(visibilityItem); + } + controller.add("part_visibility", partVisibility); + + return root.toString(); + } + +} diff --git a/src/main/java/re/imc/geysermodelenginepackgenerator/util/ZipUtil.java b/src/main/java/re/imc/geysermodelenginepackgenerator/util/ZipUtil.java index d51d5c1..cfd4a21 100644 --- a/src/main/java/re/imc/geysermodelenginepackgenerator/util/ZipUtil.java +++ b/src/main/java/re/imc/geysermodelenginepackgenerator/util/ZipUtil.java @@ -13,8 +13,16 @@ public class ZipUtil { if (files != null) { for (File file : files) { if (file.isDirectory()) { + if (folderName == null) { + compressFolder(file, file.getName(), zipOutputStream); + continue; + }; compressFolder(file, folderName + "/" + file.getName(), zipOutputStream); } else { + if (folderName == null) { + addToZipFile(file.getName(), file, zipOutputStream); + continue; + }; addToZipFile(folderName + "/" + file.getName(), file, zipOutputStream); } }