mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 18:09:27 +00:00
支持覆写原版物品模型
This commit is contained in:
@@ -327,12 +327,12 @@ public abstract class AbstractItemManager<I> 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<I> extends AbstractModelGenerator impl
|
||||
throw new LocalizedResourceConfigException("warning.config.item.bad_custom_model_data", String.valueOf(customModelData));
|
||||
}
|
||||
|
||||
// item-model值
|
||||
Key itemModelKey = null;
|
||||
|
||||
CustomItem.Builder<I> 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<I> 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<I> 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<String, Object> modelSection = MiscUtils.castToMap(section.get("model"), true);
|
||||
Map<String, Object> 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<I> extends AbstractModelGenerator impl
|
||||
ItemModel modernModel = null;
|
||||
// 旧版格式
|
||||
TreeSet<LegacyOverridesModel> 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<I> 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<Integer, Key> 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<Integer, Key> 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<Integer, ModernItemModel> 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<LegacyOverridesModel> 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<Integer, ModernItemModel> 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<LegacyOverridesModel> 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<LegacyOverridesModel> 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<LegacyOverridesModel> lom = AbstractItemManager.this.modernItemModels1_21_2.computeIfAbsent(itemModelKey, k -> new TreeSet<>());
|
||||
lom.addAll(legacyOverridesModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<LegacyOverridesModel> 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;
|
||||
|
||||
Reference in New Issue
Block a user