From 3eb2560f4bed01c5bd2fbf966c25aa4f2f62e00a Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 14 Jul 2025 02:52:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=A6=86=E5=86=99=E5=8E=9F?= =?UTF-8?q?=E7=89=88=E7=89=A9=E5=93=81=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/translations/en.yml | 2 +- .../src/main/resources/translations/zh_cn.yml | 2 +- .../core/item/AbstractItemManager.java | 161 +++++++++--------- .../core/pack/AbstractPackManager.java | 16 +- gradle.properties | 2 +- 5 files changed, 90 insertions(+), 93 deletions(-) diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 71e4ff2ca..56a24d8f5 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -177,6 +177,7 @@ warning.config.item.missing_material: "Issue found in file - The warning.config.item.invalid_material: "Issue found in file - The item '' is using an invalid material type ''." warning.config.item.invalid_custom_model_data: "Issue found in file - The item '' is using a negative custom model data '' which is invalid." warning.config.item.bad_custom_model_data: "Issue found in file - The item '' is using a custom model data '' that is too large. It's recommended to use a value lower than 16,777,216." +warning.config.item.item_model.conflict: "Issue found in file - The item '' is using an invalid 'item-model' option because this item model has been occupied by a vanilla item." warning.config.item.custom_model_data_conflict: "Issue found in file - The item '' is using a custom model data '' that has been occupied by item ''." warning.config.item.invalid_component: "Issue found in file - The item '' is using a non-existing component type ''." warning.config.item.missing_model_id: "Issue found in file - The item '' is missing the required 'custom-model-data' or 'item-model' argument." @@ -395,7 +396,6 @@ warning.config.function.remove_cooldown.missing_id: "Issue found in file warning.config.selector.missing_type: "Issue found in file - The config '' is missing the required 'type' argument for selector." warning.config.selector.invalid_type: "Issue found in file - The config '' is using an invalid selector type ''." warning.config.selector.invalid_target: "Issue found in file - The config '' is using an invalid selector target ''." -warning.config.resource_pack.item_model.conflict.vanilla: "Failed to generate item model for '' because this item model has been occupied by a vanilla item." warning.config.resource_pack.item_model.already_exist: "Failed to generate item model for '' because the file '' already exists." warning.config.resource_pack.model.generation.already_exist: "Failed to generate model because the model file '' already exists." warning.config.resource_pack.generation.missing_font_texture: "Font '' is missing required texture: ''" diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 94f47cae9..11b6758f2 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -177,6 +177,7 @@ warning.config.item.invalid_custom_model_data: "在文件 发现 warning.config.item.bad_custom_model_data: "在文件 发现问题 - 物品 '' 使用的自定义模型数据 '' 数值过大 建议使用小于 16,777,216 的值" warning.config.item.custom_model_data_conflict: "在文件 发现问题 - 物品 '' 使用的自定义模型数据 '' 已被物品 '' 占用" warning.config.item.invalid_component: "在文件 发现问题 - 物品 '' 使用了未知的数据组件 ''" +warning.config.item.item_model.conflict: "在文件 发现问题 - 物品 '' 使用了无效的 'item-model' 选项. 这个 item-model 已经存在对应的原版物品." warning.config.item.missing_model_id: "在文件 发现问题 - 物品 '' 缺少必需的 'custom-model-data' 或 'item-model' 参数" warning.config.item.missing_model: "在文件 中发现问题 - 物品 '' 缺少支持 1.21.4+ 资源包必需的 'model' 配置项" warning.config.item.behavior.missing_type: "在文件 发现问题 - 物品 '' 的行为配置缺少必需的 'type' 参数" @@ -393,7 +394,6 @@ warning.config.function.remove_cooldown.missing_id: "在文件 warning.config.selector.missing_type: "在文件 中发现问题 - 配置项 '' 缺少选择器必需的 'type' 参数" warning.config.selector.invalid_type: "在文件 中发现问题 - 配置项 '' 使用了无效的选择器类型 ''" warning.config.selector.invalid_target: "在文件 中发现问题 - 配置项 '' 使用了无效的选择器目标 ''" -warning.config.resource_pack.item_model.conflict.vanilla: "无法为 '' 生成物品模型,因为该物品模型已被原版物品占用" warning.config.resource_pack.item_model.already_exist: "无法为 '' 生成物品模型,因为文件 '' 已存在" warning.config.resource_pack.model.generation.already_exist: "无法生成模型,因为模型文件 '' 已存在" warning.config.resource_pack.generation.missing_font_texture: "字体''缺少必要纹理: ''" diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java index 9d277e9fd..ae246230c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java @@ -327,12 +327,12 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl } UniqueKey uniqueId = UniqueKey.create(id); - - // register for recipes + // 判断是不是原版物品 boolean isVanillaItem = isVanillaItem(id); Key material = Key.from(isVanillaItem ? id.value() : ResourceConfigUtils.requireNonEmptyStringOrThrow(section.get("material"), "warning.config.item.missing_material").toLowerCase(Locale.ENGLISH)); Key clientBoundMaterial = section.containsKey("client-bound-material") ? Key.from(section.get("client-bound-material").toString().toLowerCase(Locale.ENGLISH)) : material; - int customModelData = ResourceConfigUtils.getAsInt(section.getOrDefault("custom-model-data", 0), "custom-model-data"); + // 如果是原版物品,那么custom-model-data只能是0,即使用户设置了其他值 + int customModelData = isVanillaItem ? 0 : ResourceConfigUtils.getAsInt(section.getOrDefault("custom-model-data", 0), "custom-model-data"); boolean clientBoundModel = section.containsKey("client-bound-model") ? ResourceConfigUtils.getAsBoolean(section.get("client-bound-data"), "client-bound-data") : Config.globalClientboundModel(); if (customModelData < 0) { throw new LocalizedResourceConfigException("warning.config.item.invalid_custom_model_data", String.valueOf(customModelData)); @@ -341,53 +341,46 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl throw new LocalizedResourceConfigException("warning.config.item.bad_custom_model_data", String.valueOf(customModelData)); } + // item-model值 Key itemModelKey = null; CustomItem.Builder itemBuilder = createPlatformItemBuilder(uniqueId, material, clientBoundMaterial); boolean hasItemModelSection = section.containsKey("item-model"); - // To get at least one model provider - // Sets some basic model info + // 如果custom-model-data不为0 if (customModelData > 0) { - if (clientBoundModel) { - itemBuilder.clientBoundDataModifier(new CustomModelDataModifier<>(customModelData)); - } else { - itemBuilder.dataModifier(new CustomModelDataModifier<>(customModelData)); - } + if (clientBoundModel) itemBuilder.clientBoundDataModifier(new CustomModelDataModifier<>(customModelData)); + else itemBuilder.dataModifier(new CustomModelDataModifier<>(customModelData)); } - // Requires the item to have model before apply item-model + // 如果没有item-model选项被配置,同时这个物品又含有 model 区域 else if (!hasItemModelSection && section.containsKey("model") && VersionHelper.isOrAbove1_21_2()) { - // check server version here because components require 1.21.2+ - // customize or use the id + // 那么使用物品id当成item-model的值 itemModelKey = Key.from(section.getOrDefault("item-model", id.toString()).toString()); + // 但是有个前提,id必须是有效的resource location if (ResourceLocation.isValid(itemModelKey.toString())) { - if (clientBoundModel) { - itemBuilder.clientBoundDataModifier(new ItemModelModifier<>(itemModelKey)); - } else { - itemBuilder.dataModifier(new ItemModelModifier<>(itemModelKey)); - } + if (clientBoundModel) itemBuilder.clientBoundDataModifier(new ItemModelModifier<>(itemModelKey)); + else itemBuilder.dataModifier(new ItemModelModifier<>(itemModelKey)); } else { itemModelKey = null; } } + // 如果有item-model if (hasItemModelSection && VersionHelper.isOrAbove1_21_2()) { itemModelKey = Key.from(section.get("item-model").toString()); - if (clientBoundModel) { - itemBuilder.clientBoundDataModifier(new ItemModelModifier<>(itemModelKey)); - } else { - itemBuilder.dataModifier(new ItemModelModifier<>(itemModelKey)); - } + if (clientBoundModel) itemBuilder.clientBoundDataModifier(new ItemModelModifier<>(itemModelKey)); + else itemBuilder.dataModifier(new ItemModelModifier<>(itemModelKey)); } - // Get item data + // 应用物品数据 applyDataFunctions(MiscUtils.castToMap(section.get("data"), true), itemBuilder::dataModifier); applyDataFunctions(MiscUtils.castToMap(section.get("client-bound-data"), true), itemBuilder::clientBoundDataModifier); - // Add custom it here to make sure that id is always applied + // 如果不是原版物品,那么加入ce的标识符 if (!isVanillaItem) itemBuilder.dataModifier(new IdModifier<>(id)); + // 构建自定义物品 CustomItem customItem = itemBuilder .behaviors(ItemBehaviors.fromObj(pack, path, id, ResourceConfigUtils.get(section, "behavior", "behaviors"))) .settings(Optional.ofNullable(ResourceConfigUtils.get(section, "settings")) @@ -396,32 +389,32 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl .orElse(ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem))) .events(EventFunctions.parseEvents(ResourceConfigUtils.get(section, "events", "event"))) .build(); - + // 添加到缓存 addCustomItem(customItem); - // add it to category + // 如果有类别,则添加 if (section.containsKey("category")) { AbstractItemManager.this.plugin.itemBrowserManager().addExternalCategoryMember(id, MiscUtils.getAsStringList(section.get("category")).stream().map(Key::of).toList()); } - // 不处理原版物品的模型 - if (isVanillaItem) { - return; - } - - // model part, can be null - // but if it exists, either custom model data or item model should be configured + // 模型配置区域,如果这里被配置了,那么用户必须要配置custom-model-data或item-model Map modelSection = MiscUtils.castToMap(section.get("model"), true); Map legacyModelSection = MiscUtils.castToMap(section.get("legacy-model"), true); if (modelSection == null && legacyModelSection == null) { return; } - // 如果设置了model,但是没有模型值? - if (customModelData == 0 && itemModelKey == null) { - throw new LocalizedResourceConfigException("warning.config.item.missing_model_id"); + + boolean needsModelSection = isModernFormatRequired() || (needsLegacyCompatibility() && legacyModelSection == null); + // 只对自定义物品有这个限制 + if (!isVanillaItem) { + // 既没有模型值也没有item-model + if (customModelData == 0 && itemModelKey == null) { + throw new LocalizedResourceConfigException("warning.config.item.missing_model_id"); + } } - // 1.21.4+必须要配置model区域 - if (isModernFormatRequired() && modelSection == null) { + + // 1.21.4+必须要配置model区域,如果不需要高版本兼容,则可以只写legacy-model + if (needsModelSection && modelSection == null) { throw new LocalizedResourceConfigException("warning.config.item.missing_model"); } @@ -429,13 +422,14 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl ItemModel modernModel = null; // 旧版格式 TreeSet legacyOverridesModels = null; - - if (isModernFormatRequired() || (needsLegacyCompatibility() && legacyModelSection == null)) { + // 如果需要支持新版item model 或者用户需要旧版本兼容,但是没配置legacy-model + if (needsModelSection) { modernModel = ItemModels.fromMap(modelSection); for (ModelGeneration generation : modernModel.modelsToGenerate()) { prepareModelGeneration(generation); } } + // 如果需要旧版本兼容 if (needsLegacyCompatibility()) { if (legacyModelSection != null) { LegacyItemModel legacyItemModel = LegacyItemModel.fromMap(legacyModelSection, customModelData); @@ -452,48 +446,61 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl } } - boolean isVanillaItemModel = itemModelKey != null && AbstractPackManager.PRESET_ITEMS.containsKey(itemModelKey); - - // use custom model data - if (customModelData != 0) { - // use custom model data - // 其实这很奇怪,因为1.21.2以下并不支持item model,但是如果强行配置,那么不阻拦 - Key finalBaseModel = isVanillaItemModel ? itemModelKey : clientBoundMaterial; - Map conflict = AbstractItemManager.this.cmdConflictChecker.computeIfAbsent(finalBaseModel, k -> new HashMap<>()); - if (conflict.containsKey(customModelData)) { - throw new LocalizedResourceConfigException("warning.config.item.custom_model_data_conflict", String.valueOf(customModelData), conflict.get(customModelData).toString()); + // 自定义物品的model处理 + if (!isVanillaItem) { + // 这个item-model是否存在,且是原版item-model + boolean isVanillaItemModel = itemModelKey != null && AbstractPackManager.PRESET_ITEMS.containsKey(itemModelKey); + // 使用了自定义模型值 + if (customModelData != 0) { + // 如果用户主动设置了item-model且为原版物品,则使用item-model为基础模型,否则使用其视觉材质对应的item-model + Key finalBaseModel = isVanillaItemModel ? itemModelKey : clientBoundMaterial; + // 检查cmd冲突 + Map conflict = AbstractItemManager.this.cmdConflictChecker.computeIfAbsent(finalBaseModel, k -> new HashMap<>()); + if (conflict.containsKey(customModelData)) { + throw new LocalizedResourceConfigException("warning.config.item.custom_model_data_conflict", String.valueOf(customModelData), conflict.get(customModelData).toString()); + } + conflict.put(customModelData, id); + // 添加新版item model + if (isModernFormatRequired() && modernModel != null) { + TreeMap map = AbstractItemManager.this.modernOverrides.computeIfAbsent(finalBaseModel, k -> new TreeMap<>()); + map.put(customModelData, new ModernItemModel( + modernModel, + ResourceConfigUtils.getAsBoolean(section.getOrDefault("oversized-in-gui", true), "oversized-in-gui"), + ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap") + )); + } + // 添加旧版 overrides + if (needsLegacyCompatibility() && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) { + TreeSet lom = AbstractItemManager.this.legacyOverrides.computeIfAbsent(finalBaseModel, k -> new TreeSet<>()); + lom.addAll(legacyOverridesModels); + } + } else if (isVanillaItemModel) { + throw new LocalizedResourceConfigException("warning.config.item.item_model.conflict", itemModelKey.asString()); } - conflict.put(customModelData, id); - // Parse models - if (isModernFormatRequired() && modernModel != null) { - TreeMap map = AbstractItemManager.this.modernOverrides.computeIfAbsent(finalBaseModel, k -> new TreeMap<>()); - map.put(customModelData, new ModernItemModel( + + // 使用了item-model组件,且不是原版物品的 + if (itemModelKey != null && !isVanillaItemModel) { + if (isModernFormatRequired() && modernModel != null) { + AbstractItemManager.this.modernItemModels1_21_4.put(itemModelKey, new ModernItemModel( + modernModel, + ResourceConfigUtils.getAsBoolean(section.getOrDefault("oversized-in-gui", true), "oversized-in-gui"), + ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap") + )); + } + if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && needsLegacyCompatibility() && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) { + TreeSet lom = AbstractItemManager.this.modernItemModels1_21_2.computeIfAbsent(itemModelKey, k -> new TreeSet<>()); + lom.addAll(legacyOverridesModels); + } + } + } else { + // 原版物品的item model覆写 + if (isModernFormatRequired()) { + AbstractItemManager.this.modernItemModels1_21_4.put(id, new ModernItemModel( modernModel, ResourceConfigUtils.getAsBoolean(section.getOrDefault("oversized-in-gui", true), "oversized-in-gui"), ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap") )); } - if (needsLegacyCompatibility() && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) { - TreeSet lom = AbstractItemManager.this.legacyOverrides.computeIfAbsent(finalBaseModel, k -> new TreeSet<>()); - lom.addAll(legacyOverridesModels); - } - } else if (isVanillaItemModel) { - throw new IllegalArgumentException("You are not allowed to use vanilla 'item-model' without specifying a 'custom-model-data'."); - } - - // use item model, but not a vanilla model - if (itemModelKey != null && !isVanillaItemModel) { - if (isModernFormatRequired() && modernModel != null) { - AbstractItemManager.this.modernItemModels1_21_4.put(itemModelKey, new ModernItemModel( - modernModel, - ResourceConfigUtils.getAsBoolean(section.getOrDefault("oversized-in-gui", true), "oversized-in-gui"), - ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap") - )); - } - if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && needsLegacyCompatibility() && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) { - TreeSet lom = AbstractItemManager.this.modernItemModels1_21_2.computeIfAbsent(itemModelKey, k -> new TreeSet<>()); - lom.addAll(legacyOverridesModels); - } } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index ffebf8bff..855c47836 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -643,10 +643,11 @@ public abstract class AbstractPackManager implements PackManager { this.generateItemModels(generatedPackPath, this.plugin.itemManager()); this.generateItemModels(generatedPackPath, this.plugin.blockManager()); this.generateBlockOverrides(generatedPackPath); - this.generateLegacyItemOverrides(generatedPackPath); - this.generateModernItemOverrides(generatedPackPath, revisions::add); + // 一定要先生成item-model再生成overrides this.generateModernItemModels1_21_2(generatedPackPath); this.generateModernItemModels1_21_4(generatedPackPath, revisions::add); + this.generateLegacyItemOverrides(generatedPackPath); + this.generateModernItemOverrides(generatedPackPath, revisions::add); this.generateOverrideSounds(generatedPackPath); this.generateCustomSounds(generatedPackPath); this.generateClientLang(generatedPackPath); @@ -1769,12 +1770,6 @@ public abstract class AbstractPackManager implements PackManager { Key itemModelPath = entry.getKey(); TreeSet legacyOverridesModels = entry.getValue(); - // 检测item model合法性 - if (PRESET_MODERN_MODELS_ITEM.containsKey(itemModelPath) || PRESET_LEGACY_MODELS_ITEM.containsKey(itemModelPath)) { - TranslationManager.instance().log("warning.config.resource_pack.item_model.conflict.vanilla", itemModelPath.asString()); - continue; - } - // 要检查目标生成路径是否已经存在模型,如果存在模型,应该只为其生成overrides Path itemPath = generatedPackPath .resolve("assets") @@ -1836,11 +1831,6 @@ public abstract class AbstractPackManager implements PackManager { .resolve(key.namespace()) .resolve("items") .resolve(key.value() + ".json"); - - if (PRESET_ITEMS.containsKey(key)) { - TranslationManager.instance().log("warning.config.resource_pack.item_model.conflict.vanilla", key.asString()); - continue; - } if (Files.exists(itemPath)) { TranslationManager.instance().log("warning.config.resource_pack.item_model.already_exist", key.asString(), itemPath.toAbsolutePath().toString()); continue; diff --git a/gradle.properties b/gradle.properties index c49049022..fd689d2ad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.59.11 +project_version=0.0.60 config_version=41 lang_version=22 project_group=net.momirealms