diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java index 6c4d94cf2..aa98ccc73 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java @@ -7,7 +7,7 @@ import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.NetworkItemHandler; -import net.momirealms.craftengine.core.item.modifier.ArgumentModifier; +import net.momirealms.craftengine.core.item.modifier.ArgumentsModifier; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; @@ -74,7 +74,7 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler { @@ -129,7 +128,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory modifierList) { + CompoundTag compoundTag = (CompoundTag) item.getSparrowNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS).orElseGet(CompoundTag::new); + ListTag modifiers = new ListTag(); + compoundTag.put("modifiers", modifiers); + for (AttributeModifier modifier : modifierList) { + CompoundTag modifierTag = new CompoundTag(); + modifierTag.putString("type", modifier.type()); + modifierTag.putString("slot", modifier.slot().name().toLowerCase(Locale.ENGLISH)); + if (VersionHelper.isOrAbove1_21()) { + modifierTag.putString("id", modifier.id().toString()); + } else { + modifierTag.putIntArray("uuid", UUIDUtils.uuidToIntArray(UUID.nameUUIDFromBytes(modifier.id().toString().getBytes(StandardCharsets.UTF_8)))); + modifierTag.putString("name", modifier.id().toString()); + } + modifierTag.putDouble("amount", modifier.amount()); + modifierTag.putString("operation", modifier.operation().id()); + modifiers.add(modifierTag); + } + item.setNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS, compoundTag); + } } \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java index af0981b60..fff53ba54 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java @@ -5,15 +5,20 @@ import com.google.gson.JsonElement; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.item.ComponentTypes; +import net.momirealms.craftengine.core.attribute.AttributeModifier; +import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.data.JukeboxPlayable; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.GsonHelper; +import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.ListTag; import net.momirealms.sparrow.nbt.Tag; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Optional; public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { @@ -123,4 +128,29 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { protected void jukeboxSong(ComponentItemWrapper item, JukeboxPlayable data) { item.setJavaComponent(ComponentTypes.JUKEBOX_PLAYABLE, data.song()); } + + @Override + protected void attributeModifiers(ComponentItemWrapper item, List modifierList) { + ListTag modifiers = new ListTag(); + for (AttributeModifier modifier : modifierList) { + CompoundTag modifierTag = new CompoundTag(); + modifierTag.putString("type", modifier.type()); + modifierTag.putString("slot", modifier.slot().name().toLowerCase(Locale.ENGLISH)); + modifierTag.putString("id", modifier.id().toString()); + modifierTag.putDouble("amount", modifier.amount()); + modifierTag.putString("operation", modifier.operation().id()); + AttributeModifier.Display display = modifier.display(); + if (VersionHelper.isOrAbove1_21_6() && display != null) { + CompoundTag displayTag = new CompoundTag(); + AttributeModifier.Display.Type displayType = display.type(); + displayTag.putString("type", displayType.name().toLowerCase(Locale.ENGLISH)); + if (displayType == AttributeModifier.Display.Type.OVERRIDE) { + displayTag.put("value", AdventureHelper.componentToTag(display.value())); + } + modifierTag.put("display", displayTag); + } + modifiers.add(modifierTag); + } + item.setNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS, modifiers); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java index c8437d089..6d4c2456a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java @@ -5,6 +5,7 @@ import net.momirealms.craftengine.bukkit.item.LegacyItemWrapper; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries; import net.momirealms.craftengine.bukkit.util.KeyUtils; +import net.momirealms.craftengine.core.attribute.AttributeModifier; import net.momirealms.craftengine.core.item.data.Enchantment; import net.momirealms.craftengine.core.item.data.FireworkExplosion; import net.momirealms.craftengine.core.item.data.Trim; @@ -13,6 +14,9 @@ import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Color; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.SkullUtils; +import net.momirealms.craftengine.core.util.UUIDUtils; +import net.momirealms.sparrow.nbt.CompoundTag; +import net.momirealms.sparrow.nbt.ListTag; import net.momirealms.sparrow.nbt.Tag; import org.bukkit.NamespacedKey; import org.bukkit.Registry; @@ -344,4 +348,20 @@ public class UniversalItemFactory extends BukkitItemFactory { FastNMS.INSTANCE.method$ItemStack$setTag(newItemStack, FastNMS.INSTANCE.method$CompoundTag$copy(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item.getLiteralObject()))); return new LegacyItemWrapper(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(newItemStack)); } + + @Override + protected void attributeModifiers(LegacyItemWrapper item, List modifiers) { + ListTag listTag = new ListTag(); + for (AttributeModifier modifier : modifiers) { + CompoundTag modifierTag = new CompoundTag(); + modifierTag.putString("AttributeName", modifier.type()); + modifierTag.putString("Name", modifier.id().toString()); + modifierTag.putString("Slot", modifier.slot().name().toLowerCase(Locale.ENGLISH)); + modifierTag.putInt("Operation", modifier.operation().ordinal()); + modifierTag.putDouble("Amount", modifier.amount()); + modifierTag.putIntArray("UUID", UUIDUtils.uuidToIntArray(UUID.nameUUIDFromBytes(modifier.id().toString().getBytes(StandardCharsets.UTF_8)))); + listTag.add(modifierTag); + } + item.setTag(listTag, "AttributeModifiers"); + } } \ No newline at end of file diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 3f4624266..8f0f5a79a 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -72,6 +72,7 @@ warning.config.type.float: "Issue found in file - Failed to load warning.config.type.double: "Issue found in file - Failed to load '': Cannot cast '' to double type for option ''." warning.config.type.quaternionf: "Issue found in file - Failed to load '': Cannot cast '' to Quaternionf type for option ''." warning.config.type.vector3f: "Issue found in file - Failed to load '': Cannot cast '' to Vector3f type for option ''." +warning.config.type.map: "Issue found in file - Failed to load '': Cannot cast '' to Map type for option ''." warning.config.type.snbt.invalid_syntax: "Issue found in file - Failed to load '': Invalid snbt syntax ''." warning.config.number.missing_type: "Issue found in file - The config '' is missing the required 'type' argument for number argument." warning.config.number.invalid_type: "Issue found in file - The config '' is using an invalid number argument type ''." @@ -173,6 +174,9 @@ warning.config.item.data.attribute_modifiers.missing_amount: "Issue foun warning.config.item.data.attribute_modifiers.missing_operation: "Issue found in file - The item '' is missing the required 'operation' argument for 'attribute-modifiers' data." warning.config.item.data.attribute_modifiers.display.missing_type: "Issue found in file - The item '' is missing the required 'type' argument for 'attribute-modifiers' display data." warning.config.item.data.attribute_modifiers.display.missing_value: "Issue found in file - The item '' is missing the required 'value' argument for 'attribute-modifiers' display data." +warning.config.item.data.external.missing_source: "Issue found in file - The item '' is missing the required 'source' argument for 'external' data." +warning.config.item.data.external.missing_id: "Issue found in file - The item '' is missing the required 'id' argument for 'external' data." +warning.config.item.data.external.invalid_source: "Issue found in file - The item '' is using an invalid item source '' for 'external' data." warning.config.item.missing_material: "Issue found in file - The item '' is missing the required 'material' argument." 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." diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 2666687a4..77a18b454 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -72,6 +72,7 @@ warning.config.type.boolean: "在文件 发现问题 - 无法加 warning.config.type.double: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为双精度类型 (选项 '')" warning.config.type.quaternionf: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为四元数类型 (选项 '')" warning.config.type.vector3f: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为三维向量类型 (选项 '')" +warning.config.type.map: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为映射类型 (选项 '')" warning.config.type.snbt.invalid_syntax: "在文件 发现问题 - 无法加载 '': 无效的 SNBT 语法 ''." warning.config.number.missing_type: "在文件 发现问题 - 配置项 '' 缺少数字类型所需的 'type' 参数" warning.config.number.invalid_type: "在文件 发现问题 - 配置项 '' 使用了无效的数字类型 ''" diff --git a/core/src/main/java/net/momirealms/craftengine/core/attribute/AttributeModifier.java b/core/src/main/java/net/momirealms/craftengine/core/attribute/AttributeModifier.java index 0d5ff2dfb..1353e5769 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/attribute/AttributeModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/attribute/AttributeModifier.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.attribute; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.Nullable; @@ -72,7 +73,7 @@ public class AttributeModifier { } } - public record Display(AttributeModifier.Display.Type type, String value) { + public record Display(AttributeModifier.Display.Type type, Component value) { public enum Type { DEFAULT, HIDDEN, OVERRIDE diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java index 33170ded2..872aa411d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.attribute.AttributeModifier; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.data.Enchantment; import net.momirealms.craftengine.core.item.data.FireworkExplosion; @@ -253,6 +254,12 @@ public class AbstractItem, I> implements Item { return this.factory.loreComponent(this.item); } + @Override + public Item attributeModifiers(List modifiers) { + this.factory.attributeModifiers(this.item, modifiers); + return this; + } + @Override public Item unbreakable(boolean unbreakable) { this.factory.unbreakable(this.item, unbreakable); 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 2f5baff69..f8d415982 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 @@ -2,16 +2,10 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; -import net.momirealms.craftengine.core.attribute.AttributeModifier; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.behavior.ItemBehaviors; -import net.momirealms.craftengine.core.item.data.Enchantment; -import net.momirealms.craftengine.core.item.data.JukeboxPlayable; import net.momirealms.craftengine.core.item.equipment.*; import net.momirealms.craftengine.core.item.modifier.*; -import net.momirealms.craftengine.core.item.modifier.lore.DynamicLoreModifier; -import net.momirealms.craftengine.core.item.modifier.lore.LoreModifier; -import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.pack.AbstractPackManager; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; @@ -21,27 +15,22 @@ import net.momirealms.craftengine.core.pack.model.generation.AbstractModelGenera import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; import net.momirealms.craftengine.core.pack.model.select.ChargeTypeSelectProperty; import net.momirealms.craftengine.core.pack.model.select.TrimMaterialSelectProperty; -import net.momirealms.craftengine.core.pack.obfuscation.ResourcePackGenerationException; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; import net.momirealms.craftengine.core.plugin.context.event.EventFunctions; import net.momirealms.craftengine.core.plugin.context.event.EventTrigger; -import net.momirealms.craftengine.core.plugin.context.text.TextProvider; -import net.momirealms.craftengine.core.plugin.context.text.TextProviders; -import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.plugin.locale.TranslationManager; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.util.*; import org.incendo.cloud.suggestion.Suggestion; import org.incendo.cloud.type.Either; -import org.joml.Vector3f; import java.nio.file.Path; import java.util.*; import java.util.function.Consumer; -import java.util.function.Function; import java.util.stream.Stream; public abstract class AbstractItemManager extends AbstractModelGenerator implements ItemManager { @@ -52,7 +41,6 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl private final ItemParser itemParser; private final EquipmentParser equipmentParser; protected final Map> externalItemSources = new HashMap<>(); - protected final Map>> dataFunctions = new HashMap<>(); protected final Map> customItems = new HashMap<>(); protected final Map> customItemTags = new HashMap<>(); protected final Map> cmdConflictChecker = new HashMap<>(); @@ -69,14 +57,7 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl super(plugin); this.itemParser = new ItemParser(); this.equipmentParser = new EquipmentParser(); - this.registerFunctions(); - } - - @Override - public void registerDataType(Function> factory, String... alias) { - for (String a : alias) { - this.dataFunctions.put(a, factory); - } + ItemDataModifiers.init(); } protected static void registerVanillaItemExtraBehavior(ItemBehavior behavior, Key... items) { @@ -85,23 +66,23 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl } } - protected void applyDataFunctions(Map dataSection, Consumer> consumer) { + @SuppressWarnings("unchecked") + protected void applyDataModifiers(Map dataSection, Consumer> callback) { + ExceptionCollector errorCollector = new ExceptionCollector<>(); if (dataSection != null) { for (Map.Entry dataEntry : dataSection.entrySet()) { - Optional.ofNullable(this.dataFunctions.get(dataEntry.getKey())).ifPresent(function -> { + Object value = dataEntry.getValue(); + if (value == null) continue; + Optional.ofNullable(BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY.getValue(Key.withDefaultNamespace(dataEntry.getKey(), Key.DEFAULT_NAMESPACE))).ifPresent(factory -> { try { - consumer.accept(function.apply(dataEntry.getValue())); - } catch (IllegalArgumentException e) { - this.plugin.logger().warn("Invalid data format", e); + callback.accept((ItemDataModifier) factory.create(value)); + } catch (LocalizedResourceConfigException e) { + errorCollector.add(e); } }); } } - } - - @Override - public Function> getDataType(String key) { - return this.dataFunctions.get(key); + errorCollector.throwIfPresent(); } @Override @@ -338,8 +319,6 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl throw new LocalizedResourceConfigException("warning.config.item.duplicate"); } - ExceptionCollector collector = new ExceptionCollector<>(); - UniqueKey uniqueId = UniqueKey.create(id); // 判断是不是原版物品 boolean isVanillaItem = isVanillaItem(id); @@ -386,21 +365,26 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl else itemBuilder.dataModifier(new ItemModelModifier<>(itemModelKey)); } + // 对于不重要的配置,可以仅警告,不返回 + ExceptionCollector collector = new ExceptionCollector<>(); + // 应用物品数据 try { - applyDataFunctions(MiscUtils.castToMap(section.get("data"), true), itemBuilder::dataModifier); + applyDataModifiers(MiscUtils.castToMap(section.get("data"), true), itemBuilder::dataModifier); } catch (LocalizedResourceConfigException e) { collector.add(e); } - try { - applyDataFunctions(MiscUtils.castToMap(section.get("client-bound-data"), true), itemBuilder::clientBoundDataModifier); - } catch (LocalizedResourceConfigException e) { - collector.add(e); - } + try { + applyDataModifiers(MiscUtils.castToMap(section.get("client-bound-data"), true), itemBuilder::clientBoundDataModifier); + } catch (LocalizedResourceConfigException e) { + collector.add(e); + } + // 如果不是原版物品,那么加入ce的标识符 if (!isVanillaItem) itemBuilder.dataModifier(new IdModifier<>(id)); + // 事件 Map>> eventTriggerListMap; try { eventTriggerListMap = EventFunctions.parseEvents(ResourceConfigUtils.get(section, "events", "event")); @@ -409,6 +393,7 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl eventTriggerListMap = Map.of(); } + // 设置 ItemSettings settings; try { settings = Optional.ofNullable(ResourceConfigUtils.get(section, "settings")) @@ -419,12 +404,23 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl collector.add(e); settings = ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem); } + + // 行为 + List behaviors; + try { + behaviors = ItemBehaviors.fromObj(pack, path, id, ResourceConfigUtils.get(section, "behavior", "behaviors")); + } catch (LocalizedResourceConfigException e) { + collector.add(e); + behaviors = Collections.emptyList(); + } + // 构建自定义物品 CustomItem customItem = itemBuilder - .behaviors(ItemBehaviors.fromObj(pack, path, id, ResourceConfigUtils.get(section, "behavior", "behaviors"))) + .behaviors(behaviors) .settings(settings) .events(eventTriggerListMap) .build(); + // 添加到缓存 addCustomItem(customItem); @@ -433,13 +429,11 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl AbstractItemManager.this.plugin.itemBrowserManager().addExternalCategoryMember(id, MiscUtils.getAsStringList(section.get("category")).stream().map(Key::of).toList()); } - // 抛出异常 - collector.throwIfPresent(); - // 模型配置区域,如果这里被配置了,那么用户必须要配置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) { + collector.throwIfPresent(); return; } @@ -448,39 +442,47 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl if (!isVanillaItem) { // 既没有模型值也没有item-model if (customModelData == 0 && itemModelKey == null) { - throw new LocalizedResourceConfigException("warning.config.item.missing_model_id"); + collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model_id")); } } - // 1.21.4+必须要配置model区域,如果不需要高版本兼容,则可以只写legacy-model - if (needsModelSection && modelSection == null) { - throw new LocalizedResourceConfigException("warning.config.item.missing_model"); - } - // 新版格式 ItemModel modernModel = null; // 旧版格式 TreeSet legacyOverridesModels = null; // 如果需要支持新版item model 或者用户需要旧版本兼容,但是没配置legacy-model if (needsModelSection) { - modernModel = ItemModels.fromMap(modelSection); - for (ModelGeneration generation : modernModel.modelsToGenerate()) { - prepareModelGeneration(generation); + // 1.21.4+必须要配置model区域,如果不需要高版本兼容,则可以只写legacy-model + if (modelSection == null) { + collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model")); + return; + } + try { + modernModel = ItemModels.fromMap(modelSection); + for (ModelGeneration generation : modernModel.modelsToGenerate()) { + prepareModelGeneration(generation); + } + } catch (LocalizedResourceConfigException e) { + collector.addAndThrow(e); } } // 如果需要旧版本兼容 if (needsLegacyCompatibility()) { if (legacyModelSection != null) { - LegacyItemModel legacyItemModel = LegacyItemModel.fromMap(legacyModelSection, customModelData); - for (ModelGeneration generation : legacyItemModel.modelsToGenerate()) { - prepareModelGeneration(generation); + try { + LegacyItemModel legacyItemModel = LegacyItemModel.fromMap(legacyModelSection, customModelData); + for (ModelGeneration generation : legacyItemModel.modelsToGenerate()) { + prepareModelGeneration(generation); + } + legacyOverridesModels = new TreeSet<>(legacyItemModel.overrides()); + } catch (LocalizedResourceConfigException e) { + collector.addAndThrow(e); } - legacyOverridesModels = new TreeSet<>(legacyItemModel.overrides()); } else { legacyOverridesModels = new TreeSet<>(); processModelRecursively(modernModel, new LinkedHashMap<>(), legacyOverridesModels, clientBoundMaterial, customModelData); if (legacyOverridesModels.isEmpty()) { - TranslationManager.instance().log("warning.config.item.legacy_model.cannot_convert", path.toString(), id.asString()); + collector.add(new LocalizedResourceConfigException("warning.config.item.legacy_model.cannot_convert", path.toString(), id.asString())); } } } @@ -496,7 +498,7 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl // 检查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()); + collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.custom_model_data_conflict", String.valueOf(customModelData), conflict.get(customModelData).toString())); } conflict.put(customModelData, id); // 添加新版item model @@ -514,7 +516,7 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl lom.addAll(legacyOverridesModels); } } else if (isVanillaItemModel) { - throw new LocalizedResourceConfigException("warning.config.item.item_model.conflict", itemModelKey.asString()); + collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.item_model.conflict", itemModelKey.asString())); } // 使用了item-model组件,且不是原版物品的 @@ -541,157 +543,9 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl )); } } - } - } - private void registerFunctions() { - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - String plugin = data.get("plugin").toString(); - String id = data.get("id").toString(); - ExternalItemSource provider = AbstractItemManager.this.getExternalItemSource(plugin.toLowerCase(Locale.ENGLISH)); - return new ExternalModifier<>(id, Objects.requireNonNull(provider, "Item provider " + plugin + " not found")); - }, "external"); - if (VersionHelper.isOrAbove1_20_5()) { - registerDataType((obj) -> { - String name = obj.toString(); - return new CustomNameModifier<>(name); - }, "custom-name"); - registerDataType((obj) -> { - String name = obj.toString(); - return new ItemNameModifier<>(name); - }, "item-name", "display-name"); - } else { - registerDataType((obj) -> { - String name = obj.toString(); - return new CustomNameModifier<>(name); - }, "custom-name", "item-name", "display-name"); - } - registerDataType(LoreModifier::createLoreModifier, "lore", "display-lore", "description"); - registerDataType((obj) -> { - Map> dynamicLore = new LinkedHashMap<>(); - if (obj instanceof Map map) { - for (Map.Entry entry : map.entrySet()) { - dynamicLore.put(entry.getKey().toString(), LoreModifier.createLoreModifier(entry.getValue())); - } - } - return new DynamicLoreModifier<>(dynamicLore); - }, "dynamic-lore"); - registerDataType((obj) -> { - if (obj instanceof Integer integer) { - return new DyedColorModifier<>(Color.fromDecimal(integer)); - } else { - Vector3f vector3f = MiscUtils.getAsVector3f(obj, "dyed-color"); - return new DyedColorModifier<>(Color.fromVector3f(vector3f)); - } - }, "dyed-color"); - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - return new TagsModifier<>(data); - }, "tags", "tag", "nbt"); - registerDataType((object -> { - MutableInt mutableInt = new MutableInt(0); - List attributeModifiers = ResourceConfigUtils.parseConfigAsList(object, (map) -> { - String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.item.data.attribute_modifiers.missing_type"); - Key nativeType = AttributeModifiersModifier.getNativeAttributeName(Key.of(type)); - AttributeModifier.Slot slot = AttributeModifier.Slot.valueOf(map.getOrDefault("slot", "any").toString().toUpperCase(Locale.ENGLISH)); - Key id = Optional.ofNullable(map.get("id")).map(String::valueOf).map(Key::of).orElseGet(() -> { - mutableInt.add(1); - return Key.of("craftengine", "modifier_" + mutableInt.intValue()); - }); - double amount = ResourceConfigUtils.getAsDouble( - ResourceConfigUtils.requireNonNullOrThrow(map.get("amount"), "warning.config.item.data.attribute_modifiers.missing_amount"), "amount" - ); - AttributeModifier.Operation operation = AttributeModifier.Operation.valueOf( - ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("operation"), "warning.config.item.data.attribute_modifiers.missing_operation").toUpperCase(Locale.ENGLISH) - ); - AttributeModifier.Display display = null; - if (VersionHelper.isOrAbove1_21_6() && map.containsKey("display")) { - Map displayMap = MiscUtils.castToMap(map.get("display"), false); - AttributeModifier.Display.Type displayType = AttributeModifier.Display.Type.valueOf(ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("type"), "warning.config.item.data.attribute_modifiers.display.missing_type").toUpperCase(Locale.ENGLISH)); - if (displayType == AttributeModifier.Display.Type.OVERRIDE) { - String miniMessageValue = ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("value"), "warning.config.item.data.attribute_modifiers.display.missing_value"); - display = new AttributeModifier.Display(displayType, miniMessageValue); - } else { - display = new AttributeModifier.Display(displayType, null); - } - } - return new AttributeModifier(nativeType.value(), slot, id, - amount, operation, display); - }); - return new AttributeModifiersModifier<>(attributeModifiers); - }), "attributes", "attribute-modifiers", "attribute-modifier"); - registerDataType((obj) -> { - boolean value = TypeUtils.checkType(obj, Boolean.class); - return new UnbreakableModifier<>(value); - }, "unbreakable"); - registerDataType((obj) -> { - int customModelData = ResourceConfigUtils.getAsInt(obj, "custom-model-data"); - return new CustomModelDataModifier<>(customModelData); - }, "custom-model-data"); - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - List enchantments = new ArrayList<>(); - for (Map.Entry e : data.entrySet()) { - if (e.getValue() instanceof Number number) { - enchantments.add(new Enchantment(Key.of(e.getKey()), number.intValue())); - } - } - return new EnchantmentModifier<>(enchantments); - }, "enchantment", "enchantments", "enchant"); - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - String material = data.get("material").toString().toLowerCase(Locale.ENGLISH); - String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH); - return new TrimModifier<>(Key.of(material), Key.of(pattern)); - }, "trim"); - registerDataType((obj) -> { - List components = MiscUtils.getAsStringList(obj).stream().map(Key::of).toList(); - return new HideTooltipModifier<>(components); - }, "hide-tooltip", "hide-flags"); - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - Map arguments = new HashMap<>(); - for (Map.Entry entry : data.entrySet()) { - arguments.put(entry.getKey(), TextProviders.fromString(entry.getValue().toString())); - } - return new ArgumentModifier<>(arguments); - }, "args", "argument", "arguments"); - if (VersionHelper.isOrAbove1_20_5()) { - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - return new ComponentModifier<>(data); - }, "components", "component"); - registerDataType((obj) -> { - List data = MiscUtils.getAsStringList(obj); - return new RemoveComponentModifier<>(data); - }, "remove-components", "remove-component"); - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - int nutrition = ResourceConfigUtils.getAsInt(data.get("nutrition"), "nutrition"); - float saturation = ResourceConfigUtils.getAsFloat(data.get("saturation"), "saturation"); - return new FoodModifier<>(nutrition, saturation, ResourceConfigUtils.getAsBoolean(data.getOrDefault("can-always-eat", false), "can-always-eat")); - }, "food"); - } - if (VersionHelper.isOrAbove1_21()) { - registerDataType((obj) -> { - String song = obj.toString(); - return new JukeboxSongModifier<>(new JukeboxPlayable(song, true)); - }, "jukebox-playable"); - } - if (VersionHelper.isOrAbove1_21_2()) { - registerDataType((obj) -> { - String id = obj.toString(); - return new TooltipStyleModifier<>(Key.of(id)); - }, "tooltip-style"); - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - return new EquippableModifier<>(EquipmentData.fromMap(data)); - }, "equippable"); - registerDataType((obj) -> { - String id = obj.toString(); - return new ItemModelModifier<>(Key.of(id)); - }, "item-model"); + // 抛出异常 + collector.throwIfPresent(); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java index f1692ece7..ee799b262 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.attribute.AttributeModifier; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.data.Enchantment; import net.momirealms.craftengine.core.item.data.FireworkExplosion; @@ -119,6 +120,8 @@ public interface Item { Optional> loreComponent(); + Item attributeModifiers(List modifiers); + Optional jukeboxSong(); Item jukeboxSong(JukeboxPlayable song); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemDataModifierFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemDataModifierFactory.java new file mode 100644 index 000000000..446ed2272 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemDataModifierFactory.java @@ -0,0 +1,8 @@ +package net.momirealms.craftengine.core.item; + +import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; + +public interface ItemDataModifierFactory { + + ItemDataModifier create(Object arg); +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java index 70d734922..f88830935 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.attribute.AttributeModifier; import net.momirealms.craftengine.core.item.data.Enchantment; import net.momirealms.craftengine.core.item.data.FireworkExplosion; import net.momirealms.craftengine.core.item.data.JukeboxPlayable; @@ -215,4 +216,6 @@ public abstract class ItemFactory, I> { protected abstract boolean isDyeItem(W item); protected abstract Optional dyeColor(W item); + + protected abstract void attributeModifiers(W item, List modifiers); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java index d88e2d5d3..9b82c4f3d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java @@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.equipment.Equipment; -import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; import net.momirealms.craftengine.core.item.recipe.UniqueIdItem; import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel; import net.momirealms.craftengine.core.pack.model.ModernItemModel; @@ -18,14 +17,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.function.Function; public interface ItemManager extends Manageable, ModelGenerator { - void registerDataType(Function> factory, String... alias); - - Function> getDataType(String key); - Map equipments(); ConfigParser[] parsers(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ArgumentModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ArgumentsModifier.java similarity index 59% rename from core/src/main/java/net/momirealms/craftengine/core/item/modifier/ArgumentModifier.java rename to core/src/main/java/net/momirealms/craftengine/core/item/modifier/ArgumentsModifier.java index 63628171d..33f4bb98f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ArgumentModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ArgumentsModifier.java @@ -3,7 +3,11 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.plugin.context.text.TextProvider; +import net.momirealms.craftengine.core.plugin.context.text.TextProviders; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.StringTag; @@ -12,17 +16,22 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -public class ArgumentModifier implements ItemDataModifier { +public class ArgumentsModifier implements ItemDataModifier { + public static final Factory FACTORY = new Factory<>(); public static final String ARGUMENTS_TAG = "craftengine:arguments"; private final Map arguments; - public ArgumentModifier(Map arguments) { + public ArgumentsModifier(Map arguments) { this.arguments = arguments; } + public Map arguments() { + return arguments; + } + @Override - public String name() { - return "arguments"; + public Key type() { + return ItemDataModifiers.ARGUMENTS; } @Override @@ -44,4 +53,17 @@ public class ArgumentModifier implements ItemDataModifier { } return item; } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "arguments"); + Map arguments = new HashMap<>(); + for (Map.Entry entry : data.entrySet()) { + arguments.put(entry.getKey(), TextProviders.fromString(entry.getValue().toString())); + } + return new ArgumentsModifier<>(arguments); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/AttributeModifiersModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/AttributeModifiersModifier.java index 1bc71cff2..eaa06e44f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/AttributeModifiersModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/AttributeModifiersModifier.java @@ -6,19 +6,14 @@ import net.momirealms.craftengine.core.attribute.Attributes1_21; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; -import net.momirealms.craftengine.core.util.AdventureHelper; -import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.UUIDUtils; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.ListTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; +import net.momirealms.craftengine.core.util.*; +import org.jetbrains.annotations.Nullable; -import java.nio.charset.StandardCharsets; import java.util.*; -public class AttributeModifiersModifier implements ItemDataModifier { +public class AttributeModifiersModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); public static final Map CONVERTOR = new HashMap<>(); static { @@ -102,89 +97,64 @@ public class AttributeModifiersModifier implements ItemDataModifier { } @Override - public String name() { - return "attribute-modifiers"; + public Key type() { + return ItemDataModifiers.ATTRIBUTE_MODIFIERS; } - private static Object previous; - @Override public Item apply(Item item, ItemBuildContext context) { - if (VersionHelper.isOrAbove1_21_5()) { - ListTag modifiers = new ListTag(); - for (AttributeModifier modifier : this.modifiers) { - CompoundTag modifierTag = new CompoundTag(); - modifierTag.putString("type", modifier.type()); - modifierTag.putString("slot", modifier.slot().name().toLowerCase(Locale.ENGLISH)); - modifierTag.putString("id", modifier.id().toString()); - modifierTag.putDouble("amount", modifier.amount()); - modifierTag.putString("operation", modifier.operation().id()); - AttributeModifier.Display display = modifier.display(); - if (VersionHelper.isOrAbove1_21_6() && display != null) { - CompoundTag displayTag = new CompoundTag(); - AttributeModifier.Display.Type displayType = display.type(); - displayTag.putString("type", displayType.name().toLowerCase(Locale.ENGLISH)); - if (displayType == AttributeModifier.Display.Type.OVERRIDE) { - displayTag.put("value", AdventureHelper.componentToTag(AdventureHelper.miniMessage().deserialize(display.value(), context.tagResolvers()))); - } - modifierTag.put("display", displayTag); - } - modifiers.add(modifierTag); - } - item.setNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS, modifiers); - } else if (VersionHelper.isOrAbove1_20_5()) { - CompoundTag compoundTag = (CompoundTag) Optional.ofNullable(item.getSparrowNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS)).orElseGet(CompoundTag::new); - ListTag modifiers = new ListTag(); - compoundTag.put("modifiers", modifiers); - for (AttributeModifier modifier : this.modifiers) { - CompoundTag modifierTag = new CompoundTag(); - modifierTag.putString("type", modifier.type()); - modifierTag.putString("slot", modifier.slot().name().toLowerCase(Locale.ENGLISH)); - if (VersionHelper.isOrAbove1_21()) { - modifierTag.putString("id", modifier.id().toString()); - } else { - modifierTag.putIntArray("uuid", UUIDUtils.uuidToIntArray(UUID.nameUUIDFromBytes(modifier.id().toString().getBytes(StandardCharsets.UTF_8)))); - modifierTag.putString("name", modifier.id().toString()); - } - modifierTag.putDouble("amount", modifier.amount()); - modifierTag.putString("operation", modifier.operation().id()); - modifiers.add(modifierTag); - } - item.setNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS, compoundTag); - } else { - ListTag listTag = new ListTag(); - for (AttributeModifier modifier : this.modifiers) { - CompoundTag modifierTag = new CompoundTag(); - modifierTag.putString("AttributeName", modifier.type()); - modifierTag.putString("Name", modifier.id().toString()); - modifierTag.putString("Slot", modifier.slot().name().toLowerCase(Locale.ENGLISH)); - modifierTag.putInt("Operation", modifier.operation().ordinal()); - modifierTag.putDouble("Amount", modifier.amount()); - modifierTag.putIntArray("UUID", UUIDUtils.uuidToIntArray(UUID.nameUUIDFromBytes(modifier.id().toString().getBytes(StandardCharsets.UTF_8)))); - listTag.add(modifierTag); - } - item.setTag(listTag, "AttributeModifiers"); - } - return item; + return item.attributeModifiers(this.modifiers); } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS); - if (previous != null) { - networkData.put(ComponentKeys.ATTRIBUTE_MODIFIERS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.ATTRIBUTE_MODIFIERS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("AttributeModifiers"); - if (previous != null) { - networkData.put("AttributeModifiers", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("AttributeModifiers", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.ATTRIBUTE_MODIFIERS; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"AttributeModifiers"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "AttributeModifiers"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + MutableInt mutableInt = new MutableInt(0); + List attributeModifiers = ResourceConfigUtils.parseConfigAsList(arg, (map) -> { + String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.item.data.attribute_modifiers.missing_type"); + Key nativeType = AttributeModifiersModifier.getNativeAttributeName(Key.of(type)); + AttributeModifier.Slot slot = AttributeModifier.Slot.valueOf(map.getOrDefault("slot", "any").toString().toUpperCase(Locale.ENGLISH)); + Key id = Optional.ofNullable(map.get("id")).map(String::valueOf).map(Key::of).orElseGet(() -> { + mutableInt.add(1); + return Key.of("craftengine", "modifier_" + mutableInt.intValue()); + }); + double amount = ResourceConfigUtils.getAsDouble( + ResourceConfigUtils.requireNonNullOrThrow(map.get("amount"), "warning.config.item.data.attribute_modifiers.missing_amount"), "amount" + ); + AttributeModifier.Operation operation = AttributeModifier.Operation.valueOf( + ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("operation"), "warning.config.item.data.attribute_modifiers.missing_operation").toUpperCase(Locale.ENGLISH) + ); + AttributeModifier.Display display = null; + if (VersionHelper.isOrAbove1_21_6() && map.containsKey("display")) { + Map displayMap = MiscUtils.castToMap(map.get("display"), false); + AttributeModifier.Display.Type displayType = AttributeModifier.Display.Type.valueOf(ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("type"), "warning.config.item.data.attribute_modifiers.display.missing_type").toUpperCase(Locale.ENGLISH)); + if (displayType == AttributeModifier.Display.Type.OVERRIDE) { + String miniMessageValue = ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("value"), "warning.config.item.data.attribute_modifiers.display.missing_value"); + display = new AttributeModifier.Display(displayType, AdventureHelper.miniMessage().deserialize(miniMessageValue)); + } else { + display = new AttributeModifier.Display(displayType, null); + } + } + return new AttributeModifier(nativeType.value(), slot, id, + amount, operation, display); + }); + return new AttributeModifiersModifier<>(attributeModifiers); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentsModifier.java similarity index 80% rename from core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java rename to core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentsModifier.java index 3dc223ca3..7e822a08d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentsModifier.java @@ -1,14 +1,12 @@ package net.momirealms.craftengine.core.item.modifier; import com.google.gson.JsonElement; -import net.momirealms.craftengine.core.item.ComponentKeys; -import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.*; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.GsonHelper; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Pair; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; @@ -16,11 +14,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -public class ComponentModifier implements ItemDataModifier { +public class ComponentsModifier implements ItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final List> arguments; private CompoundTag customData = null; - public ComponentModifier(Map arguments) { + public ComponentsModifier(Map arguments) { List> pairs = new ArrayList<>(arguments.size()); for (Map.Entry entry : arguments.entrySet()) { Key key = Key.of(entry.getKey()); @@ -33,7 +32,7 @@ public class ComponentModifier implements ItemDataModifier { this.arguments = pairs; } - public List> arguments() { + public List> components() { return arguments; } @@ -49,8 +48,8 @@ public class ComponentModifier implements ItemDataModifier { } @Override - public String name() { - return "components"; + public Key type() { + return ItemDataModifiers.COMPONENTS; } @Override @@ -84,4 +83,13 @@ public class ComponentModifier implements ItemDataModifier { } return item; } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "components"); + return new ComponentsModifier<>(data); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomModelDataModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomModelDataModifier.java index f76bb1c78..9d1c68671 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomModelDataModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomModelDataModifier.java @@ -3,21 +3,26 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; -public class CustomModelDataModifier implements ItemDataModifier { +public class CustomModelDataModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final int argument; public CustomModelDataModifier(int argument) { this.argument = argument; } + public int customModelData() { + return this.argument; + } + @Override - public String name() { - return "custom-model-data"; + public Key type() { + return ItemDataModifiers.CUSTOM_MODEL_DATA; } @Override @@ -27,22 +32,26 @@ public class CustomModelDataModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.CUSTOM_MODEL_DATA); - if (previous != null) { - networkData.put(ComponentKeys.CUSTOM_MODEL_DATA.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.CUSTOM_MODEL_DATA.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("CustomModelData"); - if (previous != null) { - networkData.put("CustomModelData", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("CustomModelData", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.CUSTOM_MODEL_DATA; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"CustomModelData"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "CustomModelData"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + int customModelData = ResourceConfigUtils.getAsInt(arg, "custom-model-data"); + return new CustomModelDataModifier<>(customModelData); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomNameModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomNameModifier.java index ecbbbe33a..8989c2225 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomNameModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomNameModifier.java @@ -3,14 +3,14 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.AdventureHelper; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.util.Key; +import org.jetbrains.annotations.Nullable; -public class CustomNameModifier implements ItemDataModifier { +public class CustomNameModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final String argument; public CustomNameModifier(String argument) { @@ -25,9 +25,13 @@ public class CustomNameModifier implements ItemDataModifier { } } + public String customName() { + return argument; + } + @Override - public String name() { - return "custom-name"; + public Key type() { + return ItemDataModifiers.CUSTOM_NAME; } @Override @@ -37,22 +41,26 @@ public class CustomNameModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.CUSTOM_NAME); - if (previous != null) { - networkData.put(ComponentKeys.CUSTOM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.CUSTOM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("display", "Name"); - if (previous != null) { - networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.CUSTOM_NAME; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"display", "Name"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "display.Name"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + String name = arg.toString(); + return new CustomNameModifier<>(name); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java index f96536406..2ce36e797 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java @@ -3,47 +3,60 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.util.Color; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MiscUtils; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; -public class DyedColorModifier implements ItemDataModifier { +public class DyedColorModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final Color color; public DyedColorModifier(Color color) { this.color = color; } + public Color dyedColor() { + return color; + } + @Override - public String name() { - return "dyed-color"; + public Key type() { + return ItemDataModifiers.DYED_COLOR; } @Override public Item apply(Item item, ItemBuildContext context) { - item.dyedColor(this.color); - return item; + return item.dyedColor(this.color); } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.DYED_COLOR); - if (previous != null) { - networkData.put(ComponentKeys.DYED_COLOR.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.DYED_COLOR; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"display", "color"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "display.color"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + if (arg instanceof Integer integer) { + return new DyedColorModifier<>(Color.fromDecimal(integer)); } else { - networkData.put(ComponentKeys.DYED_COLOR.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("display", "color"); - if (previous != null) { - networkData.put("display.color", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("display.color", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + Vector3f vector3f = MiscUtils.getAsVector3f(arg, "dyed-color"); + return new DyedColorModifier<>(Color.fromVector3f(vector3f)); } } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EnchantmentModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EnchantmentModifier.java deleted file mode 100644 index 9168de84a..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EnchantmentModifier.java +++ /dev/null @@ -1,70 +0,0 @@ -package net.momirealms.craftengine.core.item.modifier; - -import net.momirealms.craftengine.core.item.*; -import net.momirealms.craftengine.core.item.data.Enchantment; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; - -import java.util.List; - -public class EnchantmentModifier implements ItemDataModifier { - private final List enchantments; - - public EnchantmentModifier(List enchantments) { - this.enchantments = enchantments; - } - - @Override - public String name() { - return "enchantment"; - } - - @Override - public Item apply(Item item, ItemBuildContext context) { - if (item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK)) { - item.setStoredEnchantments(this.enchantments); - } else { - item.setEnchantments(this.enchantments); - } - return item; - } - - @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK)) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.STORED_ENCHANTMENTS); - if (previous != null) { - networkData.put(ComponentKeys.STORED_ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.STORED_ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("StoredEnchantments"); - if (previous != null) { - networkData.put("StoredEnchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("StoredEnchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } - } else { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.ENCHANTMENTS); - if (previous != null) { - networkData.put(ComponentKeys.ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("Enchantments"); - if (previous != null) { - networkData.put("Enchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("Enchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } - } - return item; - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EnchantmentsModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EnchantmentsModifier.java new file mode 100644 index 000000000..8dbb7a591 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EnchantmentsModifier.java @@ -0,0 +1,68 @@ +package net.momirealms.craftengine.core.item.modifier; + +import net.momirealms.craftengine.core.item.*; +import net.momirealms.craftengine.core.item.data.Enchantment; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class EnchantmentsModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); + private final List enchantments; + + public EnchantmentsModifier(List enchantments) { + this.enchantments = enchantments; + } + + public List enchantments() { + return enchantments; + } + + @Override + public Key type() { + return ItemDataModifiers.ENCHANTMENTS; + } + + @Override + public Item apply(Item item, ItemBuildContext context) { + if (item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK)) { + return item.setStoredEnchantments(this.enchantments); + } else { + return item.setEnchantments(this.enchantments); + } + } + + @Override + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK) ? ComponentKeys.STORED_ENCHANTMENTS : ComponentKeys.ENCHANTMENTS; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK) ? new Object[]{"StoredEnchantments"} : new Object[]{"Enchantments"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK) ? "StoredEnchantments" : "Enchantments"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "enchantments"); + List enchantments = new ArrayList<>(); + for (Map.Entry e : data.entrySet()) { + if (e.getValue() instanceof Number number) { + enchantments.add(new Enchantment(Key.of(e.getKey()), number.intValue())); + } + } + return new EnchantmentsModifier<>(enchantments); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableAssetIdModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableAssetIdModifier.java index 48630e358..d6cb67ac6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableAssetIdModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableAssetIdModifier.java @@ -3,24 +3,26 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; import net.momirealms.craftengine.core.item.setting.EquipmentData; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import org.jetbrains.annotations.Nullable; import java.util.Optional; -public class EquippableAssetIdModifier implements ItemDataModifier { +public class EquippableAssetIdModifier implements SimpleNetworkItemDataModifier { private final Key assetId; public EquippableAssetIdModifier(Key assetsId) { this.assetId = assetsId; } + public Key assetId() { + return assetId; + } + @Override - public String name() { - return "equippable-asset-id"; + public Key type() { + return ItemDataModifiers.EQUIPPABLE_ASSET_ID; } @Override @@ -39,13 +41,7 @@ public class EquippableAssetIdModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.EQUIPPABLE); - if (previous != null) { - networkData.put(ComponentKeys.EQUIPPABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.EQUIPPABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - return item; + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.EQUIPPABLE; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java index 9851c1141..6570920da 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/EquippableModifier.java @@ -1,24 +1,49 @@ package net.momirealms.craftengine.core.item.modifier; +import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.setting.EquipmentData; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; -public class EquippableModifier implements ItemDataModifier { +import java.util.Map; + +public class EquippableModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final EquipmentData data; public EquippableModifier(EquipmentData data) { this.data = data; } + public EquipmentData data() { + return data; + } + @Override - public String name() { - return "equippable"; + public Key type() { + return ItemDataModifiers.EQUIPPABLE; } @Override public Item apply(Item item, ItemBuildContext context) { - item.equippable(this.data); - return item; + return item.equippable(this.data); + } + + @Override + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.EQUIPPABLE; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "equippable"); + return new EquippableModifier<>(EquipmentData.fromMap(data)); + } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ExternalModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ExternalModifier.java index 3acc923b8..a424feb2a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ExternalModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ExternalModifier.java @@ -3,9 +3,17 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ExternalItemSource; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; + +import java.util.Locale; +import java.util.Map; public class ExternalModifier implements ItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final String id; private final ExternalItemSource provider; @@ -14,9 +22,17 @@ public class ExternalModifier implements ItemDataModifier { this.provider = provider; } + public String id() { + return id; + } + + public ExternalItemSource source() { + return provider; + } + @Override - public String name() { - return "external"; + public Key type() { + return ItemDataModifiers.EXTERNAL; } @SuppressWarnings("unchecked") @@ -31,4 +47,17 @@ public class ExternalModifier implements ItemDataModifier { item.merge(anotherWrapped); return item; } + + public static class Factory implements ItemDataModifierFactory { + + @SuppressWarnings("unchecked") + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "external"); + String plugin = ResourceConfigUtils.requireNonEmptyStringOrThrow(ResourceConfigUtils.get(data, "plugin", "source"), "warning.config.item.data.external.missing_source"); + String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(data.get("id"), "warning.config.item.data.external.missing_id"); + ExternalItemSource provider = (ExternalItemSource) CraftEngine.instance().itemManager().getExternalItemSource(plugin.toLowerCase(Locale.ENGLISH)); + return new ExternalModifier<>(id, ResourceConfigUtils.requireNonNullOrThrow(provider, () -> new LocalizedResourceConfigException("warning.config.item.data.external.invalid_source", plugin))); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/FoodModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/FoodModifier.java index 4ab82b684..42fcb7f65 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/FoodModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/FoodModifier.java @@ -3,13 +3,15 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; import java.util.Map; -public class FoodModifier implements ItemDataModifier { +public class FoodModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final int nutrition; private final float saturation; private final boolean canAlwaysEat; @@ -20,9 +22,21 @@ public class FoodModifier implements ItemDataModifier { this.saturation = saturation; } + public boolean canAlwaysEat() { + return canAlwaysEat; + } + + public int nutrition() { + return nutrition; + } + + public float saturation() { + return saturation; + } + @Override - public String name() { - return "food"; + public Key type() { + return ItemDataModifiers.FOOD; } @Override @@ -36,13 +50,18 @@ public class FoodModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.FOOD); - if (previous != null) { - networkData.put(ComponentKeys.FOOD.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.FOOD.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.FOOD; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "food"); + int nutrition = ResourceConfigUtils.getAsInt(data.get("nutrition"), "nutrition"); + float saturation = ResourceConfigUtils.getAsFloat(data.get("saturation"), "saturation"); + return new FoodModifier<>(nutrition, saturation, ResourceConfigUtils.getAsBoolean(data.getOrDefault("can-always-eat", false), "can-always-eat")); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/HideTooltipModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/HideTooltipModifier.java index 56fa6eea9..e2b229923 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/HideTooltipModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/HideTooltipModifier.java @@ -1,10 +1,7 @@ package net.momirealms.craftengine.core.item.modifier; import com.google.common.collect.ImmutableMap; -import net.momirealms.craftengine.core.item.ComponentKeys; -import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.*; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.VersionHelper; @@ -19,6 +16,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; public class HideTooltipModifier implements ItemDataModifier { + public static final Factory FACTORY = new Factory<>(); public static final Map TO_LEGACY; public static final List COMPONENTS = List.of( ComponentKeys.UNBREAKABLE, @@ -127,8 +125,8 @@ public class HideTooltipModifier implements ItemDataModifier { } @Override - public String name() { - return "hide-tooltip"; + public Key type() { + return ItemDataModifiers.HIDE_TOOLTIP; } public interface Applier { @@ -233,4 +231,13 @@ public class HideTooltipModifier implements ItemDataModifier { } } } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + List components = MiscUtils.getAsStringList(arg).stream().map(Key::of).toList(); + return new HideTooltipModifier<>(components); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java index 690236b87..a262ac971 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java @@ -12,9 +12,13 @@ public class IdModifier implements ItemDataModifier { this.argument = argument; } + public Key identifier() { + return argument; + } + @Override - public String name() { - return "id"; + public Key type() { + return ItemDataModifiers.ID; } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifier.java index 2ffe87f59..6a39cf797 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifier.java @@ -2,11 +2,12 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.util.Key; import net.momirealms.sparrow.nbt.CompoundTag; public interface ItemDataModifier { - String name(); + Key type(); Item apply(Item item, ItemBuildContext context); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java new file mode 100644 index 000000000..f120401e8 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java @@ -0,0 +1,88 @@ +package net.momirealms.craftengine.core.item.modifier; + +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; +import net.momirealms.craftengine.core.item.modifier.lore.DynamicLoreModifier; +import net.momirealms.craftengine.core.item.modifier.lore.LoreModifier; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; +import net.momirealms.craftengine.core.registry.Registries; +import net.momirealms.craftengine.core.registry.WritableRegistry; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceKey; +import net.momirealms.craftengine.core.util.VersionHelper; + +public final class ItemDataModifiers { + private ItemDataModifiers() {} + + public static final Key ITEM_MODEL = Key.of("craftengine:item-model"); + public static final Key ID = Key.of("craftengine:id"); + public static final Key HIDE_TOOLTIP = Key.of("craftengine:hide-tooltip"); + public static final Key FOOD = Key.of("craftengine:food"); + public static final Key EXTERNAL = Key.of("craftengine:external"); + public static final Key EQUIPPABLE = Key.of("craftengine:equippable"); + public static final Key EQUIPPABLE_ASSET_ID = Key.of("craftengine:equippable-asset-id"); + public static final Key ENCHANTMENT = Key.of("craftengine:enchantment"); + public static final Key ENCHANTMENTS = Key.of("craftengine:enchantments"); + public static final Key DYED_COLOR = Key.of("craftengine:dyed-color"); + public static final Key DISPLAY_NAME = Key.of("craftengine:display-name"); + public static final Key CUSTOM_NAME = Key.of("craftengine:custom-name"); + public static final Key CUSTOM_MODEL_DATA = Key.of("craftengine:custom-model-data"); + public static final Key COMPONENTS = Key.of("craftengine:components"); + public static final Key ATTRIBUTE_MODIFIERS = Key.of("craftengine:attribute-modifiers"); + public static final Key ATTRIBUTES = Key.of("craftengine:attributes"); + public static final Key ARGUMENTS = Key.of("craftengine:arguments"); + public static final Key ITEM_NAME = Key.of("craftengine:item-name"); + public static final Key JUKEBOX_PLAYABLE = Key.of("craftengine:jukebox-playable"); + public static final Key REMOVE_COMPONENTS = Key.of("craftengine:remove-components"); + public static final Key TAGS = Key.of("craftengine:tags"); + public static final Key NBT = Key.of("craftengine:nbt"); + public static final Key TOOLTIP_STYLE = Key.of("craftengine:tooltip-style"); + public static final Key TRIM = Key.of("craftengine:trim"); + public static final Key LORE = Key.of("craftengine:lore"); + public static final Key UNBREAKABLE = Key.of("craftengine:unbreakable"); + public static final Key DYNAMIC_LORE = Key.of("craftengine:dynamic-lore"); + + public static void register(Key key, ItemDataModifierFactory factory) { + ((WritableRegistry>) BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY) + .register(ResourceKey.create(Registries.ITEM_DATA_MODIFIER_FACTORY.location(), key), factory); + } + + public static void init() {} + + static { + register(EXTERNAL, ExternalModifier.FACTORY); + register(LORE, LoreModifier.FACTORY); + register(DYNAMIC_LORE, DynamicLoreModifier.FACTORY); + register(DYED_COLOR, DyedColorModifier.FACTORY); + register(TAGS, TagsModifier.FACTORY); + register(NBT, TagsModifier.FACTORY); + register(ATTRIBUTE_MODIFIERS, AttributeModifiersModifier.FACTORY); + register(ATTRIBUTES, AttributeModifiersModifier.FACTORY); + register(CUSTOM_MODEL_DATA, CustomModelDataModifier.FACTORY); + register(UNBREAKABLE, UnbreakableModifier.FACTORY); + register(ENCHANTMENT, EnchantmentsModifier.FACTORY); + register(ENCHANTMENTS, EnchantmentsModifier.FACTORY); + register(TRIM, TrimModifier.FACTORY); + register(HIDE_TOOLTIP, HideTooltipModifier.FACTORY); + register(ARGUMENTS, ArgumentsModifier.FACTORY); + if (VersionHelper.isOrAbove1_20_5()) { + register(CUSTOM_NAME, CustomNameModifier.FACTORY); + register(ITEM_NAME, ItemNameModifier.FACTORY); + register(DISPLAY_NAME, ItemNameModifier.FACTORY); + register(COMPONENTS, ComponentsModifier.FACTORY); + register(REMOVE_COMPONENTS, RemoveComponentModifier.FACTORY); + register(FOOD, FoodModifier.FACTORY); + } else { + register(CUSTOM_NAME, CustomNameModifier.FACTORY); + register(ITEM_NAME, CustomNameModifier.FACTORY); + register(DISPLAY_NAME, CustomNameModifier.FACTORY); + } + if (VersionHelper.isOrAbove1_21()) { + register(JUKEBOX_PLAYABLE, JukeboxSongModifier.FACTORY); + } + if (VersionHelper.isOrAbove1_21_2()) { + register(TOOLTIP_STYLE, TooltipStyleModifier.FACTORY); + register(ITEM_MODEL, ItemModelModifier.FACTORY); + register(EQUIPPABLE, EquippableModifier.FACTORY); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemModelModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemModelModifier.java index 319cacc13..c83be84d6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemModelModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemModelModifier.java @@ -3,37 +3,43 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import org.jetbrains.annotations.Nullable; -public class ItemModelModifier implements ItemDataModifier { +public class ItemModelModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final Key data; public ItemModelModifier(Key data) { this.data = data; } + public Key data() { + return data; + } + @Override - public String name() { - return "item-model"; + public Key type() { + return ItemDataModifiers.ITEM_MODEL; } @Override public Item apply(Item item, ItemBuildContext context) { - item.itemModel(this.data.toString()); - return item; + return item.itemModel(this.data.asString()); } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.ITEM_MODEL); - if (previous != null) { - networkData.put(ComponentKeys.ITEM_MODEL.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.ITEM_MODEL.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.ITEM_MODEL; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + String id = arg.toString(); + return new ItemModelModifier<>(Key.of(id)); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java index 63cfac93f..20728b979 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java @@ -3,22 +3,26 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.util.AdventureHelper; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.util.Key; +import org.jetbrains.annotations.Nullable; -public class ItemNameModifier implements ItemDataModifier { +public class ItemNameModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final String argument; public ItemNameModifier(String argument) { this.argument = argument; } + public String itemName() { + return argument; + } + @Override - public String name() { - return "item-name"; + public Key type() { + return ItemDataModifiers.ITEM_NAME; } @Override @@ -28,22 +32,26 @@ public class ItemNameModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.ITEM_NAME); - if (previous != null) { - networkData.put(ComponentKeys.ITEM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.ITEM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("display", "Name"); - if (previous != null) { - networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.ITEM_NAME; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"display", "Name"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "display.Name"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + String name = arg.toString(); + return new ItemNameModifier<>(name); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/JukeboxSongModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/JukeboxSongModifier.java index 6ccd1ec12..7702865f6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/JukeboxSongModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/JukeboxSongModifier.java @@ -2,18 +2,25 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.data.JukeboxPlayable; +import net.momirealms.craftengine.core.util.Key; public class JukeboxSongModifier implements ItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final JukeboxPlayable song; public JukeboxSongModifier(JukeboxPlayable song) { this.song = song; } + public JukeboxPlayable song() { + return song; + } + @Override - public String name() { - return "jukebox-playable"; + public Key type() { + return ItemDataModifiers.JUKEBOX_PLAYABLE; } @Override @@ -21,4 +28,13 @@ public class JukeboxSongModifier implements ItemDataModifier { item.jukeboxSong(this.song); return item; } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + String song = arg.toString(); + return new JukeboxSongModifier<>(new JukeboxPlayable(song, true)); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/RemoveComponentModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/RemoveComponentModifier.java index 324db069b..a7ffd1c0b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/RemoveComponentModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/RemoveComponentModifier.java @@ -2,7 +2,10 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; @@ -10,19 +13,20 @@ import java.util.Collections; import java.util.List; public class RemoveComponentModifier implements ItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final List arguments; public RemoveComponentModifier(List arguments) { this.arguments = arguments; } - public List arguments() { + public List components() { return Collections.unmodifiableList(this.arguments); } @Override - public String name() { - return "remove-components"; + public Key type() { + return ItemDataModifiers.REMOVE_COMPONENTS; } @Override @@ -43,4 +47,13 @@ public class RemoveComponentModifier implements ItemDataModifier { } return item; } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + List data = MiscUtils.getAsStringList(arg); + return new RemoveComponentModifier<>(data); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/SimpleNetworkItemDataModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/SimpleNetworkItemDataModifier.java new file mode 100644 index 000000000..2d5664ff0 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/SimpleNetworkItemDataModifier.java @@ -0,0 +1,61 @@ +package net.momirealms.craftengine.core.item.modifier; + +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.sparrow.nbt.CompoundTag; +import net.momirealms.sparrow.nbt.Tag; +import org.jetbrains.annotations.Nullable; + +public interface SimpleNetworkItemDataModifier extends ItemDataModifier { + + @Override + default Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { + if (VersionHelper.COMPONENT_RELEASE) { + Key componentType= componentType(item, context); + if (componentType != null) { + Tag previous = item.getSparrowNBTComponent(componentType); + if (previous != null) { + networkData.put(componentType.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); + } else { + networkData.put(componentType.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + } + } + } else { + Object[] path = nbtPath(item, context); + if (path != null) { + Tag previous = item.getTag(path); + if (previous != null) { + networkData.put(nbtPathString(item, context), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); + } else { + networkData.put(nbtPathString(item, context), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + } + } + } + return item; + } + + @Nullable + default Key componentType(Item item, ItemBuildContext context) { + return null; + } + + @Nullable + default Object[] nbtPath(Item item, ItemBuildContext context) { + return null; + } + + default String nbtPathString(Item item, ItemBuildContext context) { + Object[] path = nbtPath(item, context); + if (path != null && path.length > 0) { + StringBuilder builder = new StringBuilder(); + for (Object object : path) { + builder.append(object.toString()); + } + return builder.toString(); + } + return ""; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TagsModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TagsModifier.java index 16a8ec444..6995c87a2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TagsModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TagsModifier.java @@ -1,12 +1,7 @@ package net.momirealms.craftengine.core.item.modifier; -import net.momirealms.craftengine.core.item.ComponentKeys; -import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; -import net.momirealms.craftengine.core.util.MiscUtils; -import net.momirealms.craftengine.core.util.TypeUtils; -import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.craftengine.core.item.*; +import net.momirealms.craftengine.core.util.*; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; @@ -14,19 +9,20 @@ import java.util.LinkedHashMap; import java.util.Map; public class TagsModifier implements ItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final Map arguments; public TagsModifier(Map arguments) { this.arguments = mapToMap(arguments); } - public Map arguments() { + public Map tags() { return arguments; } @Override - public String name() { - return "tags"; + public Key type() { + return ItemDataModifiers.TAGS; } @Override @@ -135,4 +131,12 @@ public class TagsModifier implements ItemDataModifier { private record ParsedValue(boolean success, Object result) { static final ParsedValue FAILURE = new ParsedValue(false, null); } + + public static class Factory implements ItemDataModifierFactory { + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "nbt"); + return new TagsModifier<>(data); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TooltipStyleModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TooltipStyleModifier.java index ac3a38114..573c484f5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TooltipStyleModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TooltipStyleModifier.java @@ -3,21 +3,25 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import org.jetbrains.annotations.Nullable; -public class TooltipStyleModifier implements ItemDataModifier { +public class TooltipStyleModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final Key argument; public TooltipStyleModifier(Key argument) { this.argument = argument; } + public Key tooltipStyle() { + return this.argument; + } + @Override - public String name() { - return "tooltip-style"; + public Key type() { + return ItemDataModifiers.TOOLTIP_STYLE; } @Override @@ -27,13 +31,16 @@ public class TooltipStyleModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.TOOLTIP_STYLE); - if (previous != null) { - networkData.put(ComponentKeys.TOOLTIP_STYLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.TOOLTIP_STYLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.TOOLTIP_STYLE; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + String id = arg.toString(); + return new TooltipStyleModifier<>(Key.of(id)); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java index 3a5a32a56..82c7a537e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java @@ -3,14 +3,17 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.data.Trim; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; -public class TrimModifier implements ItemDataModifier { +import java.util.Locale; +import java.util.Map; + +public class TrimModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final Key material; private final Key pattern; @@ -19,34 +22,47 @@ public class TrimModifier implements ItemDataModifier { this.pattern = pattern; } + public Key material() { + return material; + } + + public Key pattern() { + return pattern; + } + @Override - public String name() { - return "trim"; + public Key type() { + return ItemDataModifiers.TRIM; } @Override public Item apply(Item item, ItemBuildContext context) { - item.trim(new Trim(this.pattern, this.material)); - return item; + return item.trim(new Trim(this.pattern, this.material)); } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.TRIM); - if (previous != null) { - networkData.put(ComponentKeys.TRIM.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.TRIM.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("Trim"); - if (previous != null) { - networkData.put("Trim", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("Trim", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.TRIM; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"Trim"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "Trim"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + Map data = ResourceConfigUtils.getAsMap(arg, "trim"); + String material = data.get("material").toString().toLowerCase(Locale.ENGLISH); + String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH); + return new TrimModifier<>(Key.of(material), Key.of(pattern)); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/UnbreakableModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/UnbreakableModifier.java index b1be281a0..e2799c35e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/UnbreakableModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/UnbreakableModifier.java @@ -3,21 +3,26 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; -public class UnbreakableModifier implements ItemDataModifier { +public class UnbreakableModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); private final boolean argument; public UnbreakableModifier(boolean argument) { this.argument = argument; } + public boolean unbreakable() { + return argument; + } + @Override - public String name() { - return "unbreakable"; + public Key type() { + return ItemDataModifiers.UNBREAKABLE; } @Override @@ -27,22 +32,26 @@ public class UnbreakableModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.UNBREAKABLE); - if (previous != null) { - networkData.put(ComponentKeys.UNBREAKABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.UNBREAKABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("Unbreakable"); - if (previous != null) { - networkData.put("Unbreakable", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("Unbreakable", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.UNBREAKABLE; + } + + @Override + public @Nullable Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"Unbreakable"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "Unbreakable"; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + boolean value = ResourceConfigUtils.getAsBoolean(arg, "unbreakable"); + return new UnbreakableModifier<>(value); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/DynamicLoreModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/DynamicLoreModifier.java index 5f36228d8..8f60c4cca 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/DynamicLoreModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/DynamicLoreModifier.java @@ -3,16 +3,18 @@ package net.momirealms.craftengine.core.item.modifier.lore; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.craftengine.core.item.modifier.ItemDataModifiers; +import net.momirealms.craftengine.core.item.modifier.SimpleNetworkItemDataModifier; +import net.momirealms.craftengine.core.util.Key; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; -public final class DynamicLoreModifier implements ItemDataModifier { +public final class DynamicLoreModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); public static final String CONTEXT_TAG_KEY = "craftengine:display_context"; private final Map> displayContexts; private final LoreModifier defaultModifier; @@ -27,8 +29,8 @@ public final class DynamicLoreModifier implements ItemDataModifier { } @Override - public String name() { - return "dynamic-lore"; + public Key type() { + return ItemDataModifiers.DYNAMIC_LORE; } @Override @@ -42,22 +44,30 @@ public final class DynamicLoreModifier implements ItemDataModifier { } @Override - public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.LORE); - if (previous != null) { - networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } - } else { - Tag previous = item.getTag("display", "Lore"); - if (previous != null) { - networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - } else { - networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + public Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.LORE; + } + + @Override + public Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"display", "Lore"}; + } + + @Override + public String nbtPathString(Item item, ItemBuildContext context) { + return "display.Lore"; + } + + public static class Factory implements ItemDataModifierFactory { + @Override + public ItemDataModifier create(Object arg) { + Map> dynamicLore = new LinkedHashMap<>(); + if (arg instanceof Map map) { + for (Map.Entry entry : map.entrySet()) { + dynamicLore.put(entry.getKey().toString(), LoreModifier.createLoreModifier(entry.getValue())); + } } + return new DynamicLoreModifier<>(dynamicLore); } - return item; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/LoreModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/LoreModifier.java index 8e998115d..6e5f3411a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/LoreModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/lore/LoreModifier.java @@ -4,37 +4,51 @@ import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; +import net.momirealms.craftengine.core.item.modifier.ItemDataModifiers; +import net.momirealms.craftengine.core.item.modifier.SimpleNetworkItemDataModifier; +import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.ResourceConfigUtils; -import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.sparrow.nbt.CompoundTag; -import net.momirealms.sparrow.nbt.Tag; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.stream.Stream; -public sealed interface LoreModifier extends ItemDataModifier +public sealed interface LoreModifier extends SimpleNetworkItemDataModifier permits LoreModifier.EmptyLoreModifier, LoreModifier.CompositeLoreModifier, LoreModifier.DoubleLoreModifier, LoreModifier.SingleLoreModifier { + Factory FACTORY = new Factory<>(); @Override - default String name() { - return "lore"; + default Key type() { + return ItemDataModifiers.LORE; } @Override - default Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - if (VersionHelper.isOrAbove1_20_5()) { - Tag previous = item.getSparrowNBTComponent(ComponentKeys.LORE); - if (previous != null) networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - else networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); - } else { - Tag previous = item.getTag("display", "Lore"); - if (previous != null) networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); - else networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE)); + @Nullable + default Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.LORE; + } + + @Override + @Nullable + default Object[] nbtPath(Item item, ItemBuildContext context) { + return new Object[]{"display", "Lore"}; + } + + @Override + default String nbtPathString(Item item, ItemBuildContext context) { + return "display.Lore"; + } + + List lore(); + + class Factory implements ItemDataModifierFactory { + @Override + public ItemDataModifier create(Object arg) { + return createLoreModifier(arg); } - return item; } static LoreModifier createLoreModifier(Object arg) { @@ -78,6 +92,11 @@ public sealed interface LoreModifier extends ItemDataModifier public Item apply(Item item, ItemBuildContext context) { return item; } + + @Override + public List lore() { + return List.of(); + } } non-sealed class SingleLoreModifier implements LoreModifier { @@ -92,6 +111,11 @@ public sealed interface LoreModifier extends ItemDataModifier item.loreComponent(this.modification.parseAsList(context)); return item; } + + @Override + public List lore() { + return List.of(modification); + } } non-sealed class DoubleLoreModifier implements LoreModifier { @@ -108,6 +132,11 @@ public sealed interface LoreModifier extends ItemDataModifier item.loreComponent(this.modification2.apply(this.modification1.apply(Stream.empty(), context), context).toList()); return item; } + + @Override + public List lore() { + return List.of(modification1, modification2); + } } non-sealed class CompositeLoreModifier implements LoreModifier { @@ -122,5 +151,10 @@ public sealed interface LoreModifier extends ItemDataModifier item.loreComponent(Arrays.stream(this.modifications).reduce(Stream.empty(), (stream, modification) -> modification.apply(stream, context), Stream::concat).toList()); return item; } + + @Override + public List lore() { + return Arrays.asList(modifications); + } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java index ea35480b2..0afc9ab64 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java @@ -4,7 +4,6 @@ import net.momirealms.craftengine.core.item.BuildableItem; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; -import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Registries; import net.momirealms.craftengine.core.registry.WritableRegistry; @@ -33,9 +32,8 @@ public record CustomRecipeResult(BuildableItem item, int count, PostProces registerPostProcessorType(Key.of("apply_data"), args -> { List> modifiers = new ArrayList<>(); for (Map.Entry entry : args.entrySet()) { - Optional.ofNullable(CraftEngine.instance().itemManager().getDataType(entry.getKey())).ifPresent(it -> { - modifiers.add(it.apply(entry.getValue())); - }); + Optional.ofNullable(BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY.getValue(Key.withDefaultNamespace(entry.getKey(), "craftengine"))) + .ifPresent(factory -> modifiers.add(factory.create(entry.getValue()))); } return new ApplyItemDataProcessor<>(modifiers.toArray(new ItemDataModifier[0])); }); 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 f8bb24094..478d3e5bd 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 @@ -591,11 +591,7 @@ public abstract class AbstractPackManager implements PackManager { } } } catch (LocalizedException e) { - if (e instanceof LocalizedResourceConfigException exception) { - exception.setPath(cached.filePath()); - exception.setId(cached.prefix() + "." + key); - } - TranslationManager.instance().log(e.node(), e.arguments()); + printWarningRecursively(e, cached.filePath(), cached.prefix() + "." + key); } catch (Exception e) { this.plugin.logger().warn("Unexpected error loading file " + cached.filePath() + " - '" + parser.sectionId()[0] + "." + key + "'. Please find the cause according to the stacktrace or seek developer help. Additional info: " + GsonHelper.get().toJson(configEntry.getValue()), e); } @@ -607,6 +603,19 @@ public abstract class AbstractPackManager implements PackManager { } } + private void printWarningRecursively(LocalizedException e, Path path, String prefix) { + for (Throwable t : e.getSuppressed()) { + if (t instanceof LocalizedException suppressed) { + printWarningRecursively(suppressed, path, prefix); + } + } + if (e instanceof LocalizedResourceConfigException exception) { + exception.setPath(path); + exception.setId(prefix); + } + TranslationManager.instance().log(e.node(), e.arguments()); + } + private void processConfigEntry(Map.Entry entry, Path path, Pack pack, BiConsumer callback) { if (entry.getValue() instanceof Map typeSections0) { String key = entry.getKey(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/FixedNumberProvider.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/FixedNumberProvider.java index b4662a547..d636f5268 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/FixedNumberProvider.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/FixedNumberProvider.java @@ -31,6 +31,10 @@ public class FixedNumberProvider implements NumberProvider { return NumberProviders.FIXED; } + public static FixedNumberProvider of(final double value) { + return new FixedNumberProvider(value); + } + public static class FactoryImpl implements NumberProviderFactory { @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java b/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java index a88ef798b..a864ca257 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java +++ b/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java @@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.block.properties.PropertyFactory; import net.momirealms.craftengine.core.entity.furniture.HitBoxFactory; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory; import net.momirealms.craftengine.core.item.equipment.EquipmentFactory; import net.momirealms.craftengine.core.item.recipe.CustomRecipeResult; @@ -42,6 +43,7 @@ import net.momirealms.craftengine.core.util.ResourceKey; public class BuiltInRegistries { public static final Registry BLOCK = createDynamicBoundRegistry(Registries.BLOCK); public static final Registry BLOCK_BEHAVIOR_FACTORY = createConstantBoundRegistry(Registries.BLOCK_BEHAVIOR_FACTORY); + public static final Registry> ITEM_DATA_MODIFIER_FACTORY = createConstantBoundRegistry(Registries.ITEM_DATA_MODIFIER_FACTORY); public static final Registry ITEM_BEHAVIOR_FACTORY = createConstantBoundRegistry(Registries.ITEM_BEHAVIOR_FACTORY); public static final Registry PROPERTY_FACTORY = createConstantBoundRegistry(Registries.PROPERTY_FACTORY); public static final Registry> LOOT_FUNCTION_FACTORY = createConstantBoundRegistry(Registries.LOOT_FUNCTION_FACTORY); diff --git a/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java b/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java index 382277302..fe447e488 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java +++ b/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java @@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.block.properties.PropertyFactory; import net.momirealms.craftengine.core.entity.furniture.HitBoxFactory; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory; import net.momirealms.craftengine.core.item.equipment.EquipmentFactory; import net.momirealms.craftengine.core.item.recipe.CustomRecipeResult; @@ -43,6 +44,7 @@ import net.momirealms.craftengine.core.util.ResourceKey; public class Registries { public static final Key ROOT_REGISTRY = Key.withDefaultNamespace("root"); public static final ResourceKey> BLOCK = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("block")); + public static final ResourceKey>> ITEM_DATA_MODIFIER_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_data_modifier_factory")); public static final ResourceKey> PROPERTY_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("property_factory")); public static final ResourceKey> BLOCK_BEHAVIOR_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("block_behavior_factory")); public static final ResourceKey> ITEM_BEHAVIOR_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_behavior_factory")); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ExceptionCollector.java b/core/src/main/java/net/momirealms/craftengine/core/util/ExceptionCollector.java index 868df2a03..f7a678862 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ExceptionCollector.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ExceptionCollector.java @@ -19,5 +19,10 @@ public class ExceptionCollector { throw this.result; } } + + public void addAndThrow(T throwable) throws T { + this.add(throwable); + this.throwIfPresent(); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java index dfdaa4317..d0d69ebc7 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java @@ -204,4 +204,12 @@ public final class ResourceConfigUtils { } } } + + @SuppressWarnings("unchecked") + public static Map getAsMap(Object obj, String option) { + if (obj instanceof Map map) { + return (Map) map; + } + throw new LocalizedResourceConfigException("warning.config.type.map", String.valueOf(obj), option); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java b/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java index 3890ad838..0c003a3eb 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java @@ -9,6 +9,7 @@ import java.nio.charset.StandardCharsets; public class VersionHelper { public static final boolean PREMIUM = true; public static final MinecraftVersion MINECRAFT_VERSION; + public static final boolean COMPONENT_RELEASE; private static final int version; private static final int majorVersion; private static final int minorVersion; @@ -71,6 +72,8 @@ public class VersionHelper { majorVersion = major; minorVersion = minor; + COMPONENT_RELEASE = v1_20_5; + mojmap = checkMojMap(); folia = checkFolia(); paper = checkPaper(); diff --git a/gradle.properties b/gradle.properties index 829302ea9..9424ed38f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.60.8 +project_version=0.0.60.9 config_version=43 -lang_version=22 +lang_version=23 project_group=net.momirealms latest_supported_version=1.21.8