diff --git a/MMOItems-API/pom.xml b/MMOItems-API/pom.xml index ca9ffc5f..c8fc8f22 100644 --- a/MMOItems-API/pom.xml +++ b/MMOItems-API/pom.xml @@ -63,12 +63,6 @@ https://s01.oss.sonatype.org/content/repositories/snapshots/ - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - codemc-repo @@ -316,7 +310,7 @@ me.arasple.mc TrHologram - 1.11 + 2.2 provided true diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java index 00a64e42..60dbc5c8 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java @@ -27,6 +27,7 @@ public class ItemStats { LORE = new Lore(), NBT_TAGS = new NBTTags(), MAX_STACK_SIZE = new MaxStackSize(), + CAN_BREAK = new CanBreak(), LORE_FORMAT = new LoreFormat(), TOOLTIP = new TooltipStat(), @@ -110,9 +111,9 @@ public class ItemStats { UNBREAKABLE = new Unbreakable(), TIER = new ItemTierStat(), SET = new ItemSetStat(), - ARMOR = new DoubleStat("ARMOR", Material.GOLDEN_CHESTPLATE, "护甲", new String[]{"赋予持有者的护甲值"}), - ARMOR_TOUGHNESS = new DoubleStat("ARMOR_TOUGHNESS", Material.DIAMOND_CHESTPLATE, "护甲韧性", new String[]{"护甲韧性可减少所受的伤害"}), - MAX_HEALTH = new DoubleStat("MAX_HEALTH", Material.GOLDEN_APPLE, "最大生命值", new String[]{"物品赋予持有者的额外生命值"}), + ARMOR = new Armor(), + ARMOR_TOUGHNESS = new ArmorToughness(), + MAX_HEALTH = new MaxHealth(), UNSTACKABLE = new Unstackable(), MAX_MANA = new DoubleStat("MAX_MANA", Material.LAPIS_LAZULI, "最大法力值", new String[]{"增加最大法力值的魔力"}), KNOCKBACK_RESISTANCE = new KnockbackResistance(), @@ -133,6 +134,15 @@ public class ItemStats { SAFE_FALL_DISTANCE = new SafeFallDistance(), SCALE = new Scale(), STEP_HEIGHT = new StepHeight(), + BURNING_TIME = new BurningTime(), + EXPLOSION_KNOCKBACK_RESISTANCE = new ExplosionKnockbackResistance(), + MINING_EFFICIENCY = new MiningEfficiency(), + MOVEMENT_EFFICIENCY = new MovementEfficiency(), + OXYGEN_BONUS = new OxygenBonus(), + SNEAKING_SPEED = new SneakingSpeed(), + SUBMERGED_MINING_SPEED = new SubmergedMiningSpeed(), + SWEEPING_DAMAGE_RATIO = new SweepingDamageRatio(), + WATER_MOVEMENT_EFFICIENCY = new WaterMovementEfficiency(), // Permanent Effects PERM_EFFECTS = new PermanentEffects(), diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java index 2496b1f3..13ce8ad1 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java @@ -127,7 +127,7 @@ public void onLoad() { saveDefaultConfig(); configManager = new ConfigManager(); - statManager.loadInternalStats(); + statManager.loadBuiltins(); typeManager.reload(false); templateManager.preloadObjects(); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java index 55e239e8..c5a39e65 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java @@ -33,8 +33,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.function.Consumer; import java.util.logging.Level; +// TODO getItemMeta, asNMSCopy = two clones. could be done with NO clone, simply initializing item with proper interfacing public class ItemStackBuilder { @NotNull private final MMOItem mmoitem; @@ -44,6 +46,12 @@ public class ItemStackBuilder { private final LoreBuilder lore; private final List tags = new ArrayList<>(); + /** + * @deprecated Temp fix before MI7 + */ + @Deprecated + private List> futureActions; + private static final AttributeModifier FAKE_MODIFIER = VersionUtils.attrMod(new NamespacedKey(MMOItems.plugin, "decoy"), 0, Operation.ADD_NUMBER); /** @@ -97,6 +105,15 @@ public ItemMeta getMeta() { return meta; } + /** + * @deprecated Temp fix before MI7 + */ + @Deprecated + public void addFutureAction(Consumer action) { + if (futureActions == null) futureActions = new ArrayList<>(); + futureActions.add(action); + } + public void addItemTag(List newTags) { tags.addAll(newTags); } @@ -241,7 +258,10 @@ public NBTItem buildNBT(boolean forDisplay) { item.setItemMeta(meta); - return NBTItem.get(item).addTag(tags); + NBTItem nbt = NBTItem.get(item).addTag(tags); + if (futureActions != null) futureActions.forEach(a -> a.accept(nbt)); + + return nbt; } /** diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/ItemBrowser.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/ItemBrowser.java index e20b2927..96355249 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/ItemBrowser.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/ItemBrowser.java @@ -5,6 +5,7 @@ import io.lumine.mythic.lib.api.util.AltChar; import io.lumine.mythic.lib.api.util.ui.SilentNumbers; import io.lumine.mythic.lib.util.AdventureUtils; +import io.lumine.mythic.lib.version.VersionUtils; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.edition.NewItemEdition; @@ -13,6 +14,7 @@ import net.Indyuce.mmoitems.stat.BrowserDisplayIDX; import net.Indyuce.mmoitems.util.MMOUtils; import org.bukkit.*; +import org.bukkit.attribute.Attribute; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; @@ -86,6 +88,7 @@ public Inventory getInventory() { final ItemStack item = currentType.getItem(); item.setAmount(Math.max(1, Math.min(64, items))); ItemMeta meta = item.getItemMeta(); + if (MythicLib.plugin.getVersion().isAbove(1, 20, 5)) VersionUtils.addEmptyAttributeModifier(meta); AdventureUtils.setDisplayName(meta, String.format("&a%s&8 (点击浏览)", currentType.getName())); meta.addItemFlags(ItemFlag.values()); List lore = new ArrayList<>(); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/edition/ItemEdition.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/edition/ItemEdition.java index eb4ba28a..03caed19 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/edition/ItemEdition.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/edition/ItemEdition.java @@ -1,6 +1,7 @@ package net.Indyuce.mmoitems.gui.edition; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.version.VersionUtils; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.stat.type.InternalStat; @@ -23,7 +24,7 @@ public class ItemEdition extends EditionInventory { private static final int[] slots = {19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43}; - private static final NamespacedKey STAT_ID_KEY = new NamespacedKey(MMOItems.plugin,"StatId"); + private static final NamespacedKey STAT_ID_KEY = new NamespacedKey(MMOItems.plugin, "StatId"); public ItemEdition(Player player, MMOItemTemplate template) { super(player, template); @@ -52,9 +53,14 @@ public void arrangeInventory() { ItemStack item = new ItemStack(stat.getDisplayMaterial()); ItemMeta meta = item.getItemMeta(); meta.addItemFlags(ItemFlag.values()); + VersionUtils.addEmptyAttributeModifier(meta); meta.setDisplayName(ChatColor.GREEN + stat.getName()); List lore = MythicLib.plugin.parseColors(Arrays.stream(stat.getLore()).map(s -> ChatColor.GRAY + s).collect(Collectors.toList())); lore.add(""); + if (stat.getCategory() != null) { + lore.add(0, ""); + lore.add(0, ChatColor.BLUE + stat.getCategory().getLoreTag()); + } stat.whenDisplayed(lore, getEventualStatData(stat)); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/StatManager.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/StatManager.java index 03a79af6..6093b1ce 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/StatManager.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/StatManager.java @@ -1,12 +1,15 @@ package net.Indyuce.mmoitems.manager; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.element.Element; import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.ConfigFile; import net.Indyuce.mmoitems.api.Type; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.category.StatCategory; import net.Indyuce.mmoitems.stat.type.*; import net.Indyuce.mmoitems.util.ElementStatType; import org.apache.commons.lang.Validate; @@ -23,13 +26,14 @@ public class StatManager { private final Map> stats = new LinkedHashMap<>(); + private final Map categories = new HashMap<>(); /** * If, for whatever reason, a stat needs to change its internal * string ID, this map keeps a reference for the deprecated old * IDs while being separated from the main ItemStat map. */ - @BackwardsCompatibility(version = "unknown") + @BackwardsCompatibility(version = "not_specified") private final Map> legacyAliases = new HashMap<>(); /* @@ -37,8 +41,8 @@ public class StatManager { * the first time to make their access easier. Check the classes * individually to understand better */ - private final List numeric = new ArrayList<>(); - private final List itemRestriction = new ArrayList<>(); + private final List numericStats = new ArrayList<>(); + private final List itemRestrictions = new ArrayList<>(); private final List consumableActions = new ArrayList<>(); private final List playerConsumables = new ArrayList<>(); @@ -46,10 +50,25 @@ public class StatManager { * Load default stats using java reflection, get all public static final * fields in the ItemStat and register them as stat instances */ - public void loadInternalStats() { + public void loadBuiltins() { + + // Builtin categories + for (Field field : StatCategory.class.getFields()) + try { + if (Modifier.isStatic(field.getModifiers()) + && Modifier.isFinal(field.getModifiers()) + && field.get(null) instanceof StatCategory) + registerCategory((StatCategory) field.get(null)); + } catch (IllegalArgumentException | IllegalAccessException exception) { + MMOItems.plugin.getLogger().log(Level.SEVERE, String.format("Couldn't register category called '%s'", field.getName()), exception.getMessage()); + } + + // Load builtin stats for (Field field : ItemStats.class.getFields()) try { - if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && field.get(null) instanceof ItemStat) + if (Modifier.isStatic(field.getModifiers()) + && Modifier.isFinal(field.getModifiers()) + && field.get(null) instanceof ItemStat) register((ItemStat) field.get(null)); } catch (IllegalArgumentException | IllegalAccessException exception) { MMOItems.plugin.getLogger().log(Level.SEVERE, String.format("Couldn't register stat called '%s'", field.getName()), exception.getMessage()); @@ -64,7 +83,7 @@ public void reload(boolean cleanFirst) { // Clean fictive numeric stats before if (cleanFirst) - numeric.removeIf(stat -> stat instanceof FictiveNumericStat); // temporary fix, this is for elements. + numericStats.removeIf(stat -> stat instanceof FakeElementalStat); // temporary fix, this is for elements TODO improve // Register elemental stats loadElements(); @@ -100,7 +119,16 @@ private void loadCustomStats() { public void loadElements() { for (ElementStatType type : ElementStatType.values()) for (Element element : MythicLib.plugin.getElements().getAll()) - numeric.add(new FictiveNumericStat(element, type)); + numericStats.add(new FakeElementalStat(element, type)); + } + + public void registerCategory(@NotNull StatCategory category) { + categories.put(category.getId(), category); + } + + @NotNull + public StatCategory getCategory(@NotNull String id) { + return Objects.requireNonNull(categories.get(id), "No stat category found with ID '" + id + "'"); } @NotNull @@ -116,7 +144,7 @@ public void loadElements() { */ @NotNull public List getNumericStats() { - return numeric; + return numericStats; } /** @@ -125,7 +153,7 @@ public List getNumericStats() { */ @NotNull public List getItemRestrictionStats() { - return itemRestriction; + return itemRestrictions; } /** @@ -158,7 +186,7 @@ public boolean has(String id) { if (stat != null) return stat; // Numeric registry (see to-do) - stat = numeric.stream().filter(doubleStat -> doubleStat.getId().equals(id)).findFirst().orElse(null); + stat = numericStats.stream().filter(doubleStat -> doubleStat.getId().equals(id)).findFirst().orElse(null); if (stat != null) return stat; // Legacy liases @@ -169,16 +197,6 @@ public boolean has(String id) { return null; } - /** - * @deprecated Stat IDs are now stored in the stat instance directly. - * Please use StatManager#register(ItemStat) instead - */ - @Deprecated - @SuppressWarnings("unused") - public void register(String id, ItemStat stat) { - register(stat); - } - /** * Registers a stat in MMOItems. It must be done right after MMOItems loads * before any manager is initialized because stats are commonly used when @@ -187,34 +205,30 @@ public void register(String id, ItemStat stat) { * @param stat The stat to register */ public void register(@NotNull ItemStat stat) { - register(stat, false); - } - - private void register(@NotNull ItemStat stat, boolean customStat) { // Skip disabled stats. if (!stat.isEnabled()) return; - // Safe check, this can happen with numerous extra RPG plugins - if (stats.containsKey(stat.getId())) { - MMOItems.plugin.getLogger().log(Level.SEVERE, "Could not register stat '" + stat.getId() + "' as a stat with the same ID already exists."); - return; - } + // Register stat + stats.compute(stat.getId(), (id, current) -> { + Validate.isTrue(current == null, "A stat with ID '" + id + "' already exists"); + return stat; + }); - // Main registry - stats.put(stat.getId(), stat); - - // Register aliases - for (String alias : stat.getAliases()) - legacyAliases.put(alias, stat); + // Register aliases (backwards compatibility) + for (String alias : stat.getAliases()) legacyAliases.put(alias, stat); // Use-case specific registries if (stat instanceof DoubleStat && !(stat instanceof GemStoneStat) && stat.isCompatible(Type.GEM_STONE)) - numeric.add((DoubleStat) stat); - if (stat instanceof ItemRestriction) itemRestriction.add((ItemRestriction) stat); + numericStats.add((DoubleStat) stat); + if (stat instanceof ItemRestriction) itemRestrictions.add((ItemRestriction) stat); if (stat instanceof ConsumableItemInteraction) consumableActions.add((ConsumableItemInteraction) stat); if (stat instanceof PlayerConsumable) playerConsumables.add((PlayerConsumable) stat); + // Stat category + HasCategory statCatAnnot = stat.getClass().getAnnotation(HasCategory.class); + if (statCatAnnot != null) stat.setCategory(getCategory(UtilityMethods.enumName(statCatAnnot.cat()))); + /* * Cache stat for every type which may have this stat. Really important * otherwise the stat will NOT be used anywhere in the plugin. This @@ -268,4 +282,22 @@ private void registerCustomStat(@NotNull ConfigurationSection section) { throw new RuntimeException("Unable to create a custom stat of type " + type, e); } } + + /** + * @see #register(ItemStat) + * @deprecated Stat IDs are now stored in the stat instance directly. + */ + @Deprecated + @SuppressWarnings("unused") + public void register(@Nullable String id, @NotNull ItemStat stat) { + register(stat); + } + + /** + * @see #loadBuiltins() + */ + @Deprecated + public void loadInternalStats() { + loadBuiltins(); + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Armor.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Armor.java new file mode 100644 index 00000000..5b07682e --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Armor.java @@ -0,0 +1,15 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +public class Armor extends DoubleStat { + public Armor() { + super("ARMOR", + Material.GOLDEN_CHESTPLATE, + "盔甲值", + "给予持有者的护甲值。"); + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ArmorToughness.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ArmorToughness.java new file mode 100644 index 00000000..324264e3 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ArmorToughness.java @@ -0,0 +1,15 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +public class ArmorToughness extends DoubleStat { + public ArmorToughness() { + super("ARMOR_TOUGHNESS", + Material.DIAMOND_CHESTPLATE, + "盔甲韧性", + "护甲韧性减少所受的伤害"); + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackDamage.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackDamage.java index 3e3e81c8..a186aadf 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackDamage.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackDamage.java @@ -1,12 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.AttackWeaponStat; import org.bukkit.Material; import org.bukkit.attribute.Attribute; +@HasCategory(cat = "vanilla_attribute") public class AttackDamage extends AttackWeaponStat { - public AttackDamage() { - super("ATTACK_DAMAGE", Material.IRON_SWORD, "攻击伤害", new String[] { "你的武器造成的伤害量" }, - Attribute.GENERIC_ATTACK_DAMAGE); - } + public AttackDamage() { + super("ATTACK_DAMAGE", + Material.IRON_SWORD, + "攻击伤害", + new String[]{"你的武器造成的伤害量"}, + Attribute.GENERIC_ATTACK_DAMAGE); + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackSpeed.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackSpeed.java index 7a328bae..92262dc8 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackSpeed.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/AttackSpeed.java @@ -1,12 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.AttackWeaponStat; import org.bukkit.Material; import org.bukkit.attribute.Attribute; +@HasCategory(cat = "vanilla_attribute") public class AttackSpeed extends AttackWeaponStat { - public AttackSpeed() { - super("ATTACK_SPEED", Material.LIGHT_GRAY_DYE, "攻击速度", - new String[] { "武器的攻击速度 攻击/秒" }, Attribute.GENERIC_ATTACK_SPEED); - } + public AttackSpeed() { + super("ATTACK_SPEED", + Material.LIGHT_GRAY_DYE, + "攻击速度", + new String[]{"武器的攻击速度 攻击/秒"}, + Attribute.GENERIC_ATTACK_SPEED); + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockBreakSpeed.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockBreakSpeed.java index c8bcad61..e8599c9a 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockBreakSpeed.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockBreakSpeed.java @@ -1,13 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class BlockBreakSpeed extends DoubleStat { public BlockBreakSpeed() { - super("BLOCK_BREAK_SPEED", Material.IRON_PICKAXE, - "挖掘速度", new String[]{"方块破坏速度", "空手时挖掘速度默认为 1"}); + super("BLOCK_BREAK_SPEED", + Material.IRON_PICKAXE, + "挖掘速度", + "方块破坏速度,空手时挖掘速度默认为 1"); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockInteractionRange.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockInteractionRange.java index 862ede61..68849fb6 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockInteractionRange.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BlockInteractionRange.java @@ -1,13 +1,17 @@ package net.Indyuce.mmoitems.stat; import io.lumine.mythic.lib.version.VMaterial; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class BlockInteractionRange extends DoubleStat { public BlockInteractionRange() { - super("BLOCK_INTERACTION_RANGE", VMaterial.SPYGLASS.get(), - "方块交互距离", new String[]{"打破方块或与方块交互的距离。", "在创造模式下默认值为 5,", "生存模式下默认值为 4.5"}); + super("BLOCK_INTERACTION_RANGE", + VMaterial.SPYGLASS.get(), + "方块交互距离", + "打破方块或与方块交互的距离。在创造模式下默认值为 5,生存模式下默认值为 4.5"); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BrowserDisplayIDX.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BrowserDisplayIDX.java index 040ee993..edb97a11 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BrowserDisplayIDX.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BrowserDisplayIDX.java @@ -5,6 +5,7 @@ import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.api.util.NumericStatFormula; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.stat.type.DoubleStat; import org.bukkit.Material; @@ -16,6 +17,7 @@ import java.util.HashMap; import java.util.Map; +@HasCategory(cat = "template_option") public class BrowserDisplayIDX extends DoubleStat { public BrowserDisplayIDX() { super("BROWSER_IDX", Material.GHAST_TEAR, "浏览索引", new String[] {"用于在GUI界面,", "mmoitems 浏览器中整齐地 §a/ 将类似的物品显示在一起", "", "将具有相同索引的物品分组"}, new String[0]); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BurningTime.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BurningTime.java new file mode 100644 index 00000000..5a78eb3b --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/BurningTime.java @@ -0,0 +1,23 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import net.Indyuce.mmoitems.util.MMOUtils; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class BurningTime extends DoubleStat { + public BurningTime() { + super("BURNING_TIME", + Material.FIRE_CHARGE, + "点燃时间", + "决定玩家被点燃后保持燃烧时间的系数。系数为0时完全移除燃烧时间,系数为1时实体燃烧默认时间,较大数值会延长实体的燃烧时间。默认值为1,最小值为0,最大值为1024。"); + } + + @Override + public double multiplyWhenDisplaying() { + return 100; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CanBreak.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CanBreak.java new file mode 100644 index 00000000..27625a60 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CanBreak.java @@ -0,0 +1,166 @@ +package net.Indyuce.mmoitems.stat; + +import io.lumine.mythic.lib.UtilityMethods; +import io.lumine.mythic.lib.api.item.ItemTag; +import io.lumine.mythic.lib.api.item.SupportedNBTTagValues; +import io.lumine.mythic.lib.api.util.AltChar; +import io.lumine.mythic.lib.gson.JsonArray; +import io.lumine.mythic.lib.gson.JsonParser; +import io.lumine.mythic.lib.gson.JsonSyntaxException; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.edition.StatEdition; +import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; +import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; +import net.Indyuce.mmoitems.gui.edition.EditionInventory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.data.StringListData; +import net.Indyuce.mmoitems.stat.data.type.StatData; +import net.Indyuce.mmoitems.stat.type.ItemStat; +import org.apache.commons.lang.Validate; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@VersionDependant(version = {1, 20, 6}) +public class CanBreak extends ItemStat { + public CanBreak() { + super("CAN_BREAK", + Material.IRON_PICKAXE, + "可破坏列表", + new String[]{"此物品可以破坏的材料列表。该限制仅适用于冒险模式。"}, + new String[]{"tool"}); + } + + @Override + @SuppressWarnings("unchecked") + public StringListData whenInitialized(Object object) { + Validate.isTrue(object instanceof List, "必须指定一个字符串列表。"); + return new StringListData((List) object); + } + + @Override + public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { + if (event.getAction() == InventoryAction.PICKUP_ALL) + new StatEdition(inv, this).enable("在聊天栏中输入您想要的材料"); + + if (event.getAction() != InventoryAction.PICKUP_HALF || !inv.getEditedSection().contains(getPath())) + return; + + List list = inv.getEditedSection().getStringList(getPath()); + if (list.isEmpty()) return; + + String last = list.removeLast(); + inv.getEditedSection().set(getPath(), list); + inv.registerTemplateEdition(); + inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "成功移除 '" + last + "'."); + } + + @Override + public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) { + List list = inv.getEditedSection().contains(getPath()) ? inv.getEditedSection().getStringList(getPath()) : new ArrayList<>(); + + // Validate material + final Material material = Material.valueOf(UtilityMethods.enumName(message)); + + list.add(material.name()); + inv.getEditedSection().set(getPath(), list); + inv.registerTemplateEdition(); + inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "材料 " + material.name() + " 成功添加"); + } + + @Override + public void whenDisplayed(List lore, Optional statData) { + if (statData.isPresent()) { + lore.add(ChatColor.GRAY + "当前值:"); + statData.get().getList().forEach(str -> lore.add(ChatColor.GRAY + "* " + str)); + } else + lore.add(ChatColor.GRAY + "当前值: " + ChatColor.RED + "无法挖掘任何物品(冒险模式)"); + + lore.add(""); + lore.add(ChatColor.YELLOW + AltChar.listDash + " 左键添加材料"); + lore.add(ChatColor.YELLOW + AltChar.listDash + " 右键删除最后一个材料"); + } + + @NotNull + @Override + public StringListData getClearStatData() { + return new StringListData(); + } + + @Override + public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringListData data) { + List mats = data.getList().stream().map(Material::valueOf).collect(Collectors.toList()); + item.addFutureAction(nbt -> { + nbt.setCanMine(mats); + }); + + item.addItemTag(getAppliedNBT(data)); + } + + @NotNull + @Override + public ArrayList getAppliedNBT(@NotNull StringListData data) { + // Build Json Array + JsonArray array = new JsonArray(); + + // For each string in the ids of the data + for (String sts : data.getList()) { + array.add(sts); + } + + // Make returning array + ArrayList tags = new ArrayList<>(); + + // Add Json Array + tags.add(new ItemTag(getNBTPath(), array.toString())); + + return tags; + } + + @Override + public void whenLoaded(@NotNull ReadMMOItem mmoitem) { + // FInd relevant tags + ArrayList relevantTags = new ArrayList<>(); + if (mmoitem.getNBT().hasTag(getNBTPath())) + relevantTags.add(ItemTag.getTagAtPath(getNBTPath(), mmoitem.getNBT(), SupportedNBTTagValues.STRING)); + + // Generate data + StatData data = getLoadedNBT(relevantTags); + + if (data != null) + mmoitem.setData(this, data); + } + + @Nullable + @Override + public StringListData getLoadedNBT(@NotNull ArrayList storedTags) { + // Find relevant tag + ItemTag rTag = ItemTag.getTagAtPath(getNBTPath(), storedTags); + + // Found? + if (rTag == null) + // Nope + return null; + + try { + // Parse onto Json Array + JsonArray array = new JsonParser().parse((String) rTag.getValue()).getAsJsonArray(); + + // Make and return list + return new StringListData(array); + } catch (JsonSyntaxException | IllegalStateException exception) { + /* + * OLD ITEM WHICH MUST BE UPDATED. + */ + } + return null; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleIds.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleIds.java index b5cdc771..fbaaafff 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleIds.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleIds.java @@ -6,7 +6,6 @@ import io.lumine.mythic.lib.gson.JsonArray; import io.lumine.mythic.lib.gson.JsonParser; import io.lumine.mythic.lib.gson.JsonSyntaxException; -import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.edition.StatEdition; import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; @@ -43,36 +42,35 @@ public StringListData whenInitialized(Object object) { @Override public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { if (event.getAction() == InventoryAction.PICKUP_ALL) - new StatEdition(inv, ItemStats.COMPATIBLE_IDS).enable("在聊天中输入您要添加的物品 ID"); + new StatEdition(inv, this).enable("在聊天中输入您要添加的物品 ID"); - if (event.getAction() != InventoryAction.PICKUP_HALF || !inv.getEditedSection().contains("compatible-ids")) - return; - List lore = inv.getEditedSection().getStringList("compatible-ids"); - if (lore.size() < 1) + if (event.getAction() != InventoryAction.PICKUP_HALF || !inv.getEditedSection().contains(getPath())) return; - String last = lore.get(lore.size() - 1); - lore.remove(last); - inv.getEditedSection().set("compatible-ids", lore); + List lore = inv.getEditedSection().getStringList(getPath()); + if (lore.isEmpty()) return; + + String last = lore.removeLast(); + inv.getEditedSection().set(getPath(), lore); inv.registerTemplateEdition(); inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "成功删除 '" + last + "'"); } @Override public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) { - List lore = inv.getEditedSection().contains("compatible-ids") ? inv.getEditedSection().getStringList("compatible-ids") + List lore = inv.getEditedSection().contains(getPath()) ? inv.getEditedSection().getStringList(getPath()) : new ArrayList<>(); lore.add(message.toUpperCase()); - inv.getEditedSection().set("compatible-ids", lore); + inv.getEditedSection().set(getPath(), lore); inv.registerTemplateEdition(); - inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "已成功添加兼容 ID"); + inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "ID '" + message.toUpperCase() + "' 已成功添加兼容 ID"); } @Override public void whenDisplayed(List lore, Optional statData) { if (statData.isPresent()) { lore.add(ChatColor.GRAY + "Current Value:"); - statData.get().getList().forEach(str -> lore.add(ChatColor.GRAY + str)); + statData.get().getList().forEach(str -> lore.add(ChatColor.GRAY + "* " + str)); } else lore.add(ChatColor.GRAY + "当前值: " + ChatColor.RED + " 与任何物品兼容"); @@ -91,7 +89,7 @@ public StringListData getClearStatData() { public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringListData data) { // Copy Array, for lore List compatibleIds = new ArrayList<>(data.getList()); - item.getLore().insert("compatible-ids", compatibleIds); + item.getLore().insert(getPath(), compatibleIds); // Add data item.addItemTag(getAppliedNBT(data)); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleMaterials.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleMaterials.java index 319b7ca6..0f2044c2 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleMaterials.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleMaterials.java @@ -1,12 +1,12 @@ package net.Indyuce.mmoitems.stat; +import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.api.item.ItemTag; import io.lumine.mythic.lib.api.item.SupportedNBTTagValues; import io.lumine.mythic.lib.api.util.AltChar; import io.lumine.mythic.lib.gson.JsonArray; import io.lumine.mythic.lib.gson.JsonParser; import io.lumine.mythic.lib.gson.JsonSyntaxException; -import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.edition.StatEdition; import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; @@ -18,14 +18,12 @@ import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.Material; -import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -46,43 +44,37 @@ public StringListData whenInitialized(Object object) { @Override public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { if (event.getAction() == InventoryAction.PICKUP_ALL) - new StatEdition(inv, ItemStats.COMPATIBLE_MATERIALS).enable("在聊天中输入您要添加的材料的名称"); + new StatEdition(inv, this).enable("在聊天中输入您要添加的材料的名称"); - if (event.getAction() != InventoryAction.PICKUP_HALF || !inv.getEditedSection().contains("compatible-materials")) - return; - List lore = inv.getEditedSection().getStringList("compatible-materials"); - if (lore.size() < 1) + if (event.getAction() != InventoryAction.PICKUP_HALF || !inv.getEditedSection().contains(getPath())) return; - String last = lore.get(lore.size() - 1); - lore.remove(last); - inv.getEditedSection().set("compatible-materials", lore); + final List lore = inv.getEditedSection().getStringList(getPath()); + if (lore.isEmpty()) return; + + final String last = lore.removeLast(); + inv.getEditedSection().set(getPath(), lore); inv.registerTemplateEdition(); inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "成功删除 '" + last + "'"); } @Override public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) { - final Player player = inv.getPlayer(); - // Check if material exists - if (Arrays.stream(Material.values()).noneMatch(versionMaterial -> versionMaterial.name().equalsIgnoreCase(message))) { - player.sendMessage(MMOItems.plugin.getPrefix() + "材料名称无效"); - return; - } - List lore = inv.getEditedSection().contains("compatible-materials") ? inv.getEditedSection().getStringList("compatible-materials") - : new ArrayList<>(); - lore.add(message.toUpperCase()); - inv.getEditedSection().set("compatible-materials", lore); + Material mat = Material.valueOf(UtilityMethods.enumName(message)); + + List lore = inv.getEditedSection().contains(getPath()) ? inv.getEditedSection().getStringList(getPath()) : new ArrayList<>(); + lore.add(mat.name()); + inv.getEditedSection().set(getPath(), lore); inv.registerTemplateEdition(); - player.sendMessage(MMOItems.plugin.getPrefix() + "已成功添加兼容材料"); + inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "材料 " + mat.name() + " 已成功添加"); } @Override public void whenDisplayed(List lore, Optional statData) { if (statData.isPresent()) { - lore.add(ChatColor.GRAY + "当前值: "); - statData.get().getList().forEach(str -> lore.add(ChatColor.GRAY + str)); + lore.add(ChatColor.GRAY + "当前值:"); + statData.get().getList().forEach(str -> lore.add(ChatColor.GRAY + "* " + str)); } else lore.add(ChatColor.GRAY + "当前值: " + ChatColor.RED + " 与任何材料兼容"); @@ -101,7 +93,7 @@ public StringListData getClearStatData() { public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringListData data) { // Copy Array, for lore List compatibleMaterials = new ArrayList<>(data.getList()); - item.getLore().insert("compatible-materials", compatibleMaterials); + item.getLore().insert(getPath(), compatibleMaterials); // Add data item.addItemTag(getAppliedNBT(data)); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleTypes.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleTypes.java index 6fa219bb..9b36b547 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleTypes.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CompatibleTypes.java @@ -6,7 +6,6 @@ import io.lumine.mythic.lib.gson.JsonArray; import io.lumine.mythic.lib.gson.JsonParser; import io.lumine.mythic.lib.gson.JsonSyntaxException; -import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.edition.StatEdition; import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; @@ -43,36 +42,35 @@ public StringListData whenInitialized(Object object) { @Override public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { if (event.getAction() == InventoryAction.PICKUP_ALL) - new StatEdition(inv, ItemStats.COMPATIBLE_TYPES).enable("在聊天中输入您要添加的类型的名称"); + new StatEdition(inv, this).enable("在聊天中输入您要添加的类型的名称"); - if (event.getAction() != InventoryAction.PICKUP_HALF || !inv.getEditedSection().contains("compatible-types")) - return; - List lore = inv.getEditedSection().getStringList("compatible-types"); - if (lore.size() < 1) + if (event.getAction() != InventoryAction.PICKUP_HALF || !inv.getEditedSection().contains(getPath())) return; - String last = lore.get(lore.size() - 1); - lore.remove(last); - inv.getEditedSection().set("compatible-types", lore); + List lore = inv.getEditedSection().getStringList(getPath()); + if (lore.isEmpty()) return; + + String last = lore.removeLast(); + inv.getEditedSection().set(getPath(), lore); inv.registerTemplateEdition(); inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "成功删除 '" + last + "'"); } @Override public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) { - List lore = inv.getEditedSection().contains("compatible-types") ? inv.getEditedSection().getStringList("compatible-types") + List lore = inv.getEditedSection().contains(getPath()) ? inv.getEditedSection().getStringList(getPath()) : new ArrayList<>(); lore.add(message.toUpperCase()); - inv.getEditedSection().set("compatible-types", lore); + inv.getEditedSection().set(getPath(), lore); inv.registerTemplateEdition(); - inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "已成功添加兼容类型"); + inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "类型 " + message.toUpperCase() + " 已成功添加"); } @Override public void whenDisplayed(List lore, Optional statData) { if (statData.isPresent()) { - lore.add(ChatColor.GRAY + "当前值: "); - statData.get().getList().forEach(str -> lore.add(ChatColor.GRAY + str)); + lore.add(ChatColor.GRAY + "当前值:"); + statData.get().getList().forEach(str -> lore.add(ChatColor.GRAY + "* " + str)); } else lore.add(ChatColor.GRAY + "当前值: " + ChatColor.RED + "与任何物品兼容"); @@ -91,7 +89,7 @@ public StringListData getClearStatData() { public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringListData data) { // Copy Array, for lore List compatibleTypes = new ArrayList<>(data.getList()); - item.getLore().insert("compatible-types", compatibleTypes); + item.getLore().insert(getPath(), compatibleTypes); // Add data item.addItemTag(getAppliedNBT(data)); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/DisplayName.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/DisplayName.java index 47cd63bf..be026eae 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/DisplayName.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/DisplayName.java @@ -24,7 +24,10 @@ public class DisplayName extends StringStat implements GemStoneStat { public DisplayName() { - super("NAME", Material.OAK_SIGN, "显示名称", new String[]{"物品显示名称"}, + super("NAME", + Material.NAME_TAG, + "显示名称", + new String[]{"物品显示名称"}, new String[0]); } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/EntityInteractionRange.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/EntityInteractionRange.java index 2290479c..4e64ed10 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/EntityInteractionRange.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/EntityInteractionRange.java @@ -1,13 +1,18 @@ package net.Indyuce.mmoitems.stat; import io.lumine.mythic.lib.version.VMaterial; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class EntityInteractionRange extends DoubleStat { public EntityInteractionRange() { - super("ENTITY_INTERACTION_RANGE", VMaterial.SPYGLASS.get(), - "生物交互距离", new String[]{"破坏实体或与实体相互作用的距离。", "玩家默认在创造中的值为 5,", "在生存中为的值 4.5"}); + super("ENTITY_INTERACTION_RANGE", + VMaterial.SPYGLASS.get(), + "生物交互距离", + "破坏实体或与实体相互作用的距离。玩家默认在创造中的值为 5,在生存中为的值 4.5" + ); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ExplosionKnockbackResistance.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ExplosionKnockbackResistance.java new file mode 100644 index 00000000..29da13bd --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ExplosionKnockbackResistance.java @@ -0,0 +1,23 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import net.Indyuce.mmoitems.util.MMOUtils; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class ExplosionKnockbackResistance extends DoubleStat { + public ExplosionKnockbackResistance() { + super("EXPLOSION_KNOCKBACK_RESISTANCE", + Material.OBSIDIAN, + "爆炸击退抗性", + "实体从爆炸中受到的击退影响系数。系数为1时完全移除击退效果,系数为0时表示没有击退减少"); + } + + @Override + public double multiplyWhenDisplaying() { + return 100; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/FallDamageMultiplier.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/FallDamageMultiplier.java index bf09e9b1..3197be23 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/FallDamageMultiplier.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/FallDamageMultiplier.java @@ -1,14 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; import org.bukkit.Material; @VersionDependant(version = {1, 20, 5}) public class FallDamageMultiplier extends DoubleStat { public FallDamageMultiplier() { - super("FALL_DAMAGE_MULTIPLIER", Material.DAMAGED_ANVIL, - "摔落伤害", new String[]{"增加一定百分比的坠落伤害。", "默认值为100%"}); + super("FALL_DAMAGE_MULTIPLIER", + Material.DAMAGED_ANVIL, + "摔落伤害", + "增加一定百分比的坠落伤害。默认值为100%" + ); } @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Gravity.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Gravity.java index 29a4c4b8..53a28792 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Gravity.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Gravity.java @@ -1,14 +1,18 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class Gravity extends DoubleStat { public Gravity() { - super("GRAVITY", Material.STONE, - "重力", new String[]{"增加重力。默认值为1"}); + super("GRAVITY", + Material.STONE, + "重力", + "增加重力。默认值为1"); } @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideDye.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideDye.java index cec63a78..c9c642d1 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideDye.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideDye.java @@ -6,7 +6,7 @@ import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.stat.data.BooleanData; import net.Indyuce.mmoitems.stat.type.BooleanStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; import org.bukkit.inventory.ItemFlag; import org.jetbrains.annotations.NotNull; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideTrim.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideTrim.java index c78131cd..8225556d 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideTrim.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/HideTrim.java @@ -6,7 +6,7 @@ import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.stat.data.BooleanData; import net.Indyuce.mmoitems.stat.type.BooleanStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; import org.bukkit.inventory.ItemFlag; import org.jetbrains.annotations.NotNull; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/JumpStrength.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/JumpStrength.java index f3d29995..eaca0e25 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/JumpStrength.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/JumpStrength.java @@ -1,13 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class JumpStrength extends DoubleStat { public JumpStrength() { - super("JUMP_STRENGTH", Material.SADDLE, - "跳跃高度", new String[]{"以块为单位的跳跃高度,", "默认值为1.25"}); + super("JUMP_STRENGTH", + Material.SADDLE, + "跳跃高度", + "以块为单位的跳跃高度, 默认值为1.25"); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/KnockbackResistance.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/KnockbackResistance.java index 6e6eedef..f8a41fe9 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/KnockbackResistance.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/KnockbackResistance.java @@ -1,16 +1,20 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") public class KnockbackResistance extends DoubleStat { - public KnockbackResistance() { - super("KNOCKBACK_RESISTANCE", Material.CHAINMAIL_CHESTPLATE, "击退抗性", new String[] { - "你的物品阻止爆炸、苦力怕造成的击退的几率...", "1.0 对应 100%、0.7 至 70%..." }); - } + public KnockbackResistance() { + super("KNOCKBACK_RESISTANCE", + Material.CHAINMAIL_CHESTPLATE, + "击退抗性", + "你的物品阻止爆炸、苦力怕造成的击退的几率...,1.0 对应 100%、0.7 至 70%..."); + } - @Override - public double multiplyWhenDisplaying() { - return 100; - } + @Override + public double multiplyWhenDisplaying() { + return 100; + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxAbsorption.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxAbsorption.java index 596c8e15..c593fcf6 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxAbsorption.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxAbsorption.java @@ -1,13 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 2}) public class MaxAbsorption extends DoubleStat { public MaxAbsorption() { - super("MAX_ABSORPTION", Material.ENCHANTED_GOLDEN_APPLE, - "伤害吸收最大值", new String[]{"并不提供永久的伤害吸收效果", "而是増加你在任何时候", "可以拥有的最大吸收之(黄色心)心数量"}); + super("MAX_ABSORPTION", + Material.ENCHANTED_GOLDEN_APPLE, + "伤害吸收最大值", + "并不提供永久的伤害吸收效果,而是増加你在任何时候可以拥有的最大吸收之(黄色心)心数量"); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxHealth.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxHealth.java new file mode 100644 index 00000000..a6cc331c --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxHealth.java @@ -0,0 +1,15 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +public class MaxHealth extends DoubleStat { + public MaxHealth() { + super("MAX_HEALTH", + Material.GOLDEN_APPLE, + "最大给予生命值", + "此物品给予持有者的生命值。"); + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxItemDamage.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxItemDamage.java index c338fdc0..0fe03553 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxItemDamage.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxItemDamage.java @@ -5,11 +5,12 @@ import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.api.util.NumericStatFormula; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.stat.data.type.StatData; import net.Indyuce.mmoitems.stat.type.DoubleStat; import net.Indyuce.mmoitems.stat.type.GemStoneStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.inventory.meta.Damageable; @@ -21,7 +22,7 @@ @VersionDependant(version = {1, 20, 5}) public class MaxItemDamage extends DoubleStat implements GemStoneStat { public MaxItemDamage() { - super("MAX_ITEM_DAMAGE", Material.DAMAGED_ANVIL, "物品耐久(原版)", new String[]{"仅适用于 1.20.5+ 物品的最大耐久。使用原版耐久实现", "(比自定义耐久稳定得多)"}, new String[]{"all"}); + super("MAX_ITEM_DAMAGE", Material.DAMAGED_ANVIL, "物品耐久(原版)", new String[]{"仅适用于 1.20.5+ 物品的最大耐久。使用原版耐久实现(比自定义耐久稳定得多)"}, new String[]{"all"}); } @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxStackSize.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxStackSize.java index 7bf731d3..2e20455c 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxStackSize.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MaxStackSize.java @@ -5,17 +5,19 @@ import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.api.util.NumericStatFormula; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.stat.data.type.StatData; import net.Indyuce.mmoitems.stat.type.DoubleStat; import net.Indyuce.mmoitems.stat.type.GemStoneStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class MaxStackSize extends DoubleStat implements GemStoneStat { public MaxStackSize() { diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MiningEfficiency.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MiningEfficiency.java new file mode 100644 index 00000000..8bbe3e66 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MiningEfficiency.java @@ -0,0 +1,19 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import net.Indyuce.mmoitems.util.MMOUtils; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class MiningEfficiency extends DoubleStat { + public MiningEfficiency() { + super("MINING_EFFICIENCY", + Material.IRON_PICKAXE, + "挖掘效率", + "在使用高效挖掘方块的工具时,挖掘速度的增加系数。默认值和最小值为0,最大值为1024。" + ); + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MovementEfficiency.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MovementEfficiency.java new file mode 100644 index 00000000..4b6203d3 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MovementEfficiency.java @@ -0,0 +1,23 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class MovementEfficiency extends DoubleStat { + public MovementEfficiency() { + super("MOVEMENT_EFFICIENCY", + Material.LEATHER_BOOTS, + "移动效率", + "实体在减缓移动的方块中移动的效率。系数为1时移除所有减速,系数为0时应用全部减速。默认值和最小值为0,最大值为1。" + ); + } + + @Override + public double multiplyWhenDisplaying() { + return 100; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MovementSpeed.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MovementSpeed.java index 94fcbbdb..9038fd89 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MovementSpeed.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/MovementSpeed.java @@ -1,13 +1,20 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") public class MovementSpeed extends DoubleStat { - public MovementSpeed() { - super("MOVEMENT_SPEED", Material.LEATHER_BOOTS, "移动速度", new String[] { "移动速度增加步行速度, ", "(默认MC行走速度: 0.1)" }); - } + public MovementSpeed() { + super("MOVEMENT_SPEED", + Material.LEATHER_BOOTS, + "移动速度", + "移动速度增加步行速度, (默认MC行走速度: 0.1)"); + } - @Override - public double multiplyWhenDisplaying() { return 100; } + @Override + public double multiplyWhenDisplaying() { + return 100; + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/OxygenBonus.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/OxygenBonus.java new file mode 100644 index 00000000..af908e6b --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/OxygenBonus.java @@ -0,0 +1,17 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class OxygenBonus extends DoubleStat { + public OxygenBonus() { + super("OXYGEN_BONUS", + Material.CONDUIT, + "氧气消耗几率", + "实体在水下不消耗氧气的几率系数。0无效果,值大于0时使用以下公式确定消耗氧气的几率:1 / (bonus_oxygen + 1)。最大值为1024"); + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/PickaxePower.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/PickaxePower.java index 5573a257..e1520072 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/PickaxePower.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/PickaxePower.java @@ -38,11 +38,11 @@ public void whenPreviewed(@NotNull ItemStackBuilder item, @NotNull DoubleData cu if (techMinimum < 0 && !handleNegativeStats()) { techMinimum = 0; } - if (techMinimum < ((NumericStatFormula) templateData).getBase() - ((NumericStatFormula) templateData).getMaxSpread()) { - techMinimum = ((NumericStatFormula) templateData).getBase() - ((NumericStatFormula) templateData).getMaxSpread(); + if (techMinimum < templateData.getBase() - templateData.getMaxSpread()) { + techMinimum = templateData.getBase() - templateData.getMaxSpread(); } - if (techMaximum > ((NumericStatFormula) templateData).getBase() + ((NumericStatFormula) templateData).getMaxSpread()) { - techMaximum = ((NumericStatFormula) templateData).getBase() + ((NumericStatFormula) templateData).getMaxSpread(); + if (techMaximum > templateData.getBase() + templateData.getMaxSpread()) { + techMaximum = templateData.getBase() + templateData.getMaxSpread(); } // Add NBT Path diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RequiredClass.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RequiredClass.java index ac647ad9..1eed6abf 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RequiredClass.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RequiredClass.java @@ -31,131 +31,130 @@ import java.util.regex.Pattern; public class RequiredClass extends StringListStat implements ItemRestriction, GemStoneStat { - public RequiredClass() { - super("REQUIRED_CLASS", Material.WRITABLE_BOOK, "所需职业", - new String[] { "需要特定职业才能使用物品" }, new String[] { "!block", "all" }); - } - - @Override - @SuppressWarnings("unchecked") - public StringListData whenInitialized(Object object) { - Validate.isTrue(object instanceof List, "必须指定一个字符串列表"); - return new StringListData((List) object); - } - - @Override - public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { - if (event.getAction() == InventoryAction.PICKUP_ALL) - new StatEdition(inv, this).enable("在聊天栏中输入您希望使用物品的职业"); - - if (event.getAction() == InventoryAction.PICKUP_HALF) { - if (inv.getEditedSection().getKeys(false).contains("required-class")) { - List supportedClasses = inv.getEditedSection().getStringList("required-class"); - if (supportedClasses.size() < 1) - return; - - String last = supportedClasses.get(supportedClasses.size() - 1); - supportedClasses.remove(last); - inv.getEditedSection().set(getPath(), supportedClasses.size() == 0 ? null : supportedClasses); - inv.registerTemplateEdition(); - inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "已成功删除 " + last + "."); - } - } - } - - @Override - public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) { - List lore = (inv.getEditedSection().getKeys(false).contains("required-class") ? inv.getEditedSection().getStringList("required-class") - : new ArrayList<>()); - lore.add(message); - inv.getEditedSection().set(getPath(), lore); - inv.registerTemplateEdition(); - inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "所需类已成功添加"); - } - - @Override - public void whenLoaded(@NotNull ReadMMOItem mmoitem) { - - // Find tag - ArrayList rtags = new ArrayList<>(); - if (mmoitem.getNBT().hasTag(getNBTPath())) - rtags.add(ItemTag.getTagAtPath(getNBTPath(), mmoitem.getNBT(), SupportedNBTTagValues.STRING)); - - // Build - StatData data = getLoadedNBT(rtags); - - // Success? - if (data != null) { mmoitem.setData(this, data);} - } - - @Nullable - @Override - public StringListData getLoadedNBT(@NotNull ArrayList storedTags) { - - // Get it - ItemTag listTag = ItemTag.getTagAtPath(getNBTPath(), storedTags); - - // Found? - if (listTag != null) { - - // Create String List Data - return new StringListData(((String) listTag.getValue()).split(Pattern.quote(", "))); - } - - // No correct tags - return null; - } - - @Override - public void whenDisplayed(List lore, Optional statData) { - - if (statData.isPresent()) { - lore.add(ChatColor.GRAY + "Cu当前值:"); - StringListData data = (StringListData) statData.get(); - data.getList().forEach(el -> lore.add(ChatColor.GRAY + "* " + ChatColor.GREEN + el)); - - } else - lore.add(ChatColor.GRAY + "当前值: " + ChatColor.RED + "None"); - - lore.add(""); - lore.add(ChatColor.YELLOW + AltChar.listDash + " 单击以添加班级"); - lore.add(ChatColor.YELLOW + AltChar.listDash + " 右键单击以删除最后一类"); - } - - @NotNull - @Override - public ArrayList getAppliedNBT(@NotNull StringListData data) { - - // Make the result list - ArrayList ret = new ArrayList<>(); - - // Add the Json Array - ret.add(new ItemTag(getNBTPath(), String.join(", ", ((StringListData) data).getList()))); - - // Ready. - return ret; - } - - @Override - public boolean canUse(RPGPlayer player, NBTItem item, boolean message) { - String requiredClass = item.getString(ItemStats.REQUIRED_CLASS.getNBTPath()); - if (!requiredClass.equals("") && !hasRightClass(player, requiredClass) && !player.getPlayer().hasPermission("mmoitems.bypass.class")) { - if (message) { - Message.WRONG_CLASS.format(ChatColor.RED).send(player.getPlayer()); - player.getPlayer().playSound(player.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.5f); - } - return false; - } - return true; - } - - private boolean hasRightClass(RPGPlayer player, String requiredClass) { - String name = ChatColor.stripColor(player.getClassName()); - - for (String found : requiredClass.split(Pattern.quote(", "))) - if (found.equalsIgnoreCase(name)) - return true; - - return false; - } + public RequiredClass() { + super("REQUIRED_CLASS", Material.WRITABLE_BOOK, "所需 Class", + new String[]{"需要特定 Class才能使用物品"}, new String[]{"!block", "all"}); + } + + @Override + @SuppressWarnings("unchecked") + public StringListData whenInitialized(Object object) { + Validate.isTrue(object instanceof List, "必须指定一个字符串列表"); + return new StringListData((List) object); + } + + @Override + public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { + if (event.getAction() == InventoryAction.PICKUP_ALL) + new StatEdition(inv, this).enable("在聊天栏中输入您希望使用物品的 Class"); + + if (event.getAction() == InventoryAction.PICKUP_HALF && inv.getEditedSection().getKeys(false).contains("required-class")) { + List supportedClasses = inv.getEditedSection().getStringList("required-class"); + if (supportedClasses.size() < 1) + return; + + String last = supportedClasses.remove(supportedClasses.size() - 1); + inv.getEditedSection().set(getPath(), supportedClasses.size() == 0 ? null : supportedClasses); + inv.registerTemplateEdition(); + inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "已成功删除 " + last + "."); + } + } + + @Override + public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) { + List lore = (inv.getEditedSection().getKeys(false).contains("required-class") ? inv.getEditedSection().getStringList("required-class") + : new ArrayList<>()); + lore.add(message); + inv.getEditedSection().set(getPath(), lore); + inv.registerTemplateEdition(); + inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "所需 Class 已成功添加"); + } + + @Override + public void whenLoaded(@NotNull ReadMMOItem mmoitem) { + + // Find tag + ArrayList rtags = new ArrayList<>(); + if (mmoitem.getNBT().hasTag(getNBTPath())) + rtags.add(ItemTag.getTagAtPath(getNBTPath(), mmoitem.getNBT(), SupportedNBTTagValues.STRING)); + + // Build + StatData data = getLoadedNBT(rtags); + + // Success? + if (data != null) { + mmoitem.setData(this, data); + } + } + + @Nullable + @Override + public StringListData getLoadedNBT(@NotNull ArrayList storedTags) { + + // Get it + ItemTag listTag = ItemTag.getTagAtPath(getNBTPath(), storedTags); + + // Found? + if (listTag != null) { + + // Create String List Data + return new StringListData(((String) listTag.getValue()).split(Pattern.quote(", "))); + } + + // No correct tags + return null; + } + + @Override + public void whenDisplayed(List lore, Optional statData) { + + if (statData.isPresent()) { + lore.add(ChatColor.GRAY + "当前值:"); + StringListData data = (StringListData) statData.get(); + data.getList().forEach(el -> lore.add(ChatColor.GRAY + "* " + ChatColor.GREEN + el)); + + } else + lore.add(ChatColor.GRAY + "当前值: " + ChatColor.RED + "None"); + + lore.add(""); + lore.add(ChatColor.YELLOW + AltChar.listDash + " 单击以添加 Class."); + lore.add(ChatColor.YELLOW + AltChar.listDash + " 右键单击以删除最后一类"); + } + + @NotNull + @Override + public ArrayList getAppliedNBT(@NotNull StringListData data) { + + // Make the result list + ArrayList ret = new ArrayList<>(); + + // Add the Json Array + ret.add(new ItemTag(getNBTPath(), String.join(", ", ((StringListData) data).getList()))); + + // Ready. + return ret; + } + + @Override + public boolean canUse(RPGPlayer player, NBTItem item, boolean message) { + String requiredClass = item.getString(ItemStats.REQUIRED_CLASS.getNBTPath()); + if (!requiredClass.equals("") && !hasRightClass(player, requiredClass) && !player.getPlayer().hasPermission("mmoitems.bypass.class")) { + if (message) { + Message.WRONG_CLASS.format(ChatColor.RED).send(player.getPlayer()); + player.getPlayer().playSound(player.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.5f); + } + return false; + } + return true; + } + + private boolean hasRightClass(RPGPlayer player, String requiredClass) { + String name = ChatColor.stripColor(player.getClassName()); + + for (String found : requiredClass.split(Pattern.quote(", "))) + if (found.equalsIgnoreCase(name)) + return true; + + return false; + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SafeFallDistance.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SafeFallDistance.java index f416c0fe..59042571 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SafeFallDistance.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SafeFallDistance.java @@ -1,12 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class SafeFallDistance extends DoubleStat { public SafeFallDistance() { - super("SAFE_FALL_DISTANCE", Material.RED_BED, "摔落高度", new String[]{"不受到摔落伤害的高度", "(玩家跳下时,不会受到摔落伤害)", "默认值为3"}); + super("SAFE_FALL_DISTANCE", + Material.RED_BED, + "摔落高度", + "控制玩家受到摔落伤害的距离。默认值为3,合法范围是-1024到+1024。"); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Scale.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Scale.java index fee8f5f3..94c45547 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Scale.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Scale.java @@ -1,13 +1,18 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class Scale extends DoubleStat { public Scale() { - super("SCALE", Material.STONE, "尺寸", new String[]{"玩家大小", "默认值为 1"}); + super("SCALE", + Material.STONE, + "尺寸", + "允许将玩家的大小更改为默认大小的0.0625倍到16倍之间。"); } @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SneakingSpeed.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SneakingSpeed.java new file mode 100644 index 00000000..f514cd56 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SneakingSpeed.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class SneakingSpeed extends DoubleStat { + public SneakingSpeed() { + super("SNEAKING_SPEED", + Material.LEATHER_BOOTS, + "潜行移动速度", + "潜行时的移动速度系数。系数为1表示潜行速度与行走速度相同,系数为0表示潜行时无法移动。默认值为0.3,最小值为0,最大值为1。"); + } + + @Override + public double multiplyWhenDisplaying() { + return 100; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingBreakChance.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingBreakChance.java index 9369e9e8..b4b9c545 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingBreakChance.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingBreakChance.java @@ -10,6 +10,7 @@ import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.message.Message; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.SoulboundData; import net.Indyuce.mmoitems.stat.type.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.type.DoubleStat; @@ -24,8 +25,9 @@ import java.util.Random; +@HasCategory(cat = "soulbound") public class SoulbindingBreakChance extends DoubleStat implements ConsumableItemInteraction { - private static final Random random = new Random(); + private static final Random RANDOM = new Random(); public SoulbindingBreakChance() { super("SOULBOUND_BREAK_CHANCE", Material.ENDER_EYE, "解除灵魂绑定机率", @@ -55,7 +57,7 @@ public boolean handleConsumableEffect(@NotNull InventoryClickEvent event, @NotNu return false; } - if (random.nextDouble() < soulboundBreakChance / 100) { + if (RANDOM.nextDouble() < soulboundBreakChance / 100) { BreakSoulboundEvent called = new BreakSoulboundEvent(playerData, consumable.getMMOItem(), target); Bukkit.getPluginManager().callEvent(called); if (called.isCancelled()) diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingChance.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingChance.java index 6f0f80a7..09cd3ea6 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingChance.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulbindingChance.java @@ -10,6 +10,7 @@ import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.message.Message; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.SoulboundData; import net.Indyuce.mmoitems.stat.type.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.type.DoubleStat; @@ -25,6 +26,7 @@ import java.util.Random; +@HasCategory(cat = "soulbound") public class SoulbindingChance extends DoubleStat implements ConsumableItemInteraction { private static final Random random = new Random(); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Soulbound.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Soulbound.java index 486c3e07..cd6f2ed3 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Soulbound.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Soulbound.java @@ -12,6 +12,7 @@ import net.Indyuce.mmoitems.api.player.RPGPlayer; import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.gui.edition.EditionInventory; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.SoulboundData; import net.Indyuce.mmoitems.stat.data.random.RandomStatData; import net.Indyuce.mmoitems.stat.data.type.StatData; @@ -33,6 +34,7 @@ import java.util.UUID; import java.util.regex.Pattern; +@HasCategory(cat = "soulbound") public class Soulbound extends ItemStat, SoulboundData> implements InternalStat, ItemRestriction { public Soulbound() { super("SOULBOUND", Material.ENDER_EYE, "灵魂绑定", new String[0], new String[0]); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulboundLevel.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulboundLevel.java index 7da13a76..63c9644c 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulboundLevel.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoulboundLevel.java @@ -3,15 +3,14 @@ import io.lumine.mythic.lib.api.item.ItemTag; import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; import net.Indyuce.mmoitems.api.util.NumericStatFormula; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.stat.type.DoubleStat; import net.Indyuce.mmoitems.util.MMOUtils; import org.bukkit.Material; import org.jetbrains.annotations.NotNull; -/** - * Soulbound level for consumables. - */ +@HasCategory(cat = "soulbound") public class SoulboundLevel extends DoubleStat { public SoulboundLevel() { super("SOULBOUND_LEVEL", Material.ENDER_EYE, "灵魂绑定等级", new String[]{"灵魂绑定等级决定了玩家在尝试使", "用灵魂绑定物品时会受到多少伤害", "\n它还决定了打破绑定的难度."}, new String[]{"consumable"}); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StepHeight.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StepHeight.java index dcbedb96..38f82bfe 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StepHeight.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StepHeight.java @@ -1,13 +1,17 @@ package net.Indyuce.mmoitems.stat; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.DoubleStat; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; +@HasCategory(cat = "vanilla_attribute") @VersionDependant(version = {1, 20, 5}) public class StepHeight extends DoubleStat { public StepHeight() { - super("STEP_HEIGHT", Material.GOLDEN_BOOTS, - "坡度", new String[]{"行走或冲刺时,不需要跳跃就可以越过","的额外方块数。默认值是0.6,即仅高于一个半砖。"}); + super("STEP_HEIGHT", + Material.STONE_SLAB, + "Step Height", + "决定生物无需跳跃即可越过的最大方块高度。默认值为0.6,合法范围是0到10。"); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SubmergedMiningSpeed.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SubmergedMiningSpeed.java new file mode 100644 index 00000000..d7b8fdb8 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SubmergedMiningSpeed.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class SubmergedMiningSpeed extends DoubleStat { + public SubmergedMiningSpeed() { + super("SUBMERGED_MINING_SPEED", + Material.WATER_BUCKET, + "液体中挖掘速度", + "被液体淹没时的挖掘速度系数。系数为1表示淹没时的挖掘速度与在陆地上一样快,系数为0表示淹没时无法挖掘。请注意,这仅代表淹没因素,其他因素(如未接触地面)也会影响。默认值为0.2,最小值为0,最大值为20。"); + } + + @Override + public double multiplyWhenDisplaying() { + return 100; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SuccessRate.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SuccessRate.java index f08b410d..8786c7f3 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SuccessRate.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SuccessRate.java @@ -7,7 +7,7 @@ public class SuccessRate extends DoubleStat implements GemStoneStat { - /* + /** * in a different class because Success Rate is meant to be a proper stat */ public SuccessRate() { diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SweepingDamageRatio.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SweepingDamageRatio.java new file mode 100644 index 00000000..c127dded --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SweepingDamageRatio.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class SweepingDamageRatio extends DoubleStat { + public SweepingDamageRatio() { + super("SWEEPING_DAMAGE_RATIO", + Material.LIGHT_GRAY_DYE, + "横扫伤害比例", + "在横扫攻击中,基础攻击伤害有多少会传递到次要目标。这是对横扫攻击基础伤害1的额外加成。值为0表示没有基础攻击伤害传递(横扫伤害为1),值为1表示所有基础攻击伤害都传递。默认值和最小值为0,最大值为1。"); + } + + @Override + public double multiplyWhenDisplaying() { + return 100; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimMaterialStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimMaterialStat.java index f8ab9696..d45f0be0 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimMaterialStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimMaterialStat.java @@ -6,7 +6,7 @@ import net.Indyuce.mmoitems.stat.type.ChooseStat; import net.Indyuce.mmoitems.stat.type.GemStoneStat; import net.Indyuce.mmoitems.util.StatChoice; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Registry; @@ -29,7 +29,13 @@ public TrimMaterialStat() { if (!isEnabled()) return; for (TrimMaterial mat : Registry.TRIM_MATERIAL) - addChoices(new StatChoice(mat.getKey().getKey())); + addChoices(new StatChoice(mat.getKey().toString())); + } + + @Nullable + @Override + public StatChoice getChoice(String id) { + return super.getChoice(TrimPatternStat.fixNamespacedKey(id).toString()); } @Override @@ -49,6 +55,6 @@ public void whenLoaded(@NotNull ReadMMOItem mmoitem) { if (!(mmoitem.getNBT().getItem().getItemMeta() instanceof ArmorMeta)) return; final ArmorMeta meta = (ArmorMeta) mmoitem.getNBT().getItem().getItemMeta(); if (!meta.hasTrim()) return; - mmoitem.setData(this, new StringData(meta.getTrim().getMaterial().getKey().getKey())); + mmoitem.setData(this, new StringData(meta.getTrim().getMaterial().getKey().toString())); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimPatternStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimPatternStat.java index 8fc0e095..02cfb6a0 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimPatternStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/TrimPatternStat.java @@ -6,7 +6,7 @@ import net.Indyuce.mmoitems.stat.type.ChooseStat; import net.Indyuce.mmoitems.stat.type.GemStoneStat; import net.Indyuce.mmoitems.util.StatChoice; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Registry; @@ -29,14 +29,25 @@ public TrimPatternStat() { if (!isEnabled()) return; for (TrimPattern mat : Registry.TRIM_PATTERN) - addChoices(new StatChoice(mat.getKey().getKey())); + addChoices(new StatChoice(mat.getKey().toString())); + } + + public static NamespacedKey fixNamespacedKey(String str) { + if (!str.contains(":")) return NamespacedKey.minecraft(str); + return NamespacedKey.fromString(str); + } + + @Nullable + @Override + public StatChoice getChoice(String id) { + return super.getChoice(fixNamespacedKey(id).toString()); } @Override public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StringData data) { if (!(item.getMeta() instanceof ArmorMeta)) return; - @Nullable TrimPattern pattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(data.toString().toLowerCase())); + @Nullable TrimPattern pattern = Registry.TRIM_PATTERN.get(fixNamespacedKey(data.toString())); if (pattern == null) return; final ArmorMeta meta = (ArmorMeta) item.getMeta(); @@ -49,6 +60,6 @@ public void whenLoaded(@NotNull ReadMMOItem mmoitem) { if (!(mmoitem.getNBT().getItem().getItemMeta() instanceof ArmorMeta)) return; final ArmorMeta meta = (ArmorMeta) mmoitem.getNBT().getItem().getItemMeta(); if (!meta.hasTrim()) return; - mmoitem.setData(this, new StringData(meta.getTrim().getPattern().getKey().getKey())); + mmoitem.setData(this, new StringData(meta.getTrim().getPattern().getKey().toString())); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/WaterMovementEfficiency.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/WaterMovementEfficiency.java new file mode 100644 index 00000000..73cb928d --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/WaterMovementEfficiency.java @@ -0,0 +1,22 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; +import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.Material; + +@HasCategory(cat = "vanilla_attribute") +@VersionDependant(version = {1, 21}) +public class WaterMovementEfficiency extends DoubleStat { + public WaterMovementEfficiency() { + super("WATER_MOVEMENT_EFFICIENCY", + Material.WATER_BUCKET, + "液体中移动效率", + "被液体淹没时的移动速度系数。系数越高,越能减轻水下移动的惩罚。请注意,这仅代表淹没因素,其他因素(如未接触地面)也会影响。默认值和最小值为0,最大值为1。"); + } + + @Override + public double multiplyWhenDisplaying() { + return 100; + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/annotation/HasCategory.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/annotation/HasCategory.java new file mode 100644 index 00000000..e29052b2 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/annotation/HasCategory.java @@ -0,0 +1,13 @@ +package net.Indyuce.mmoitems.stat.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Can be used to give categories to stats + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface HasCategory { + + public String cat(); +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/annotation/VersionDependant.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/annotation/VersionDependant.java new file mode 100644 index 00000000..a77f62b5 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/annotation/VersionDependant.java @@ -0,0 +1,20 @@ +package net.Indyuce.mmoitems.stat.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Version string is MAJOR.MINOR.PATCH + *

