mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-29 20:09:13 +00:00
优化模型值自动分配
This commit is contained in:
@@ -193,6 +193,7 @@ warning.config.item.invalid_custom_model_data: "<yellow>Issue found in file <arg
|
|||||||
warning.config.item.bad_custom_model_data: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a custom model data '<arg:2>' that is too large. It's recommended to use a value lower than 16,777,216.</yellow>"
|
warning.config.item.bad_custom_model_data: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a custom model data '<arg:2>' that is too large. It's recommended to use a value lower than 16,777,216.</yellow>"
|
||||||
warning.config.item.item_model.conflict: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using an invalid 'item-model' option because this item model has been occupied by a vanilla item.</yellow>"
|
warning.config.item.item_model.conflict: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using an invalid 'item-model' option because this item model has been occupied by a vanilla item.</yellow>"
|
||||||
warning.config.item.custom_model_data_conflict: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a custom model data '<arg:2>' that has been occupied by item '<arg:3>'.</yellow>"
|
warning.config.item.custom_model_data_conflict: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a custom model data '<arg:2>' that has been occupied by item '<arg:3>'.</yellow>"
|
||||||
|
warning.config.item.custom_model_data_exhausted: "<yellow>Issue found in file <arg:0> - Cannot allocate custom model data for item '<arg:1>' as the custom model data has already been exhausted.</yellow>"
|
||||||
warning.config.item.invalid_component: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a non-existing component type '<arg:2>'.</yellow>"
|
warning.config.item.invalid_component: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a non-existing component type '<arg:2>'.</yellow>"
|
||||||
warning.config.item.missing_model_id: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is missing the required 'custom-model-data' or 'item-model' argument.</yellow>"
|
warning.config.item.missing_model_id: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is missing the required 'custom-model-data' or 'item-model' argument.</yellow>"
|
||||||
warning.config.item.missing_model: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is missing the required 'model' section for 1.21.4+ resource pack support.</yellow>"
|
warning.config.item.missing_model: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is missing the required 'model' section for 1.21.4+ resource pack support.</yellow>"
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
protected final Map<Key, CustomItem<I>> customItemsById = new HashMap<>();
|
protected final Map<Key, CustomItem<I>> customItemsById = new HashMap<>();
|
||||||
protected final Map<String, CustomItem<I>> customItemsByPath = new HashMap<>();
|
protected final Map<String, CustomItem<I>> customItemsByPath = new HashMap<>();
|
||||||
protected final Map<Key, List<UniqueKey>> customItemTags = new HashMap<>();
|
protected final Map<Key, List<UniqueKey>> customItemTags = new HashMap<>();
|
||||||
protected final Map<Key, Map<Integer, Key>> cmdConflictChecker = new HashMap<>();
|
|
||||||
protected final Map<Key, ModernItemModel> modernItemModels1_21_4 = new HashMap<>();
|
protected final Map<Key, ModernItemModel> modernItemModels1_21_4 = new HashMap<>();
|
||||||
protected final Map<Key, TreeSet<LegacyOverridesModel>> modernItemModels1_21_2 = new HashMap<>();
|
protected final Map<Key, TreeSet<LegacyOverridesModel>> modernItemModels1_21_2 = new HashMap<>();
|
||||||
protected final Map<Key, TreeSet<LegacyOverridesModel>> legacyOverrides = new HashMap<>();
|
protected final Map<Key, TreeSet<LegacyOverridesModel>> legacyOverrides = new HashMap<>();
|
||||||
@@ -128,7 +127,6 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
this.modernOverrides.clear();
|
this.modernOverrides.clear();
|
||||||
this.customItemTags.clear();
|
this.customItemTags.clear();
|
||||||
this.equipments.clear();
|
this.equipments.clear();
|
||||||
this.cmdConflictChecker.clear();
|
|
||||||
this.modernItemModels1_21_4.clear();
|
this.modernItemModels1_21_4.clear();
|
||||||
this.modernItemModels1_21_2.clear();
|
this.modernItemModels1_21_2.clear();
|
||||||
}
|
}
|
||||||
@@ -331,7 +329,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean needsItemModelCompatibility() {
|
private boolean needsItemModelCompatibility() {
|
||||||
return Config.packMaxVersion().isAbove(MinecraftVersions.V1_21_2);
|
return Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Key, IdAllocator> idAllocators() {
|
public Map<Key, IdAllocator> idAllocators() {
|
||||||
@@ -425,11 +423,19 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
customModelDataFuture = CompletableFuture.completedFuture(0);
|
customModelDataFuture = CompletableFuture.completedFuture(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 是否使用客户端侧模型
|
|
||||||
boolean clientBoundModel = VersionHelper.PREMIUM && (section.containsKey("client-bound-model") ? ResourceConfigUtils.getAsBoolean(section.get("client-bound-model"), "client-bound-model") : Config.globalClientboundModel());
|
|
||||||
|
|
||||||
// 当模型值完成分配的时候
|
// 当模型值完成分配的时候
|
||||||
customModelDataFuture.thenAccept(customModelData -> ResourceConfigUtils.runCatching(path, node, () -> {
|
customModelDataFuture.whenComplete((customModelData, throwable) -> ResourceConfigUtils.runCatching(path, node, () -> {
|
||||||
|
|
||||||
|
if (throwable != null) {
|
||||||
|
// 检测custom model data 冲突
|
||||||
|
if (throwable instanceof IdAllocator.IdConflictException exception) {
|
||||||
|
throw new LocalizedResourceConfigException("warning.config.item.custom_model_data_conflict", String.valueOf(exception.id()), exception.previousOwner());
|
||||||
|
}
|
||||||
|
// custom model data 已被用尽,不太可能
|
||||||
|
else if (throwable instanceof IdAllocator.IdExhaustedException) {
|
||||||
|
throw new LocalizedResourceConfigException("warning.config.item.custom_model_data_exhausted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// item model
|
// item model
|
||||||
Key itemModel = null;
|
Key itemModel = null;
|
||||||
@@ -447,6 +453,9 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
// 用户没设置item model但是有custom model data,那么就使用custom model data
|
// 用户没设置item model但是有custom model data,那么就使用custom model data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 是否使用客户端侧模型
|
||||||
|
boolean clientBoundModel = VersionHelper.PREMIUM && (section.containsKey("client-bound-model") ? ResourceConfigUtils.getAsBoolean(section.get("client-bound-model"), "client-bound-model") : Config.globalClientboundModel());
|
||||||
|
|
||||||
CustomItem.Builder<I> itemBuilder = createPlatformItemBuilder(uniqueId, material, clientBoundMaterial);
|
CustomItem.Builder<I> itemBuilder = createPlatformItemBuilder(uniqueId, material, clientBoundMaterial);
|
||||||
if (customModelData > 0) {
|
if (customModelData > 0) {
|
||||||
if (clientBoundModel) itemBuilder.clientBoundDataModifier(new CustomModelDataModifier<>(customModelData));
|
if (clientBoundModel) itemBuilder.clientBoundDataModifier(new CustomModelDataModifier<>(customModelData));
|
||||||
@@ -553,6 +562,11 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
* ========================
|
* ========================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// 原版物品还改模型?自己替换json去
|
||||||
|
if (isVanillaItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 模型配置区域,如果这里被配置了,那么用户必须要配置custom-model-data或item-model
|
// 模型配置区域,如果这里被配置了,那么用户必须要配置custom-model-data或item-model
|
||||||
Map<String, Object> modelSection = MiscUtils.castToMap(section.get("model"), true);
|
Map<String, Object> modelSection = MiscUtils.castToMap(section.get("model"), true);
|
||||||
Map<String, Object> legacyModelSection = MiscUtils.castToMap(section.get("legacy-model"), true);
|
Map<String, Object> legacyModelSection = MiscUtils.castToMap(section.get("legacy-model"), true);
|
||||||
@@ -561,9 +575,8 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needsModelSection = isModernFormatRequired() || (needsLegacyCompatibility() && legacyModelSection == null);
|
|
||||||
// 只对自定义物品有这个限制,既没有模型值也没有item-model
|
// 只对自定义物品有这个限制,既没有模型值也没有item-model
|
||||||
if (!isVanillaItem && customModelData == 0 && itemModel == null) {
|
if (customModelData == 0 && itemModel == null) {
|
||||||
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model_id"));
|
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,7 +585,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
// 旧版格式
|
// 旧版格式
|
||||||
TreeSet<LegacyOverridesModel> legacyOverridesModels = null;
|
TreeSet<LegacyOverridesModel> legacyOverridesModels = null;
|
||||||
// 如果需要支持新版item model 或者用户需要旧版本兼容,但是没配置legacy-model
|
// 如果需要支持新版item model 或者用户需要旧版本兼容,但是没配置legacy-model
|
||||||
if (needsModelSection) {
|
if (isModernFormatRequired() || (needsLegacyCompatibility() && legacyModelSection == null)) {
|
||||||
// 1.21.4+必须要配置model区域,如果不需要高版本兼容,则可以只写legacy-model
|
// 1.21.4+必须要配置model区域,如果不需要高版本兼容,则可以只写legacy-model
|
||||||
if (modelSection == null) {
|
if (modelSection == null) {
|
||||||
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model"));
|
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model"));
|
||||||
@@ -603,66 +616,52 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
legacyOverridesModels = new TreeSet<>();
|
legacyOverridesModels = new TreeSet<>();
|
||||||
processModelRecursively(modernModel, new LinkedHashMap<>(), legacyOverridesModels, clientBoundMaterial, customModelData);
|
processModelRecursively(modernModel, new LinkedHashMap<>(), legacyOverridesModels, clientBoundMaterial, customModelData);
|
||||||
if (legacyOverridesModels.isEmpty()) {
|
if (legacyOverridesModels.isEmpty()) {
|
||||||
collector.add(new LocalizedResourceConfigException("warning.config.item.legacy_model.cannot_convert", path.toString(), id.asString()));
|
collector.add(new LocalizedResourceConfigException("warning.config.item.legacy_model.cannot_convert"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自定义物品的model处理
|
boolean hasLegacyModel = legacyOverridesModels != null && !legacyOverridesModels.isEmpty();
|
||||||
if (!isVanillaItem) {
|
boolean hasModernModel = modernModel != null;
|
||||||
// 这个item-model是否存在,且是原版item-model
|
|
||||||
boolean isVanillaItemModel = itemModel != null && AbstractPackManager.PRESET_ITEMS.containsKey(itemModel);
|
|
||||||
// 使用了自定义模型值
|
|
||||||
if (customModelData != 0) {
|
|
||||||
// 如果用户主动设置了item-model且为原版物品,则使用item-model为基础模型,否则使用其视觉材质对应的item-model
|
|
||||||
Key finalBaseModel = isVanillaItemModel ? itemModel : clientBoundMaterial;
|
|
||||||
// 检查cmd冲突
|
|
||||||
Map<Integer, Key> conflict = AbstractItemManager.this.cmdConflictChecker.computeIfAbsent(finalBaseModel, k -> new HashMap<>());
|
|
||||||
if (conflict.containsKey(customModelData)) {
|
|
||||||
collector.addAndThrow(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) {
|
|
||||||
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.item_model.conflict", itemModel.asString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用了item-model组件,且不是原版物品的
|
// 自定义物品的model处理
|
||||||
if (itemModel != null && !isVanillaItemModel) {
|
// 这个item-model是否存在,且是原版item-model
|
||||||
if (isModernFormatRequired() && modernModel != null) {
|
boolean isVanillaItemModel = itemModel != null && AbstractPackManager.PRESET_ITEMS.containsKey(itemModel);
|
||||||
AbstractItemManager.this.modernItemModels1_21_4.put(itemModel, new ModernItemModel(
|
// 使用了自定义模型值
|
||||||
modernModel,
|
if (customModelData != 0) {
|
||||||
ResourceConfigUtils.getAsBoolean(section.getOrDefault("oversized-in-gui", true), "oversized-in-gui"),
|
// 如果用户主动设置了item-model且为原版物品,则使用item-model为基础模型,否则使用其视觉材质对应的item-model
|
||||||
ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap")
|
Key finalBaseModel = isVanillaItemModel ? itemModel : clientBoundMaterial;
|
||||||
));
|
// 添加新版item model
|
||||||
}
|
if (isModernFormatRequired() && hasModernModel) {
|
||||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && needsLegacyCompatibility() && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) {
|
TreeMap<Integer, ModernItemModel> map = AbstractItemManager.this.modernOverrides.computeIfAbsent(finalBaseModel, k -> new TreeMap<>());
|
||||||
TreeSet<LegacyOverridesModel> lom = AbstractItemManager.this.modernItemModels1_21_2.computeIfAbsent(itemModel, k -> new TreeSet<>());
|
map.put(customModelData, new ModernItemModel(
|
||||||
lom.addAll(legacyOverridesModels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 原版物品的item model覆写
|
|
||||||
if (isModernFormatRequired()) {
|
|
||||||
AbstractItemManager.this.modernItemModels1_21_4.put(id, new ModernItemModel(
|
|
||||||
modernModel,
|
modernModel,
|
||||||
ResourceConfigUtils.getAsBoolean(section.getOrDefault("oversized-in-gui", true), "oversized-in-gui"),
|
ResourceConfigUtils.getAsBoolean(section.getOrDefault("oversized-in-gui", true), "oversized-in-gui"),
|
||||||
ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap")
|
ResourceConfigUtils.getAsBoolean(section.getOrDefault("hand-animation-on-swap", true), "hand-animation-on-swap")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
// 添加旧版 overrides
|
||||||
|
if (needsLegacyCompatibility() && hasLegacyModel) {
|
||||||
|
TreeSet<LegacyOverridesModel> lom = AbstractItemManager.this.legacyOverrides.computeIfAbsent(finalBaseModel, k -> new TreeSet<>());
|
||||||
|
lom.addAll(legacyOverridesModels);
|
||||||
|
}
|
||||||
|
} else if (isVanillaItemModel) {
|
||||||
|
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.item_model.conflict", itemModel.asString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用了item-model组件,且不是原版物品的
|
||||||
|
if (itemModel != null && !isVanillaItemModel) {
|
||||||
|
if (isModernFormatRequired() && hasModernModel) {
|
||||||
|
AbstractItemManager.this.modernItemModels1_21_4.put(itemModel, 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 (needsItemModelCompatibility() && needsLegacyCompatibility() && hasLegacyModel) {
|
||||||
|
TreeSet<LegacyOverridesModel> lom = AbstractItemManager.this.modernItemModels1_21_2.computeIfAbsent(itemModel, k -> new TreeSet<>());
|
||||||
|
lom.addAll(legacyOverridesModels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 抛出异常
|
// 抛出异常
|
||||||
|
|||||||
@@ -223,20 +223,46 @@ public class IdAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class IdConflictException extends RuntimeException {
|
public static class IdConflictException extends RuntimeException {
|
||||||
|
private final String previousOwner;
|
||||||
|
private final int id;
|
||||||
|
|
||||||
public IdConflictException(String previousOwner, int id) {
|
public IdConflictException(String previousOwner, int id) {
|
||||||
super("ID " + id + " is already occupied by: " + previousOwner);
|
super("ID " + id + " is already occupied by: " + previousOwner);
|
||||||
|
this.previousOwner = previousOwner;
|
||||||
|
this.id = id;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class IdOutOfRangeException extends RuntimeException {
|
public String previousOwner() {
|
||||||
public IdOutOfRangeException(String name, int id, int min, int max) {
|
return previousOwner;
|
||||||
super("ID " + id + " for '" + name + "' is out of range. Valid range: " + min + "-" + max);
|
}
|
||||||
|
|
||||||
|
public int id() {
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IdExhaustedException extends RuntimeException {
|
public static class IdExhaustedException extends RuntimeException {
|
||||||
|
private final String name;
|
||||||
|
private final int min;
|
||||||
|
private final int max;
|
||||||
|
|
||||||
public IdExhaustedException(String name, int min, int max) {
|
public IdExhaustedException(String name, int min, int max) {
|
||||||
super("No available auto ID for '" + name + "'. All IDs in range " + min + "-" + max + " are occupied.");
|
super("No available auto ID for '" + name + "'. All IDs in range " + min + "-" + max + " are occupied.");
|
||||||
|
this.name = name;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int min() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int max() {
|
||||||
|
return max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user