+ * This annotation indicates the LOWEST VERSION at which + * the given feature is available. Usually, it's the + * version where some non-backwards compatible feature was + * implemented into Minecraft or Spigot. + * + * @author Jules + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface VersionDependant { + + public int[] version(); +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/category/StatCategory.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/category/StatCategory.java new file mode 100644 index 00000000..8ac16fc9 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/category/StatCategory.java @@ -0,0 +1,41 @@ +package net.Indyuce.mmoitems.stat.category; + +import org.jetbrains.annotations.NotNull; + +public class StatCategory { + private final String id, name, loreTag; + + /** + * @param id Internal identifier of stat category. Must be unique + * @param name Name used to identify the category in the item browser + * @param loreTag Lore tag added to stats with the given category + */ + public StatCategory(String id, String name, String loreTag) { + this.id = id; + this.name = name; + this.loreTag = loreTag; + } + + @NotNull + public String getId() { + return id; + } + + @NotNull + public String getName() { + return name; + } + + @NotNull + public String getLoreTag() { + return loreTag; + } + + public static final StatCategory + TEMPLATE_OPTION = new StatCategory("TEMPLATE_OPTION", "Template Option, Misc", "Template Option"), + SOULBOUND = new StatCategory("SOULBOUND", "Soulbound", "Soulbound"), + ELEMENTAL = new StatCategory("ELEMENTAL", "Elements", "Elements"), + VANILLA_ATTRIBUTE = new StatCategory("VANILLA_ATTRIBUTE", "Vanilla Attributes", "Vanilla Attribute"), + REQUIREMENT = new StatCategory("REQUIREMENT", "Item Requirements", "Item Requirement"), + USE_COST = new StatCategory("USE_COST", "Item Costs", "Use Cost"); +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ChooseStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ChooseStat.java index 77e06cb4..90a56c53 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ChooseStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ChooseStat.java @@ -1,11 +1,10 @@ package net.Indyuce.mmoitems.stat.type; import io.lumine.mythic.lib.api.util.AltChar; -import io.lumine.mythic.lib.api.util.ui.SilentNumbers; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.gui.edition.EditionInventory; import net.Indyuce.mmoitems.stat.data.StringData; -import net.Indyuce.mmoitems.stat.data.random.RandomStatData; +import net.Indyuce.mmoitems.util.MMOUtils; import net.Indyuce.mmoitems.util.StatChoice; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; @@ -15,7 +14,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; /** * Choose Stats present a list of options from which the user may choose one. @@ -52,7 +54,7 @@ public StatChoice getChoice(String id) { @Override public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) { - Validate.isTrue(choices.size() > 0, "基于选择的统计数据无效 '" + getId() + ": 没有可供选择的选项"); + Validate.isTrue(!choices.isEmpty(), "基于选择的统计数据无效 '" + getId() + ": 没有可供选择的选项"); // If removing, reset to default if (event.getAction() == InventoryAction.PICKUP_HALF) { @@ -67,18 +69,14 @@ public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEv } else { // Get current - StatChoice current = getChoice(inv.getEditedSection().getString(getPath())); - - // Included? - int currentIndex = current != null ? Math.max(0, choices.indexOf(current)) : 0; + String found = inv.getEditedSection().getString(getPath()); + int currentIndex = found == null ? -1 : choices.indexOf(getChoice(found)); // Increase and Cap if (++currentIndex >= choices.size()) currentIndex = 0; - // Get - current = choices.get(currentIndex); - // Edits into persistent files + StatChoice current = choices.get(currentIndex); inv.getEditedSection().set(getPath(), current.getId()); inv.registerTemplateEdition(); @@ -89,14 +87,14 @@ public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEv @Override public void whenDisplayed(List lore, Optional statData) { - Validate.isTrue(choices.size() > 0, "基于选择的统计数据无效 '" + getId() + ": 没有可供选择的选项"); + Validate.isTrue(!choices.isEmpty(), "基于选择的统计数据无效 '" + getId() + ": 没有可供选择的选项"); // To display current choosing, gets the very first element - StatChoice def = statData.isPresent() ? getChoice(statData.get().toString()) : choices.get(0); - lore.add(ChatColor.GRAY + "当前值: " + (statData.isPresent() ? ChatColor.GREEN : ChatColor.RED) + def); + @Nullable StatChoice found = statData.isPresent() ? getChoice(statData.get().toString()) : null; + lore.add(ChatColor.GRAY + "当前值: " + (found != null ? ChatColor.GREEN + found.getId() : ChatColor.RED + "None")); // Display Definition - for (String definition : SilentNumbers.chop(def.getHint(), 50, "")) + if (found != null && found.getHint() != null) for (String definition : MMOUtils.trimString(LORE_LINE_WIDTH, found.getHint())) lore.add(ChatColor.GRAY + " " + definition); lore.add(""); @@ -105,7 +103,7 @@ public void whenDisplayed(List lore, Optional statData) { for (StatChoice existing : choices) { // Is it the one? - String pick = existing.equals(def) ? ChatColor.RED.toString() + ChatColor.BOLD : ChatColor.GOLD.toString(); + String pick = existing.equals(found) ? ChatColor.RED.toString() + ChatColor.BOLD : ChatColor.GOLD.toString(); lore.add(pick + " " + AltChar.smallListDash + " " + ChatColor.GRAY + existing.getId()); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java index 242580c1..1abab38e 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java @@ -20,6 +20,7 @@ import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.stat.data.type.StatData; import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo; +import net.Indyuce.mmoitems.util.MMOUtils; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -44,6 +45,10 @@ public DoubleStat(String id, Material mat, String name, String[] lore) { this(id, mat, name, lore, new String[]{"!miscellaneous", "!block", "all"}, true); } + public DoubleStat(String id, Material mat, String name, String lore) { + this(id, mat, name, MMOUtils.trimString(LORE_LINE_WIDTH, lore), new String[]{"!miscellaneous", "!block", "all"}, true); + } + public DoubleStat(String id, Material mat, String name, String[] lore, String[] types, Material... materials) { this(id, mat, name, lore, types, true, materials); } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/FictiveNumericStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/FakeElementalStat.java similarity index 90% rename from MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/FictiveNumericStat.java rename to MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/FakeElementalStat.java index 5330c7f7..fa89d879 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/FictiveNumericStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/FakeElementalStat.java @@ -6,6 +6,7 @@ import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.api.util.NumericStatFormula; import net.Indyuce.mmoitems.gui.edition.EditionInventory; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.util.ElementStatType; import org.bukkit.Material; @@ -26,9 +27,10 @@ * * @deprecated Definitely not a perfect implementation */ +@HasCategory(cat = "elemental") @Deprecated -public class FictiveNumericStat extends DoubleStat implements InternalStat { - public FictiveNumericStat(Element el, ElementStatType type) { +public class FakeElementalStat extends DoubleStat implements InternalStat { + public FakeElementalStat(Element el, ElementStatType type) { super(type.getConcatenatedTagPath(el), Material.BARRIER, "虚拟统计", new String[0]); } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java index 3c10dd98..ac584cdd 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java @@ -8,9 +8,10 @@ import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; import net.Indyuce.mmoitems.gui.edition.EditionInventory; +import net.Indyuce.mmoitems.stat.category.StatCategory; import net.Indyuce.mmoitems.stat.data.random.RandomStatData; import net.Indyuce.mmoitems.stat.data.type.StatData; -import net.Indyuce.mmoitems.util.VersionDependant; +import net.Indyuce.mmoitems.stat.annotation.VersionDependant; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryClickEvent; @@ -30,7 +31,7 @@ public abstract class ItemStat, S extends StatData> private final List compatibleTypes; private final List compatibleMaterials; - @Nullable + @NotNull private String[] aliases = {}; /** @@ -39,6 +40,10 @@ public abstract class ItemStat, S extends StatData> */ private boolean enabled = true; + private StatCategory category; + + protected static final int LORE_LINE_WIDTH = 50; + /** * Initializes an item stat * @@ -66,6 +71,12 @@ public ItemStat(@NotNull String id, @NotNull Material material, @NotNull String final VersionDependant implVersion = getClass().getAnnotation(VersionDependant.class); if (MythicLib.plugin.getVersion().isUnder(implVersion.version())) disable(); } + + // Backwards compatibility + if (getClass().isAnnotationPresent(net.Indyuce.mmoitems.util.VersionDependant.class)) { + final net.Indyuce.mmoitems.util.VersionDependant implVersion = getClass().getAnnotation(net.Indyuce.mmoitems.util.VersionDependant.class); + if (MythicLib.plugin.getVersion().isUnder(implVersion.version())) disable(); + } } /** @@ -177,6 +188,15 @@ public String getGeneralStatFormat() { return generalStatFormat; } + @Nullable + public StatCategory getCategory() { + return category; + } + + public void setCategory(@Nullable StatCategory category) { + this.category = category; + } + @NotNull public String getName() { return name; @@ -199,7 +219,7 @@ public String getId() { *

* Aliases have to follow the UPPER_CASE stat identifier format. */ - @Nullable + @NotNull public String[] getAliases() { return aliases; } @@ -302,6 +322,8 @@ public boolean equals(Object o) { return id.equals(itemStat.id); } + + @Override public int hashCode() { return Objects.hash(id); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java index 7a2b6c59..bca87c77 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java @@ -40,6 +40,32 @@ public static boolean isColorable(@NotNull Particle particle) { return particle.getDataType() == Particle.DustOptions.class; } + public static String[] trimString(int charactersPerLine, @NotNull String... inputs) { + List list = new ArrayList<>(); + + for (String input : inputs) { + if (input.length() <= charactersPerLine) { + list.add(input); + continue; + } + + StringBuilder currentLine = new StringBuilder(); + + for (String word : input.split(" ")) { + if (!currentLine.isEmpty()) currentLine.append(" "); + currentLine.append(word); + if (currentLine.length() > charactersPerLine || word.endsWith("\n")) { + list.add(currentLine.toString()); // Return line + currentLine.setLength(0); // Empty current line + } + } + + // Add last line (sometimes not necessary) + if (!currentLine.isEmpty()) list.add(currentLine.toString()); + } + + return list.toArray(new String[0]); + } @NotNull public static ItemStack readIcon(@NotNull String stringInput) { diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/StatChoice.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/StatChoice.java index ab50df5b..44e073c8 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/StatChoice.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/StatChoice.java @@ -8,7 +8,7 @@ public class StatChoice { private final String id, hint; public StatChoice(String id) { - this(id, "- 无提示 -"); + this(id, null); } public StatChoice(String id, @Nullable String hint) { diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/VersionDependant.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/VersionDependant.java index d6065fcc..7067314b 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/VersionDependant.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/VersionDependant.java @@ -4,15 +4,10 @@ import java.lang.annotation.RetentionPolicy; /** - * Version string is MAJOR.MINOR.PATCH - *

- * This annotation indicates the LOWEST VERSION at which - * the given feature is available. Usually, it's the - * version where some non-backwards compatible feature was - * implemented into Minecraft or Spigot. - * - * @author Jules + * @see net.Indyuce.mmoitems.stat.annotation.VersionDependant + * @deprecated Moved to another class */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) public @interface VersionDependant { diff --git a/MMOItems-Dist/pom.xml b/MMOItems-Dist/pom.xml index 1420b45b..85837da8 100644 --- a/MMOItems-Dist/pom.xml +++ b/MMOItems-Dist/pom.xml @@ -15,11 +15,11 @@ - + io.papermc.paper paper-api - 1.20.6-R0.1-SNAPSHOT + 1.21.1-R0.1-SNAPSHOT provided true @@ -46,6 +46,13 @@ 1.1 provided true + + + + net.md-5 + bungeecord-chat + + diff --git a/MMOItems-Dist/src/main/resources/default/item/armor.yml b/MMOItems-Dist/src/main/resources/default/item/armor.yml index ac432f63..0b1a50e0 100644 --- a/MMOItems-Dist/src/main/resources/default/item/armor.yml +++ b/MMOItems-Dist/src/main/resources/default/item/armor.yml @@ -164,6 +164,8 @@ DRAGON_BOOTS: - Magenta - Black set: DRAGON + +# Spellcaster set SPELLCASTER_HELMET: base: material: LEATHER_HELMET @@ -300,6 +302,8 @@ SPELLCASTER_BOOTS: hide-dye: true dye-color: 125 0 255 set: SPELLCASTER + +# Omnielemental set OMNIELEMENTAL_HELMET: base: material: LEATHER_HELMET @@ -586,6 +590,8 @@ CONTROL_DEVICES: armor: 7.0 tier: MAGICAL unbreakable: true + +# Undead slayer UNDEAD_SLAYER_HELMET: base: material: NETHERITE_HELMET @@ -725,6 +731,8 @@ MYTHRIL_CHAINMAIL: - Blue required-level: 4.0 tier: UNCOMMON + +# Steel set STEEL_HELMET: base: material: IRON_HELMET @@ -891,6 +899,8 @@ HUGE_MOTHRON_WINGS: unbreakable: true movement-speed: -0.03 will-break: false + +# Arcane set ARCANE_HELM: base: material: LEATHER_HELMET @@ -967,6 +977,8 @@ ARCANE_BOOTS: spread: 0.033 max-spread: 0.1 set: ARCANE + +# Gingerbread set GINGERBREAD_HELM: base: material: LEATHER_HELMET @@ -1129,6 +1141,8 @@ TRAVEL_BOOTS: max-durability: 100.0 armor: 2.0 fall-damage-reduction: 5.0 + +# Shadow set SHADOWVEIL: base: material: LEATHER_HELMET @@ -1219,6 +1233,187 @@ SHADOWBOOTS: max-health: 8.0 movement-speed: 0.01 dye-color: 0 0 0 + +# Misc +HELMET_OF_THE_SEA: + base: + material: LEATHER_HELMET + max-durability: 8000.0 + attack-damage: + base: 6.0 + scale: 0.1 + spread: 0.2 + max-spread: 0.3 + required-level: 10.0 + weapon-damage: + base: 10.0 + scale: 0.1 + spread: 0.2 + max-spread: 0.25 + magic-damage: + base: 10.0 + scale: 0.1 + spread: 0.2 + max-spread: 0.25 + physical-damage: + base: 15.0 + scale: 0.1 + spread: 0.2 + max-spread: 0.25 + cooldown-reduction: + base: 15.0 + scale: 0.1 + spread: 0.2 + max-spread: 0.25 + pve-damage: + base: 15.0 + scale: 0.1 + spread: 0.2 + max-spread: 0.25 + tier: RARE + dye-color: 120 120 255 + name: §9Helmet of the Ocean + hide-dye: true + element: + water: + defense: + base: 25.0 + scale: 0.0 + spread: 0.2 + max-spread: 0.4 + amphibian: DAMP + perm-effects: + NIGHT_VISION: 1.0 + WATER_BREATHING: 1.0 + lore: + - §3Will only work when §9§lUNDERWATER§3. + - §3Gives §9Night Vision §3and §9Water Breathing§3. +MOON_BOOTS: + base: + material: DIAMOND_BOOTS + lore: + - §bMoon boots will simulate being on the moon! + - §7Gives §3Jump Boost II§7 when worn. + - §cWill only work in "the end" biome. + max-durability: 2650.0 + name: §b§lMoon Boots + tier: UNIQUE + armor-toughness: 1.5 + armor: 3.0 + fall-damage-reduction: 75.0 + perm-effects: + JUMP: 2.0 + required-biomes: + - the_end +CONTROL_DEVICES: + base: + material: LEATHER_HELMET + max-durability: 15000.0 + name: §d§lControl Devices + dye-color: 255 102 204 + ability: {} + set: PSYCHIC + perm-effects: + DAMAGE_RESISTANCE: 2.0 + SPEED: 2.0 + REGENERATION: 2.0 + FIRE_RESISTANCE: 1.0 + INCREASE_DAMAGE: 2.0 + required-class: + - Mage + lore: + - §7To keep your powers in check... + armor-toughness: 2.0 + armor: 7.0 + tier: MAGICAL + unbreakable: true +DEAD_PHARAOH_HELMET: + base: + material: PLAYER_HEAD + skull-texture: + value: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGU1NWRmOTc5YWI3OTc0OWY4YjU1MWI0MjM5YTQ2OWFhNzY5ZDliNDYwNTBhYWJkOWY2ZDFjZWU1M2VkMzYifX19 + uuid: 852deb36-af4a-412f-ac76-2b06dc123ed2 + name: '&cDead Pharaoh Helmet' + disable-interaction: true + item-particles: + type: FIREFLIES + particle: SMOKE_NORMAL + fire-damage-reduction: 30.0 + armor: 4.0 + undead-damage: 30.0 + lore: + - '&7This powerful forgotten helmet' + - '&7will greatly increase your power' + - '&7against undead creatures.' + required-level: 9.0 +MOSSY_SKELETON_SKULL: + base: + material: PLAYER_HEAD + skull-texture: + value: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWE2MzE0ZWFjMzQ0MTZjZTEwYWIyMmMyZTFjNGRjYjQ3MmEzZmViOThkNGUwNGQzZmJiYjg1YTlhNDcxYjE4In19fQ + uuid: f455a085-3f09-43ac-8be1-175204d1a6ad + name: '&8Mossy Skeleton Skull' + required-level: 6.0 + armor: 3.5 + knockback-resistance: 0.1 + movement-speed: -0.01 + disable-interaction: true +SKELETON_CROWN: + base: + material: PLAYER_HEAD + skull-texture: + value: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGM3OGQyMTAyZGI3NWYxYjM3NDRhNWU3ZTliYWNjZjg4ZmRhNGNjNDk3OWViYzBhODFiN2Q5ZWI1NzIxYzAifX19 + uuid: ccb901e7-0919-463d-9bdd-ee9acae8e0e2 + name: '&eSkeleton Crown' + required-level: 9.0 + armor: 3.0 + movement-speed: 0.01 + ability: + ability1: + type: LIFE_ENDER + mode: DAMAGED + damage: 3.0 + cooldown: 9.0 + lore: + - '&7Every 9 seconds, summons a' + - '&cdeadly meteor&7 at your attacker,' + - '&7dealing &c4&7 damage while briefly' + - '&7knocking them away.' + disable-interaction: true +WYVERN_CAP: + base: + material: GOLDEN_HELMET + name: '&fWyvern Cap' + required-level: 10.0 + hide-enchants: false + enchants: + unbreaking: 9 + armor: 2.5 + fall-damage-reduction: 70.0 + perm-effects: + JUMP: 2 + lore: + - '&7Grants permanent jump boost II' + crafting: + shaped: + '1': + - TOME.WYVERN_FEATHER TOME.WYVERN_SOUL TOME.WYVERN_FEATHER + - TOME.WYVERN_FEATHER AIR TOME.WYVERN_FEATHER + - AIR AIR AIR + '2': + - AIR AIR AIR + - TOME.WYVERN_FEATHER TOME.WYVERN_SOUL TOME.WYVERN_FEATHER + - TOME.WYVERN_FEATHER AIR TOME.WYVERN_FEATHER +TRAVEL_BOOTS: + base: + material: LEATHER_BOOTS + name: §fTravel boots + movement-speed: 0.005 + dye-color: 187 118 126 + will-break: true + max-durability: 100.0 + armor: 2.0 + fall-damage-reduction: 5.0 GARGOYLE_CHESTPLATE: base: material: IRON_CHESTPLATE @@ -1246,3 +1441,103 @@ SHRINKING_BOOTS: lore: - '&7&oMay this item help you get' - '&7&othrough the narrowest paths...' +MYTHRIL_CHAINMAIL: + base: + material: CHAINMAIL_CHESTPLATE + name: '&b--] &fMythril Chainmail &b[--' + block-power: + base: 60.0 + spread: 0.048 + max-spread: 0.14 + block-rating: + base: 12.5 + spread: 0.06 + max-spread: 0.17 + armor: 5 + element: + ice: + defense: 8.0 + earth: + defense: 6.4 + gem-sockets: + - Red + - Blue + required-level: 4.0 + tier: UNCOMMON +CURSED_WITHER_SKULL: + base: + material: WITHER_SKELETON_SKULL + name: '&7Cursed Wither Skull' + required-level: 30.0 + tier: UNIQUE + gem-sockets: + - Red + - Blue + armor: 3.0 + armor-toughness: 2.0 + perm-effects: + ABSORPTION: 1 + lore: + - '&7Grants a permanent &62' + - '&6hearts &7absorption shield.' + durability: 1.0 + element: + thunder: + defense: 67.4 + fire: + defense: 53.4 + crafting: + shaped: + '1': + - BONE BONE BONE + - BONE MATERIAL.UNIQUE_WEAPON_ESSENCE BONE + - BONE BONE BONE +LARGE_MOTHRON_WINGS: + base: + material: ELYTRA + max-durability: 5.0 + two-handed: false + name: '&eLarge Mothron Wings' + tier: RARE + gravity: -0.02 + unbreakable: true + movement-speed: -0.03 + will-break: false +FIREPROOF_JACKET: + base: + material: LEATHER_CHESTPLATE + burning-time: -0.9 + name: Fireproof Jacket + enchants: + unbreaking: 4.0 + trim-pattern: vex + trim-material: redstone +BEE_WINGS: + base: + material: ELYTRA + name: Bee Wings + movement-speed: 0.02 + fall-damage-multiplier: -0.5 + jump-strength: 0.2 + gravity: -0.04 + safe-fall-distance: 7.0 +SOULWALKER: + base: + material: GOLDEN_BOOTS + name: Soulwalker + movement-efficiency: 0.9 + armor: 3.0 + step-height: 0.4 + lore: + - '&7Negates soulsand movement impairing.' + +DIVING_BOOTS: + base: + material: GOLDEN_BOOTS + name: Diving Boots + trim-material: copper + trim-pattern: wild + water-movement-efficiency: 1.0 + gravity: 2.0 + step-height: 0.5 + diff --git a/MMOItems-Dist/src/main/resources/default/item/dagger.yml b/MMOItems-Dist/src/main/resources/default/item/dagger.yml index 10208e53..1d755b29 100644 --- a/MMOItems-Dist/src/main/resources/default/item/dagger.yml +++ b/MMOItems-Dist/src/main/resources/default/item/dagger.yml @@ -179,8 +179,8 @@ SNEAKY_DAGGER: lore: - §7这把匕首十分神秘。 tier: UNCOMMON - attack-damage: 5.0 - attack-speed: 2.2 + attack-damage: 11.0 + attack-speed: 0.9 critical-strike-chance: base: 9.0 scale: 0.1 @@ -197,4 +197,5 @@ SNEAKY_DAGGER: type: BACKSTAB mode: ATTACK cooldown: 3.0 - extra: 50.0 \ No newline at end of file + extra: 50.0 + sneaking-speed: 2.0 diff --git a/MMOItems-Dist/src/main/resources/default/item/tool.yml b/MMOItems-Dist/src/main/resources/default/item/tool.yml index d45cb359..64dfec41 100644 --- a/MMOItems-Dist/src/main/resources/default/item/tool.yml +++ b/MMOItems-Dist/src/main/resources/default/item/tool.yml @@ -55,7 +55,7 @@ AUTOSMELT_PICKAXE: - v magma_cream - 1.0..|v netherite_block - 1.0..|v magma_cream - 1.0.. - v AIR 0 1..|v stick - 1.0..|v AIR 0 1.. - v AIR 0 1..|v stick - 1.0..|v AIR 0 1.. -UNBREAKABLE_SHEARS: +SILK_SHEARS: base: material: SHEARS enchants: @@ -66,3 +66,12 @@ UNBREAKABLE_SHEARS: - §7能够采集§9草§7和§2玻璃§7。 tier: UNCOMMON required-level: 5.0 + +FAST_PICK: + base: + material: WOODEN_PICKAXE + mining-efficiency: 100.0 + max-item-damage: 100.0 + lore: + - '&7&oInsanely fast, but won''t loot' + diff --git a/MMOItems-Dist/src/main/resources/default/language/lore-format.yml b/MMOItems-Dist/src/main/resources/default/language/lore-format.yml index 21f3c100..c01866d6 100644 --- a/MMOItems-Dist/src/main/resources/default/language/lore-format.yml +++ b/MMOItems-Dist/src/main/resources/default/language/lore-format.yml @@ -92,6 +92,15 @@ lore-format: - '#safe-fall-distance#' - '#scale#' - '#step-height#' + - '#burning-time#' + - '#explosion-knockback-resistance#' + - '#mining-efficiency#' + - '#movement-efficiency#' + - '#oxygen-bonus#' + - '#sneaking-speed#' + - '#submerged-mining-speed#' + - '#sweeping-damage-ratio#' + - '#water-movement-efficiency#' - '#lute-attack-effect#' - '#two-handed#' - '#handworn#' diff --git a/MMOItems-Dist/src/main/resources/default/language/stats.yml b/MMOItems-Dist/src/main/resources/default/language/stats.yml index e486ebed..6a079577 100644 --- a/MMOItems-Dist/src/main/resources/default/language/stats.yml +++ b/MMOItems-Dist/src/main/resources/default/language/stats.yml @@ -85,15 +85,24 @@ additional-experience-woodcutting: '&7■ 额外伐木经验: &f{value}%' # 1.20.2+ Attributes block-break-speed: '&3 &7■ 挖掘速度: &f{value}' -block-interaction-range: '&3 &7■ 方块交互距离: &f{value}' # Range for interacting with blocks & mining. -entity-interaction-range: '&3 &7■ 攻击距离: &f{value}' -fall-damage-multiplier: '&3 &7■ 摔落伤害: &f{value}%' -gravity: '&3 &7■ 重力: &f{value}%' -jump-strength: '&3 &7■ 跳跃高度: &f{value}' -max-absorption: '&3 &7■ 伤害吸收: &f{value}' -safe-fall-distance: '&3 &7■ 安全摔落距离: &f{value}' -scale: '&3 &7■ 大小: &f{value}%' -step-height: '&3 &7■ Smooth Walking: &f{value}' # TODO 不知道怎么翻,先放着 +block-interaction-range: '&3 &7■ 范围: &f{value}' # Range for interacting with blocks & mining. +entity-interaction-range: '&3 &7■ 战斗范围: &f{value}' +fall-damage-multiplier: '&3 &7■ 坠落伤害: &f{value}%' +gravity: '&3 &7■ 重力强度: &f{value}%' +jump-strength: '&3 &7■ 跳跃强度: &f{value}' +max-absorption: '&3 &7■ 最大伤害吸收: &f{value}' +safe-fall-distance: '&3 &7■ 安全坠落距离: &f{value}' +scale: ' &3 &7■ 大小: &f{value}%' +step-height: ' &3 &7■ 平稳行走: &f{value}' +burning-time: '&3 &7■ 燃烧时间: &f{value}%' +explosion-knockback-resistance: '&3 &7■ 爆炸击退抗性: &f{value}%' +mining-efficiency: '&3 &7■ 挖掘效率: &f{value}' +movement-efficiency: '&3 &7■ 移动效率: &f{value}%' +oxygen-bonus: '&3 &7■ 水下呼吸: &f{value}' +sneaking-speed: '&3 &7■ 潜行速度: &f{value}%' +submerged-mining-speed: '&3 &7■ 水下挖掘速度: &f{value}%' +sweeping-damage-ratio: '&3 &7■ 横扫伤害: &f{value}%' +water-movement-efficiency: '&3 &7■ 水下移动速度: &f{value}%' # Extra Options perm-effects: '&3 &7■ 永久效果 &f{effect}' diff --git a/pom.xml b/pom.xml index 2e758d89..de7369db 100644 --- a/pom.xml +++ b/pom.xml @@ -59,14 +59,22 @@ + phoenix https://nexus.phoenixdevt.fr/repository/maven-public/ + - nexus + lumine https://mvn.lumine.io/repository/maven-public/ + + + papermc + https://repo.papermc.io/repository/maven-public/ + +