From 766affefab1fe0c7df2c1cfbef8f4a5afe5b8e51 Mon Sep 17 00:00:00 2001 From: Jules Date: Sun, 19 Jan 2025 19:58:39 +0100 Subject: [PATCH] More bugfixing --- .../java/net/Indyuce/mmoitems/ItemStats.java | 90 +++--- .../net/Indyuce/mmoitems/StatCategories.java | 1 + .../net/Indyuce/mmoitems/api/CustomSound.java | 21 +- .../mmoitems/api/interaction/Consumable.java | 6 + .../api/item/mmoitem/LiveItemEditor.java | 6 +- .../api/item/template/MMOItemTemplate.java | 17 +- .../mmoitems/gui/CraftingStationView.java | 4 +- .../listener/CustomSoundListener.java | 109 ------- .../Indyuce/mmoitems/manager/StatManager.java | 14 +- .../net/Indyuce/mmoitems/stat/Abilities.java | 26 +- .../mmoitems/stat/ArrowPotionEffects.java | 2 +- .../mmoitems/stat/BrowserDisplayIDX.java | 8 +- .../net/Indyuce/mmoitems/stat/Crafting.java | 7 +- .../mmoitems/stat/CraftingPermission.java | 8 +- .../net/Indyuce/mmoitems/stat/Effects.java | 2 +- .../Indyuce/mmoitems/stat/ElementalStat.java | 189 ++---------- .../net/Indyuce/mmoitems/stat/GemSockets.java | 16 +- .../Indyuce/mmoitems/stat/RepairPower.java | 3 +- .../mmoitems/stat/ShieldPatternStat.java | 1 + .../net/Indyuce/mmoitems/stat/SoundStat.java | 291 +++++++----------- .../stat/component/type/ComponentType.java | 11 + .../type/builtin/MapComponentType.java | 15 +- .../type/builtin/ObjectComponentType.java | 78 ++++- .../type/builtin/StringComponentType.java | 1 - .../mmoitems/stat/type/IntegerStat.java | 2 - .../Indyuce/mmoitems/stat/type/ItemStat.java | 33 +- .../stat/type/extra/TemplateOption.java | 14 - .../Indyuce/mmoitems/util/RepairUtils.java | 4 +- .../listener/CustomSoundListener.java | 77 +++++ 29 files changed, 441 insertions(+), 615 deletions(-) delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/extra/TemplateOption.java create mode 100644 MMOItems-Dist/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java 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 5ee8a2db..db2283f2 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java @@ -64,48 +64,48 @@ public class ItemStats { public static final ItemStat DISABLE_ATTACK_PASSIVE = new DisableStat("ATTACK_PASSIVE", Material.BARRIER, "Disable On-Hit Effect", "Disables on-hit effects granted by the item type.", new String[]{"weapon"}); // RPG Stats - public static final ItemStat REQUIRED_LEVEL = new RequiredLevel(); + public static final RequiredLevel REQUIRED_LEVEL = new RequiredLevel(); public static final ItemStat> REQUIRED_CLASS = new RequiredClass(); - public static final ItemStat ATTACK_DAMAGE = new AttackDamage(); - public static final ItemStat ATTACK_SPEED = new AttackSpeed(); - public static final ItemStat CRITICAL_STRIKE_CHANCE = new DoubleStat("CRITICAL_STRIKE_CHANCE", Material.NETHER_STAR, "Critical Strike Chance", "Critical Strikes deal more damage, in % chance.", new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat CRITICAL_STRIKE_POWER = new DoubleStat("CRITICAL_STRIKE_POWER", Material.NETHER_STAR, "Critical Strike Power", new String[]{"The extra damage weapon crits deals.", "(Stacks with default value)", "In %."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat SKILL_CRITICAL_STRIKE_CHANCE = new DoubleStat("SKILL_CRITICAL_STRIKE_CHANCE", Material.NETHER_STAR, "Skill Critical Strike Chance", new String[]{"Increases the chance of dealing skill crits (in %)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat SKILL_CRITICAL_STRIKE_POWER = new DoubleStat("SKILL_CRITICAL_STRIKE_POWER", Material.NETHER_STAR, "Skill Critical Strike Power", new String[]{"Extra damage dealt (in %) by skill crits.", "(Stacks with default value)", "In %."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat BLOCK_POWER = new DoubleStat("BLOCK_POWER", Material.IRON_HELMET, "Block Power", new String[]{"The % of the damage your", "armor/shield can block.", "Default: 25%"}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat BLOCK_RATING = new DoubleStat("BLOCK_RATING", Material.IRON_HELMET, "Block Rating", new String[]{"The chance your piece of armor", "has to block any entity attack."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat BLOCK_COOLDOWN_REDUCTION = new DoubleStat("BLOCK_COOLDOWN_REDUCTION", Material.IRON_HELMET, "Block Cooldown Reduction", new String[]{"Reduces the blocking cooldown (%)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat DODGE_RATING = new DoubleStat("DODGE_RATING", Material.FEATHER, "Dodge Rating", new String[]{"The chance to dodge an attack.", "Dodging completely negates", "the attack damage."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat DODGE_COOLDOWN_REDUCTION = new DoubleStat("DODGE_COOLDOWN_REDUCTION", Material.FEATHER, "Dodge Cooldown Reduction", new String[]{"Reduces the dodging cooldown (%)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat PARRY_RATING = new DoubleStat("PARRY_RATING", Material.BUCKET, "Parry Rating", new String[]{"The chance to parry an attack.", "Parrying negates the damage", "and knocks the attacker back."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat PARRY_COOLDOWN_REDUCTION = new DoubleStat("PARRY_COOLDOWN_REDUCTION", Material.BUCKET, "Parry Cooldown Reduction", new String[]{"Reduces the parrying cooldown (%)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat COOLDOWN_REDUCTION = new DoubleStat("COOLDOWN_REDUCTION", Material.BOOK, "Cooldown Reduction", new String[]{"Reduces cooldowns of item and player skills (%)."}).setCategory(StatCategories.OFFENSE); - public static final ItemStat RANGE = new DoubleStat("RANGE", Material.STICK, "Range", new String[]{"The range of your item attacks."}, new String[]{"staff", "whip", "wand", "musket", "gem_stone"}).setCategory(StatCategories.RANGED_WEAPONS); + public static final AttackDamage ATTACK_DAMAGE = new AttackDamage(); + public static final AttackSpeed ATTACK_SPEED = new AttackSpeed(); + public static final ItemStat CRITICAL_STRIKE_CHANCE = new DoubleStat("CRITICAL_STRIKE_CHANCE", Material.NETHER_STAR, "Critical Strike Chance", "Critical Strikes deal more damage, in % chance.", new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat CRITICAL_STRIKE_POWER = new DoubleStat("CRITICAL_STRIKE_POWER", Material.NETHER_STAR, "Critical Strike Power", new String[]{"The extra damage weapon crits deals.", "(Stacks with default value)", "In %."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat SKILL_CRITICAL_STRIKE_CHANCE = new DoubleStat("SKILL_CRITICAL_STRIKE_CHANCE", Material.NETHER_STAR, "Skill Critical Strike Chance", new String[]{"Increases the chance of dealing skill crits (in %)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat SKILL_CRITICAL_STRIKE_POWER = new DoubleStat("SKILL_CRITICAL_STRIKE_POWER", Material.NETHER_STAR, "Skill Critical Strike Power", new String[]{"Extra damage dealt (in %) by skill crits.", "(Stacks with default value)", "In %."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat BLOCK_POWER = new DoubleStat("BLOCK_POWER", Material.IRON_HELMET, "Block Power", new String[]{"The % of the damage your", "armor/shield can block.", "Default: 25%"}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat BLOCK_RATING = new DoubleStat("BLOCK_RATING", Material.IRON_HELMET, "Block Rating", new String[]{"The chance your piece of armor", "has to block any entity attack."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat BLOCK_COOLDOWN_REDUCTION = new DoubleStat("BLOCK_COOLDOWN_REDUCTION", Material.IRON_HELMET, "Block Cooldown Reduction", new String[]{"Reduces the blocking cooldown (%)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat DODGE_RATING = new DoubleStat("DODGE_RATING", Material.FEATHER, "Dodge Rating", new String[]{"The chance to dodge an attack.", "Dodging completely negates", "the attack damage."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat DODGE_COOLDOWN_REDUCTION = new DoubleStat("DODGE_COOLDOWN_REDUCTION", Material.FEATHER, "Dodge Cooldown Reduction", new String[]{"Reduces the dodging cooldown (%)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat PARRY_RATING = new DoubleStat("PARRY_RATING", Material.BUCKET, "Parry Rating", new String[]{"The chance to parry an attack.", "Parrying negates the damage", "and knocks the attacker back."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat PARRY_COOLDOWN_REDUCTION = new DoubleStat("PARRY_COOLDOWN_REDUCTION", Material.BUCKET, "Parry Cooldown Reduction", new String[]{"Reduces the parrying cooldown (%)."}, new String[]{"!miscellaneous", "!block", "all"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat COOLDOWN_REDUCTION = new DoubleStat("COOLDOWN_REDUCTION", Material.BOOK, "Cooldown Reduction", new String[]{"Reduces cooldowns of item and player skills (%)."}).setCategory(StatCategories.OFFENSE); + public static final ItemStat RANGE = new DoubleStat("RANGE", Material.STICK, "Range", new String[]{"The range of your item attacks."}, new String[]{"staff", "whip", "wand", "musket", "gem_stone"}).setCategory(StatCategories.RANGED_WEAPONS); public static final DoubleStat MANA_COST = new ManaCost(); - public static final ItemStat STAMINA_COST = new DoubleStat("STAMINA_COST", Material.LIGHT_GRAY_DYE, "Stamina Cost", new String[]{"Stamina spent by your weapon to be used."}, new String[]{"weapon"}).setCategory(StatCategories.USE_COST); - public static final ItemStat ARROW_VELOCITY = new DoubleStat("ARROW_VELOCITY", Material.ARROW, "Arrow Velocity", new String[]{"Determines how far your", "weapon can shoot.", "Default: 1.0"}, new String[]{"gem_stone", "bow", "crossbow"}).setCategory(StatCategories.RANGED_WEAPONS); + public static final ItemStat STAMINA_COST = new DoubleStat("STAMINA_COST", Material.LIGHT_GRAY_DYE, "Stamina Cost", new String[]{"Stamina spent by your weapon to be used."}, new String[]{"weapon"}).setCategory(StatCategories.USE_COST); + public static final ItemStat ARROW_VELOCITY = new DoubleStat("ARROW_VELOCITY", Material.ARROW, "Arrow Velocity", new String[]{"Determines how far your", "weapon can shoot.", "Default: 1.0"}, new String[]{"gem_stone", "bow", "crossbow"}).setCategory(StatCategories.RANGED_WEAPONS); public static final ItemStat ARROW_POTION_EFFECTS = new ArrowPotionEffects(); - public static final ItemStat PVE_DAMAGE = new DoubleStat("PVE_DAMAGE", Material.PORKCHOP, "PvE Damage", new String[]{"Additional damage against", "non human entities in %."}, new String[]{"equipment", "gem_stone"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat PVP_DAMAGE = new DoubleStat("PVP_DAMAGE", Material.SKELETON_SKULL, "PvP Damage", new String[]{"Additional damage", "against players in %."}, new String[]{"equipment", "gem_stone"}).setCategory(StatCategories.OFFENSE); - public static final ItemStat BLUNT_POWER = new DoubleStat("BLUNT_POWER", Material.IRON_AXE, "Blunt Power", new String[]{"The radius of the AoE attack.", "If set to 2.0, enemies within 2 blocks", "around your target will take damage.", "&9This stat only applies to Blunt weapons."}, new String[]{"weapon", "gem_stone"}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat BLUNT_RATING = new DoubleStat("BLUNT_RATING", Material.BRICK, "Blunt Rating", new String[]{"The force of the blunt attack.", "If set to 50%, enemies hit by the attack", "will take 50% of the initial damage.", "&9This stat only applies to Blunt weapons."}, new String[]{"weapon", "gem_stone"}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat WEAPON_DAMAGE = new DoubleStat("WEAPON_DAMAGE", Material.IRON_SWORD, "Weapon Damage", new String[]{"Additional on-hit weapon damage in %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat SKILL_DAMAGE = new DoubleStat("SKILL_DAMAGE", Material.BOOK, "Skill Damage", new String[]{"Additional ability damage in %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat PROJECTILE_DAMAGE = new DoubleStat("PROJECTILE_DAMAGE", Material.ARROW, "Projectile Damage", new String[]{"Additional skill/weapon projectile damage."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat MAGIC_DAMAGE = new DoubleStat("MAGIC_DAMAGE", Material.MAGMA_CREAM, "Magic Damage", new String[]{"Additional magic skill damage in %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat PHYSICAL_DAMAGE = new DoubleStat("PHYSICAL_DAMAGE", Material.IRON_AXE, "Physical Damage", new String[]{"Additional skill/weapon physical damage."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat DEFENSE = new DoubleStat("DEFENSE", Material.SHIELD, "Defense", new String[]{"Reduces damage from any source.", "Formula can be set in MMOLib Config."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat DAMAGE_REDUCTION = new DoubleStat("DAMAGE_REDUCTION", Material.IRON_CHESTPLATE, "Damage Reduction", new String[]{"Reduces damage from any source.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat FALL_DAMAGE_REDUCTION = new DoubleStat("FALL_DAMAGE_REDUCTION", Material.FEATHER, "Fall Damage Reduction", new String[]{"Reduces fall damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat PROJECTILE_DAMAGE_REDUCTION = new DoubleStat("PROJECTILE_DAMAGE_REDUCTION", Material.SNOWBALL, "Projectile Damage Reduction", new String[]{"Reduces projectile damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat PHYSICAL_DAMAGE_REDUCTION = new DoubleStat("PHYSICAL_DAMAGE_REDUCTION", Material.LEATHER_CHESTPLATE, "Physical Damage Reduction", new String[]{"Reduces physical damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat FIRE_DAMAGE_REDUCTION = new DoubleStat("FIRE_DAMAGE_REDUCTION", Material.BLAZE_POWDER, "Fire Damage Reduction", new String[]{"Reduces fire damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat MAGIC_DAMAGE_REDUCTION = new DoubleStat("MAGIC_DAMAGE_REDUCTION", Material.POTION, "Magic Damage Reduction", new String[]{"Reduce magic damage dealt by potions.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat PVE_DAMAGE_REDUCTION = new DoubleStat("PVE_DAMAGE_REDUCTION", Material.PORKCHOP, "PvE Damage Reduction", new String[]{"Reduces damage dealt by mobs.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat PVP_DAMAGE_REDUCTION = new DoubleStat("PVP_DAMAGE_REDUCTION", Material.SKELETON_SKULL, "PvP Damage Reduction", new String[]{"Reduces damage dealt by players", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); - public static final ItemStat UNDEAD_DAMAGE = new DoubleStat("UNDEAD_DAMAGE", Material.SKELETON_SKULL, "Undead Damage", new String[]{"Deals additional damage to undead.", "In %."}).setCategory(StatCategories.OFFENSE); - public static final ItemStat LIFESTEAL = new DoubleStat("LIFESTEAL", Material.REDSTONE, "Lifesteal", new String[]{"Percentage of damage you gain back as", "health when inflicting weapon damage."}).setCategory(StatCategories.OFFENSE); - public static final ItemStat SPELL_VAMPIRISM = new DoubleStat("SPELL_VAMPIRISM", Material.REDSTONE, "Spell Vampirism", new String[]{"Percentage of damage you gain back as", "health when inflicting skill damage."}).setCategory(StatCategories.OFFENSE); + public static final ItemStat PVE_DAMAGE = new DoubleStat("PVE_DAMAGE", Material.PORKCHOP, "PvE Damage", new String[]{"Additional damage against", "non human entities in %."}, new String[]{"equipment", "gem_stone"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat PVP_DAMAGE = new DoubleStat("PVP_DAMAGE", Material.SKELETON_SKULL, "PvP Damage", new String[]{"Additional damage", "against players in %."}, new String[]{"equipment", "gem_stone"}).setCategory(StatCategories.OFFENSE); + public static final ItemStat BLUNT_POWER = new DoubleStat("BLUNT_POWER", Material.IRON_AXE, "Blunt Power", new String[]{"The radius of the AoE attack.", "If set to 2.0, enemies within 2 blocks", "around your target will take damage.", "&9This stat only applies to Blunt weapons."}, new String[]{"weapon", "gem_stone"}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat BLUNT_RATING = new DoubleStat("BLUNT_RATING", Material.BRICK, "Blunt Rating", new String[]{"The force of the blunt attack.", "If set to 50%, enemies hit by the attack", "will take 50% of the initial damage.", "&9This stat only applies to Blunt weapons."}, new String[]{"weapon", "gem_stone"}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat WEAPON_DAMAGE = new DoubleStat("WEAPON_DAMAGE", Material.IRON_SWORD, "Weapon Damage", new String[]{"Additional on-hit weapon damage in %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat SKILL_DAMAGE = new DoubleStat("SKILL_DAMAGE", Material.BOOK, "Skill Damage", new String[]{"Additional ability damage in %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat PROJECTILE_DAMAGE = new DoubleStat("PROJECTILE_DAMAGE", Material.ARROW, "Projectile Damage", new String[]{"Additional skill/weapon projectile damage."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat MAGIC_DAMAGE = new DoubleStat("MAGIC_DAMAGE", Material.MAGMA_CREAM, "Magic Damage", new String[]{"Additional magic skill damage in %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat PHYSICAL_DAMAGE = new DoubleStat("PHYSICAL_DAMAGE", Material.IRON_AXE, "Physical Damage", new String[]{"Additional skill/weapon physical damage."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat DEFENSE = new DoubleStat("DEFENSE", Material.SHIELD, "Defense", new String[]{"Reduces damage from any source.", "Formula can be set in MMOLib Config."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat DAMAGE_REDUCTION = new DoubleStat("DAMAGE_REDUCTION", Material.IRON_CHESTPLATE, "Damage Reduction", new String[]{"Reduces damage from any source.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat FALL_DAMAGE_REDUCTION = new DoubleStat("FALL_DAMAGE_REDUCTION", Material.FEATHER, "Fall Damage Reduction", new String[]{"Reduces fall damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat PROJECTILE_DAMAGE_REDUCTION = new DoubleStat("PROJECTILE_DAMAGE_REDUCTION", Material.SNOWBALL, "Projectile Damage Reduction", new String[]{"Reduces projectile damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat PHYSICAL_DAMAGE_REDUCTION = new DoubleStat("PHYSICAL_DAMAGE_REDUCTION", Material.LEATHER_CHESTPLATE, "Physical Damage Reduction", new String[]{"Reduces physical damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat FIRE_DAMAGE_REDUCTION = new DoubleStat("FIRE_DAMAGE_REDUCTION", Material.BLAZE_POWDER, "Fire Damage Reduction", new String[]{"Reduces fire damage.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat MAGIC_DAMAGE_REDUCTION = new DoubleStat("MAGIC_DAMAGE_REDUCTION", Material.POTION, "Magic Damage Reduction", new String[]{"Reduce magic damage dealt by potions.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat PVE_DAMAGE_REDUCTION = new DoubleStat("PVE_DAMAGE_REDUCTION", Material.PORKCHOP, "PvE Damage Reduction", new String[]{"Reduces damage dealt by mobs.", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat PVP_DAMAGE_REDUCTION = new DoubleStat("PVP_DAMAGE_REDUCTION", Material.SKELETON_SKULL, "PvP Damage Reduction", new String[]{"Reduces damage dealt by players", "In %."}).setCategory(StatCategories.DAMAGE_MITIGATION); + public static final ItemStat UNDEAD_DAMAGE = new DoubleStat("UNDEAD_DAMAGE", Material.SKELETON_SKULL, "Undead Damage", new String[]{"Deals additional damage to undead.", "In %."}).setCategory(StatCategories.OFFENSE); + public static final ItemStat LIFESTEAL = new DoubleStat("LIFESTEAL", Material.REDSTONE, "Lifesteal", new String[]{"Percentage of damage you gain back as", "health when inflicting weapon damage."}).setCategory(StatCategories.OFFENSE); + public static final ItemStat SPELL_VAMPIRISM = new DoubleStat("SPELL_VAMPIRISM", Material.REDSTONE, "Spell Vampirism", new String[]{"Percentage of damage you gain back as", "health when inflicting skill damage."}).setCategory(StatCategories.OFFENSE); // Extra Stats public static final ItemStat UNBREAKABLE = new Unbreakable(); @@ -170,13 +170,13 @@ public class ItemStats { public static final ItemStat MAX_CONSUME = new MaxConsume(); public static final ItemStat SUCCESS_RATE = new SuccessRate(); - public static final ItemStat// Crafting Stats - CRAFTING = new Crafting(); - public static final ItemStat CRAFT_PERMISSION = new CraftingPermission(); + // Crafting Stats + public static final Crafting CRAFTING = new Crafting(); + public static final CraftingPermission CRAFT_PERMISSION = new CraftingPermission(); //CRAFT_AMOUNT = new DoubleStat("CRAFTED_AMOUNT", Material.WOODEN_AXE, "Crafted Amount", new String[]{"The stack count for", "this item when crafted."}, new String[0]), - public static final ItemStat// Unique Stats - AUTOSMELT = new BooleanStat("AUTOSMELT", Material.COAL, "Autosmelt", "When toggled on, your tool will automatically smelt mined ores.", new String[]{"tool"}).setCategory(StatCategories.TOOLS); + // Unique (??) Stats + public static final ItemStat AUTOSMELT = new BooleanStat("AUTOSMELT", Material.COAL, "Autosmelt", "When toggled on, your tool will automatically smelt mined ores.", new String[]{"tool"}).setCategory(StatCategories.TOOLS); public static final ItemStat BOUNCING_CRACK = new BooleanStat("BOUNCING_CRACK", Material.COBBLESTONE_WALL, "Bouncing Crack", "When toggled on, your tool will also break nearby blocks.", new String[]{"tool"}).setCategory(StatCategories.TOOLS); public static final ItemStat PICKAXE_POWER = new PickaxePower(); //public static final ItemStatCUSTOM_SOUNDS = new CustomSounds(), @@ -210,7 +210,7 @@ public class ItemStats { public static final ItemStat DOWNGRADE_ON_DEATH = new BooleanStat("DEATH_DOWNGRADE", Material.DAMAGED_ANVIL, "Downgrade on Death", "If the wearer of this item dies, it may downgrade (based on &6Death Downgrade Chance &7stat).\nRequired to define an &6Upgrade Template.\nRequires keep-inventory gamerule. ", new String[]{"equipment"}).setCategory(StatCategories.UPGRADING); public static final ItemStat DOWNGRADE_ON_DEATH_CHANCE = new DoubleStat("DEATH_DOWNGRADE_CHANCE", Material.SKELETON_SKULL, "Death Downgrade Chance", "Probability that an item with &cDowngrade on Death &7will be downgraded when the player dies.\n\n Exceeding 100% will for sure downgrade one item, and roll again to downgrade another (with the excess probability). The same item won't be downgraded twice.", new String[]{"equipment"}, false).setCategory(StatCategories.UPGRADING); - // Unique Item Stats + // Unique (??) Item Stats public static final DyeColor DYE_COLOR = new DyeColor(); public static final ItemStat HIDE_DYE = new HideDye(); public static final ItemStat ARMOR_TRIM = new ArmorTrimStat(); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/StatCategories.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/StatCategories.java index a60f73b6..c17c76f3 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/StatCategories.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/StatCategories.java @@ -31,6 +31,7 @@ public class StatCategories { GENERAL = new StatCategory("GENERAL", "General", "General"), SPECIAL = new StatCategory("SPECIAL", "Special", "Special"), TOGGLES = new StatCategory("TOGGLES", "Toggles", "Toggles"), + SOUNDS = new StatCategory("SOUNDS", "Sounds", "Item Sounds"), MMOCORE_PROFESSIONS = new StatCategory("MMOCORE_PROFESSIONS", "MMOCore Professions", "MMOCore Professions", true), MMOCORE_ATTRIBUTES = new StatCategory("MMOCORE_ATTRIBUTES", "MMOCore Attributes", "MMOCore Attributes", true), ITEM = new StatCategory("ITEM", "Item & Texture", "Item & Texture"); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java index 59b929db..8b8d8349 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/CustomSound.java @@ -10,31 +10,36 @@ public enum CustomSound { ON_BLOCK_BREAK(Material.COBBLESTONE, 25, "Plays when a block is broken with the item."), ON_PICKUP(Material.IRON_INGOT, 28, "Plays when you pickup the item from the ground."), ON_LEFT_CLICK(Material.STONE_AXE, 31, "Plays when item is left-clicked."), - ON_CRAFT(Material.CRAFTING_TABLE, 34, "Plays when item is crafted in a crafting inventory", "or when smelted from someting in a furnace."), - ON_CONSUME(Material.APPLE, 37, "Plays when item has been consumed.", "(After eating/drinking animation)"), + ON_CRAFT(Material.CRAFTING_TABLE, 34, "Plays when item is crafted in a crafting inventory or when smelted from something in a furnace."), + ON_CONSUME(Material.APPLE, 37, "Plays when item has been consumed, after eating or drinking animation."), ON_ITEM_BREAK(Material.FLINT, 40, "Plays when the item breaks."), ON_CROSSBOW(Material.ARROW, 38, "Plays when a crossbow shoots an arrow."), ON_PLACED(Material.STONE, 43, "Plays when the block is placed."); - private final ItemStack item; - private final String[] lore; + private final Material icon; + private final String lore; private final int slot; - CustomSound(Material material, int slot, String... lore) { - this.item = new ItemStack(material); + CustomSound(Material icon, int slot, String lore) { + this.icon = icon; this.lore = lore; this.slot = slot; } + @Deprecated public ItemStack getItem() { - return item; + return new ItemStack(icon); + } + + public Material getIcon() { + return icon; } public String getName() { return UtilityMethods.caseOnWords(name().toLowerCase().replace('_', ' ')); } - public String[] getLore() { + public String getLore() { return lore; } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java index 229cd3ef..882b2b9d 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java @@ -5,13 +5,16 @@ import io.lumine.mythic.lib.api.item.ItemTag; import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.util.SmartGive; import io.lumine.mythic.lib.comp.flags.CustomFlag; +import io.lumine.mythic.lib.version.Sounds; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.CustomSound; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.event.item.ConsumableConsumedEvent; import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; import net.Indyuce.mmoitems.api.item.util.LoreUpdate; import net.Indyuce.mmoitems.api.player.PlayerData; +import net.Indyuce.mmoitems.stat.SoundStat; import net.Indyuce.mmoitems.stat.behaviour.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.behaviour.PlayerConsumable; import org.bukkit.Bukkit; @@ -80,6 +83,9 @@ public class Consumable extends UseItem { for (PlayerConsumable sc : MMOItems.plugin.getStats().getPlayerConsumables()) sc.onConsume(mmoitem, player, vanillaEeating); + // Play consume sound + SoundStat.playSound(nbtItem.getItem(), CustomSound.ON_CONSUME, event.getPlayer(), Sounds.ENTITY_GENERIC_EAT); + /** * If the item does not have a maximum amount of uses, this will always * return 0 and that portion will just skip. diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/LiveItemEditor.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/LiveItemEditor.java index 1bfb8e5b..73b3ab05 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/LiveItemEditor.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/LiveItemEditor.java @@ -2,16 +2,12 @@ package net.Indyuce.mmoitems.api.item.mmoitem; import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.api.Type; -import net.Indyuce.mmoitems.stat.component.StatComponent; -import net.Indyuce.mmoitems.stat.type.ItemStat; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; // TODO @Deprecated public class LiveItemEditor extends MMOItem { - public LiveItemEditor(NBTItem nbtItem) { + public LiveItemEditor(NBTItem item) { super(Type.get(item.getType()), item.getString("MMOITEMS_ITEM_ID")); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java index d4153b92..5f48114d 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java @@ -15,6 +15,7 @@ import net.Indyuce.mmoitems.api.player.RPGPlayer; import net.Indyuce.mmoitems.api.util.NumericStatFormula; import net.Indyuce.mmoitems.api.util.message.FFPMMOItems; import net.Indyuce.mmoitems.stat.component.model.Model; +import net.Indyuce.mmoitems.stat.component.type.builtin.VoidComponentType; import net.Indyuce.mmoitems.stat.data.random.RandomStatData; import net.Indyuce.mmoitems.stat.type.ItemStat; import org.apache.commons.lang.Validate; @@ -28,6 +29,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; public class MMOItemTemplate implements ItemReference, PreloadedObject { private final Type type; @@ -77,11 +79,16 @@ public class MMOItemTemplate implements ItemReference, PreloadedObject { try { final String id = UtilityMethods.enumName(key); final ItemStat stat = MMOItems.plugin.getStats().get(id); - Validate.notNull(stat, FriendlyFeedbackProvider.quickForConsole(FFPMMOItems.get(), "Could not find stat with ID '$i{0}$b'", id)); - // Check for a block with alternative syntax - boolean alternativeSyntax = MMOItems.plugin.getStats().checkAlternateYAMLSyntax(MMOItemTemplate.this, key, config::get); - if (alternativeSyntax) continue; + // [BACKWARDS COMPATIBILITY] Check for a block with alternative syntax + if (stat == null) { + boolean alternativeSyntax = MMOItems.plugin.getStats().checkAlternateYAMLSyntax(MMOItemTemplate.this, key, config.get("base." + key)); + if (alternativeSyntax) continue; + throw new RuntimeException(String.format("Could not find stat with ID '%s'", id)); + } + + // Don't load anything + if (stat.getComponentType() instanceof VoidComponentType) continue; // Load a model Model model = stat.getComponentType().fromConfig(config.get("base." + key)); @@ -91,6 +98,8 @@ public class MMOItemTemplate implements ItemReference, PreloadedObject { // Log ffp.log(FriendlyFeedbackCategory.INFORMATION, "Could not load base item data '$f{0}$b': {1}", key, exception.getMessage()); + MMOItems.plugin.getLogger().log(Level.INFO, "Could not load base item data '" + key + "'"); + exception.printStackTrace(); } // Print all failures diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/CraftingStationView.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/CraftingStationView.java index 4be068b9..2eb488b5 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/CraftingStationView.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/gui/CraftingStationView.java @@ -18,7 +18,7 @@ import net.Indyuce.mmoitems.api.event.PlayerUseCraftingStationEvent; import net.Indyuce.mmoitems.api.item.util.ConfigItems; import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.comp.eco.MoneyCondition; -import net.Indyuce.mmoitems.listener.CustomSoundListener; +import net.Indyuce.mmoitems.stat.SoundStat; import net.Indyuce.mmoitems.util.MMOUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -201,7 +201,7 @@ public class CraftingStationView extends PluginInventory { recipe.whenClaimed().forEach(trigger -> trigger.whenCrafting(playerData)); // Play sounds - CustomSoundListener.playSound(result, CustomSound.ON_CRAFT, player); + SoundStat.playSound(result, CustomSound.ON_CRAFT, player); if (!recipe.hasOption(Recipe.RecipeOption.SILENT_CRAFT)) player.playSound(player.getLocation(), station.getSound(), 1, 1); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java deleted file mode 100644 index badd52e6..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java +++ /dev/null @@ -1,109 +0,0 @@ -package net.Indyuce.mmoitems.listener; - -import net.Indyuce.mmoitems.api.CustomSound; -import net.Indyuce.mmoitems.api.util.SoundReader; -import io.lumine.mythic.lib.api.item.NBTItem; -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityPickupItemEvent; -import org.bukkit.event.inventory.CraftItemEvent; -import org.bukkit.event.inventory.FurnaceSmeltEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerItemBreakEvent; -import org.bukkit.event.player.PlayerItemConsumeEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class CustomSoundListener implements Listener { - @EventHandler(priority = EventPriority.HIGH) - public void a(EntityDamageByEntityEvent event) { - if (!(event.getDamager() instanceof Player) || !(event.getEntity() instanceof LivingEntity)) return; - - Player player = (Player) event.getDamager(); - playSound(player.getInventory().getItemInMainHand(), CustomSound.ON_ATTACK, player); - } - - @EventHandler(priority = EventPriority.HIGH) - public void b(EntityPickupItemEvent event) { - if (event.getEntityType().equals(EntityType.PLAYER)) - playSound(event.getItem().getItemStack(), CustomSound.ON_PICKUP, (Player) event.getEntity()); - } - - @EventHandler(priority = EventPriority.HIGH) - public void c(BlockBreakEvent event) { - playSound(event.getPlayer().getInventory().getItemInMainHand(), CustomSound.ON_BLOCK_BREAK, event.getPlayer()); - } - - @EventHandler - public void d(PlayerInteractEvent event) { - if (event.getAction() == Action.PHYSICAL || !event.hasItem()) return; - - if (event.getAction().name().contains("RIGHT_CLICK")) - playSound(event.getItem(), CustomSound.ON_RIGHT_CLICK, event.getPlayer()); - - if (event.getAction().name().contains("LEFT_CLICK")) - playSound(event.getItem(), CustomSound.ON_LEFT_CLICK, event.getPlayer()); - } - - @EventHandler(priority = EventPriority.HIGH) - public void e(CraftItemEvent event) { - playSound(event.getInventory().getResult(), CustomSound.ON_CRAFT, event.getWhoClicked().getLocation()); - } - - @EventHandler(priority = EventPriority.HIGH) - public void f(FurnaceSmeltEvent event) { - playSound(event.getResult(), CustomSound.ON_CRAFT, event.getBlock().getLocation()); - } - - @EventHandler(priority = EventPriority.HIGH) - public void g(PlayerItemConsumeEvent event) { - playSound(event.getItem(), CustomSound.ON_CONSUME, event.getPlayer()); - } - - @EventHandler(priority = EventPriority.HIGH) - public void h1(PlayerItemBreakEvent event) { - playSound(event.getBrokenItem(), CustomSound.ON_ITEM_BREAK, event.getPlayer()); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void i(BlockPlaceEvent event) { - playSound(event.getItemInHand(), CustomSound.ON_PLACED, event.getPlayer()); - } - - public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Player player) { - playSound(item, type, player.getLocation(), null); - } - - public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Player player, @Nullable Sound defaultSound) { - playSound(item, type, player.getLocation(), defaultSound); - } - - public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Location loc) { - playSound(item, type, loc, null); - } - - public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Location loc, @Nullable Sound defaultSound) { - if (item == null) return; - - final NBTItem nbt = NBTItem.get(item); - final String soundName = nbt.getString("MMOITEMS_SOUND_" + type.name()); - if (soundName == null || soundName.isEmpty()) { - if (defaultSound != null) loc.getWorld().playSound(loc, defaultSound, 1, 1); - return; - } - - final SoundReader sound = new SoundReader(soundName, defaultSound); - sound.play(loc, (float) nbt.getDouble("MMOITEMS_SOUND_" + type.name() + "_VOL"), (float) nbt.getDouble("MMOITEMS_SOUND_" + type.name() + "_PIT")); - } -} 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 6c27f338..d2cdb332 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 @@ -8,9 +8,12 @@ import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.StatCategories; import net.Indyuce.mmoitems.api.ConfigFile; +import net.Indyuce.mmoitems.api.CustomSound; import net.Indyuce.mmoitems.api.Type; +import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.stat.ElementalStat; +import net.Indyuce.mmoitems.stat.SoundStat; import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.behaviour.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.behaviour.ItemRestriction; @@ -33,6 +36,7 @@ import java.lang.reflect.Modifier; import java.util.*; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import java.util.logging.Level; public class StatManager { @@ -73,6 +77,7 @@ public class StatManager { // Load builtin stats forEachField(ItemStats.class, ItemStat.class, this::register, "Couldn't register stat called '%s': %s"); loadElementalStats(); // Needed on startup otherwise templates cant use them + loadSoundStats(); // Custom stats loadCustomStats(); @@ -104,6 +109,11 @@ public class StatManager { register(new ElementalStat(element, type)); } + private void loadSoundStats() { + for (CustomSound sound : CustomSound.values()) + register(new SoundStat(sound)); + } + public void reload(boolean cleanFirst) { // Unregister stats that require it @@ -153,10 +163,10 @@ public class StatManager { @BackwardsCompatibility(version = "6.10.1") public boolean checkAlternateYAMLSyntax(@NotNull MMOItemTemplate template, @NotNull String configKey, - @NotNull Function supplier) { + @NotNull Object syntaxBlock) { final SyntaxAdapter adapter = yamlSyntaxAdapters.get(UtilityMethods.enumName(configKey).toLowerCase()); // Snake case final boolean result = adapter != null; - if (result) adapter.adapt(template, supplier.apply(configKey)); + if (result) adapter.adapt(template, syntaxBlock); return result; } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java index d2737100..8cbd472b 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Abilities.java @@ -12,9 +12,7 @@ import net.Indyuce.mmoitems.stat.component.model.Model; import net.Indyuce.mmoitems.stat.component.model.builtin.NumberModel; import net.Indyuce.mmoitems.stat.component.model.builtin.ObjectModel; import net.Indyuce.mmoitems.stat.component.type.ComponentType; -import net.Indyuce.mmoitems.stat.component.type.builtin.ArrayComponentType; -import net.Indyuce.mmoitems.stat.component.type.builtin.ObjectComponentType; -import net.Indyuce.mmoitems.stat.component.type.builtin.StringComponentType; +import net.Indyuce.mmoitems.stat.component.type.builtin.*; import net.Indyuce.mmoitems.stat.type.ItemStat; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -29,18 +27,25 @@ public class Abilities extends ItemStat> { public Abilities() { super("ABILITY", new String[]{"!block", "all"}); - ComponentType modifierMapType = ObjectComponentType.init() - .build(); - ComponentType abilityType = ObjectComponentType.init() .implementation(AbilityComponent::new) - .addField("ability", StringComponentType.skillHandler() + + .addField("Id", "type", StringComponentType.skillHandler() .icon(Material.FIRE_CHARGE) .name("Ability").build()) - .addField("mode", StringComponentType.triggerType() + + .addField("CastMode", "mode", StringComponentType.triggerType() .icon(Material.COMMAND_BLOCK_MINECART) .name("Trigger").build()) - .addField("modifiers", modifierMapType) + + .addField("Modifiers", MapComponentType.mapOf(NumberComponentType.decimal().build()) + .validateKeys(str -> !str.equals("mode") && !str.equals("type")) // Backwards compatibility + .name("Ability Modifiers") + .icon(Material.BLAZE_POWDER) + .trimdesc("Edit cooldown, mana usage, damage dealt, duration... or any other numerical parameter of your skill.") + .flattened(true) + .build()) + .icon(Material.FIRE_CHARGE) .name(obj -> { // UI render name of ability @@ -70,7 +75,6 @@ public class Abilities extends ItemStat> { return lore; }) - //.setFlattened(true) .build(); // TODO ui display rules @@ -81,8 +85,6 @@ public class Abilities extends ItemStat> { .name("Abilities") .trimdesc("Make your item cast amazing abilities to kill monsters or buff yourself. Abilities can be actively cast, set on a timer or triggered by specific world events. Custom abilities can be created using MythicLib, MythicMobs, Fabled...") .build()); - - // TODO config syntax adapter needed for the modifier part. } private String generalFormat, modifierIfAny, modifierForEach, modifierSplitter, abilitySplitter, modifierNewLine; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ArrowPotionEffects.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ArrowPotionEffects.java index feb06506..626b6eba 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ArrowPotionEffects.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ArrowPotionEffects.java @@ -38,7 +38,7 @@ public class ArrowPotionEffects extends ItemStat .addField("duration", NumberComponentType.decimal() .icon(Material.CLOCK) .name("Effect Duration").build()) - .stringSeparatedStringFormat(" ") + .stringSeparatedStringFormat(" ", false) .icon(Material.TIPPED_ARROW) .name("Potion Effect") .build(); 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 72721995..03dab1de 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 @@ -4,8 +4,8 @@ import net.Indyuce.mmoitems.ItemStats; 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.component.model.builtin.NumberModel; import net.Indyuce.mmoitems.stat.type.IntegerStat; -import net.Indyuce.mmoitems.stat.type.extra.TemplateOption; import org.bukkit.Material; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -16,13 +16,15 @@ import java.util.HashMap; import java.util.Map; @HasCategory(cat = "template_option") -public class BrowserDisplayIDX extends IntegerStat implements TemplateOption { +public class BrowserDisplayIDX extends IntegerStat { public BrowserDisplayIDX() { super("BROWSER_IDX", Material.GHAST_TEAR, "Browser Index", "Used to display similar items together, neatly in the GUI &a/mmoitems browse. &7Items with the same index are grouped.", null); + + setTemplateOption(true); } /** @@ -41,7 +43,7 @@ public class BrowserDisplayIDX extends IntegerStat implements TemplateOption { Double armorIDX = null; if (template.getType().getAvailableStats().contains(ItemStats.BROWSER_DISPLAY_IDX)) { - NumericStatFormula indexData = (NumericStatFormula) template.getModels().get(ItemStats.BROWSER_DISPLAY_IDX); + NumericStatFormula indexData = ((NumberModel) template.getModels().get(ItemStats.BROWSER_DISPLAY_IDX)).getFormula(); // Get value if it existed if (indexData != null && indexData.getBase() != 0) { armorIDX = indexData.getBase(); } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java index 428b9e42..f5478299 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java @@ -16,7 +16,6 @@ import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.component.builtin.VoidComponent; import net.Indyuce.mmoitems.stat.component.type.builtin.VoidComponentType; import net.Indyuce.mmoitems.stat.type.ItemStat; -import net.Indyuce.mmoitems.stat.type.extra.TemplateOption; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -26,7 +25,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @HasCategory(cat = "misc") -public class Crafting extends ItemStat implements TemplateOption { +public class Crafting extends ItemStat { public Crafting() { super("CRAFTING", null); @@ -35,6 +34,8 @@ public class Crafting extends ItemStat implements TemplateOption .name("Crafting Recipes") .trimdesc("The crafting recipes of your item. Changing a recipe requires &o/mi reload recipes&7.") .build()); + + setTemplateOption(true); } @Override @@ -45,7 +46,7 @@ public class Crafting extends ItemStat implements TemplateOption @Nullable @Override public VoidComponent read(ReadMMOItem mmoitem) { - throw new RuntimeException("Not supported"); + return null; } @Deprecated diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CraftingPermission.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CraftingPermission.java index b2ce07b9..0080e729 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CraftingPermission.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/CraftingPermission.java @@ -2,16 +2,14 @@ package net.Indyuce.mmoitems.stat; import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.type.StringStat; -import net.Indyuce.mmoitems.stat.type.extra.TemplateOption; import org.bukkit.Material; @HasCategory(cat = "template_option") -public class CraftingPermission extends StringStat implements TemplateOption { +public class CraftingPermission extends StringStat { public CraftingPermission() { - super("CRAFT_PERMISSION", Material.OAK_SIGN, "Crafting Recipe Permission", - "The permission needed to craft this item. Changing this value requires &o/mi reload recipes&7.", - null); + super("CRAFT_PERMISSION", Material.OAK_SIGN, "Crafting Recipe Permission", "The permission needed to craft this item. Changing this value requires &o/mi reload recipes&7.", null); setGemstoneTransferable(false); + setTemplateOption(true); } } \ No newline at end of file diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Effects.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Effects.java index ae9ed3c8..c7514422 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Effects.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/Effects.java @@ -40,7 +40,7 @@ public class Effects extends ItemStat> implement public static ComponentType potionEffectComponentType() { return ObjectComponentType.init() .implementation(PotionEffectComponent::new) - .stringSeparatedStringFormat(" ") + .stringSeparatedStringFormat(" ", false) .addField("Type", StringComponentType.potionEffectType() .icon(Material.POTION) .name("Potion Effect Type") diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ElementalStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ElementalStat.java index 06676e4c..26feacbd 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ElementalStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ElementalStat.java @@ -1,6 +1,7 @@ package net.Indyuce.mmoitems.stat; import io.lumine.mythic.lib.element.Element; +import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.util.NumericStatFormula; import net.Indyuce.mmoitems.stat.annotation.HasCategory; @@ -11,15 +12,29 @@ import net.Indyuce.mmoitems.stat.yaml.SyntaxAdapter; import net.Indyuce.mmoitems.util.ElementStatType; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; @HasCategory(cat = "elements") public class ElementalStat extends DoubleStat { + private final Element element; + private final ElementStatType statType; + public ElementalStat(Element element, ElementStatType statType) { - super(statType.getConcatenatedTagPath(element), new String[]{"equipment", "ornament", "gem_stone"}); + super(statType.getConcatenatedTagPath(element), + element.getIcon(), + String.format("%s %s", element.getName(), statType.getName()), + "Elemental stat.", + new String[]{"equipment", "ornament", "gem_stone"}); + + this.element = element; + this.statType = statType; setRemoveOnReload(true); + + registerAlternateYAMLSyntax(ALTERNATE_SYNTAX); } + @BackwardsCompatibility(version = "7.0") public static final SyntaxAdapter ALTERNATE_SYNTAX = new SyntaxAdapter("element", (template, obj) -> { Validate.isTrue(obj instanceof ConfigurationSection, "Not a configuration section"); @@ -38,184 +53,24 @@ public class ElementalStat extends DoubleStat { } }); - /* - public static void updateComponentType() { - - ItemStat stat = MMOItems.plugin.getStats().get("ELEMENT"); - ObjectComponentType.Builder builder = ObjectComponentType.object(); - for (Element element : MythicLib.plugin.getElements().getAll()) - for (ElementStatType statType : ElementStatType.values()) - builder.addField(statType.getConcatenatedTagPath(element).toLowerCase(), DoubleComponentType.numeric() - .setIcon(element.getIcon()) - .setName(element.getName() + " " + statType.getName()) - .build()); - stat.setComponentType(builder - .acceptTreedConfigPaths(true) - //.setKey("ELEMENT") - .setIcon(Material.MAGMA_CREAM) - .setName("Elemental Stats") - .trimLore("Have the weapon deal on-hit elemental damage, reduce or increase incoming elemental damage.") - .setActionLoreTags("Click to edit elemental stats.", "Right click to reset elements") - .build()); - } - - @Override - public RandomElementListData whenInitialized(Object object) { - Validate.isTrue(object instanceof ConfigurationSection, "Must specify a config section"); - return new RandomElementListData((ConfigurationSection) object); - } - - @Deprecated - public void whenDisplayed(List lore, Optional statData) { - - if (statData.isPresent()) { - lore.add(ChatColor.GRAY + "Current Value:"); - RandomElementListData data = statData.get(); - data.getKeys().forEach(key -> lore.add(ChatColor.GRAY + "* " + key.getKey().getName() + " " + key.getValue().getName() + ": " + ChatColor.RED + data.getStat(key.getKey(), key.getValue()))); - - } else - lore.add(ChatColor.GRAY + "Current Value: " + ChatColor.RED + "None"); - - lore.add(""); - lore.add(ChatColor.YELLOW + AltChar.listDash + " Click to access the elements edition menu."); - lore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to remove all the elements."); - } - - @NotNull - @Override - public ElementListData getClearStatData() { - return new ElementListData(); - } - - private Map statFormat = new HashMap<>(); - @Override + @BackwardsCompatibility(version = "unspecified") public void readTranslationFile(@NotNull ConfigurationSection translationFile) { + String ifError = String.format("", element.getId(), statType.lowerCaseName()); // Up-to-date code Object configObject = translationFile.get("element"); if (configObject instanceof ConfigurationSection) { - final ConfigurationSection config = (ConfigurationSection) configObject; - for (ElementStatType statType : ElementStatType.values()) - statFormat.put(statType, config.getString(statType.lowerCaseName(), "")); + parseAndSetGeneralStatFormat(((ConfigurationSection) configObject).getString(statType.lowerCaseName(), ifError)); } // LEGACY CODE else { - for (ElementStatType statType : ElementStatType.values()) - statFormat.put(statType, translationFile.getString("elemental-" + statType.lowerCaseName(), "")); + parseAndSetGeneralStatFormat(translationFile.getString("elemental-" + statType.lowerCaseName(), ifError)); } } - @NotNull - private String formatForLore(Element element, ElementStatType statType) { - return statFormat.get(statType) - .replace("{color}", element.getColor()) - .replace("{icon}", element.getLoreIcon()) - .replace("{element}", element.getName()); + private void parseAndSetGeneralStatFormat(@NotNull String format) { + generalStatFormat = format.replace("{color}", element.getColor()).replace("{icon}", element.getLoreIcon()).replace("{element}", element.getName()); } - - @Override - public void whenApplied(@NotNull ItemStackBuilder item, @NotNull ElementListData data) { - - List lore = new ArrayList<>(); - - // Write Lore - for (Pair pair : data.getKeys()) { - final String format = formatForLore(pair.getKey(), pair.getValue()); - final double value = data.getStat(pair.getKey(), pair.getValue()); - lore.add(DoubleStat.formatPath("ELEMENTAL_STAT", format, true, value)); - } - - // Insert non-empty lore - if (!lore.isEmpty()) - item.getLore().insert("elements", lore); - - // Addtags - item.addItemTag(getAppliedNBT(data)); - } - - @NotNull - @Override - public ArrayList getAppliedNBT(@NotNull ElementListData data) { - - // Create Array - ArrayList ret = new ArrayList<>(); - for (Pair pair : data.getKeys()) - ret.add(new ItemTag("MMOITEMS_" + pair.getValue().getConcatenatedTagPath(pair.getKey()), data.getStat(pair.getKey(), pair.getValue()))); - - // Thats it - return ret; - } - - @Override - public void whenLoaded(@NotNull ReadMMOItem mmoitem) { - - // Seek the relevant tags - ArrayList relevantTags = new ArrayList<>(); - for (Element element : Element.values()) - for (ElementStatType statType : ElementStatType.values()) { - final String path = "MMOITEMS_" + statType.getConcatenatedTagPath(element); - if (mmoitem.getNBT().hasTag(path)) - relevantTags.add(ItemTag.getTagAtPath(path, mmoitem.getNBT(), SupportedNBTTagValues.DOUBLE)); - } - - // Generate Data - StatData data = getLoadedNBT(relevantTags); - - // Found? - if (data != null) { - mmoitem.setData(this, data); - } - } - - @Nullable - @Override - public ElementListData getLoadedNBT(@NotNull ArrayList storedTags) { - - // Create new - ElementListData elements = new ElementListData(); - - // Try to find every existing element - for (Element element : Element.values()) - for (ElementStatType statType : ElementStatType.values()) { - final String path = "MMOITEMS_" + statType.getConcatenatedTagPath(element); - ItemTag tag = ItemTag.getTagAtPath(path, storedTags); - if (tag != null) - elements.setStat(element, statType, (double) tag.getValue()); - } - - return elements.isEmpty() ? null : elements; - } - - @Override - public void whenPreviewed(@NotNull ItemStackBuilder item, @NotNull ElementListData currentData, @NotNull RandomElementListData templateData) throws IllegalArgumentException { - Validate.isTrue(currentData instanceof ElementListData, "Current Data is not ElementListData"); - Validate.isTrue(templateData instanceof RandomElementListData, "Template Data is not RandomElementListData"); - - List elementLore = new ArrayList<>(); - - // Examine every element stat possible - for (Element element : Element.values()) - for (ElementStatType statType : ElementStatType.values()) { - - NumericStatFormula nsf = templateData.getStat(element, statType); - - // Get Value - final double techMinimum = nsf.calculate(0, NumericStatFormula.FormulaInputType.LOWER_BOUND); - final double techMaximum = nsf.calculate(0, NumericStatFormula.FormulaInputType.UPPER_BOUND); - - // Display if not ZERO - if (techMinimum != 0 || techMaximum != 0) { - final String builtRange = DoubleStat.formatPath(statType.getConcatenatedTagPath(element), formatForLore(element, statType), true, techMinimum, techMaximum); - elementLore.add(builtRange); - } - } - - if (!elementLore.isEmpty()) item.getLore().insert("elements", elementLore); - - // Add tags - item.addItemTag(getAppliedNBT(currentData)); - } - */ } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/GemSockets.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/GemSockets.java index 16e7360c..4a4ed9ea 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/GemSockets.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/GemSockets.java @@ -34,10 +34,14 @@ public class GemSockets extends ItemStat { public GemSockets() { super("GEM_SOCKETS", new String[]{"!gem_stone", "equipment", "ornament"}); + // No description needed, the UI directly skips the "gemsockets/gemstones" level. setComponentType(ObjectComponentType.init() - // No description needed, the UI directly skips the object level. - .addField("EmptySlots", ArrayComponentType.arrayOf(StringComponentType.init().build()).build()) + .addField("EmptySlots", ArrayComponentType.arrayOf(StringComponentType.init().build()) + .icon(Material.EMERALD) + .name("Gem Sockets") + .trimdesc("The amount of gem sockets naturally present on your item.") + .build()) // Gemstones (internal) part .addField("Gemstones", ArrayComponentType.arrayOf(ObjectComponentType.init() @@ -47,9 +51,6 @@ public class GemSockets extends ItemStat { .build()) .implementation(GemstonesComponent::new) - .icon(Material.EMERALD) - .name("Gem Sockets") - .trimdesc("The amount of gem sockets naturally present on your item.") .build()); } @@ -88,9 +89,10 @@ public class GemSockets extends ItemStat { // Find upgrade level int itemLevel = builder.getMMOItem().hasUpgradeTemplate() ? builder.getMMOItem().getUpgradeLevel() : 0; - // Applied gemstones List lore = new ArrayList<>(); - if (component.getGemstones() != null) for (GemstoneComponent gem : component.getGemstones()) { + + // Applied gemstones + for (GemstoneComponent gem : component.getGemstones()) { String gemName = gem.getName(); // Upgrades? diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java index fdeb1ea8..55809089 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java @@ -8,7 +8,6 @@ import net.Indyuce.mmoitems.api.interaction.Consumable; import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.message.Message; -import net.Indyuce.mmoitems.listener.CustomSoundListener; import net.Indyuce.mmoitems.stat.annotation.HasCategory; import net.Indyuce.mmoitems.stat.behaviour.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.type.DoubleStat; @@ -67,7 +66,7 @@ public class RepairPower extends DoubleStat implements ConsumableItemInteraction Message.REPAIRED_ITEM .format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(repairPower)) .send(player); - CustomSoundListener.playSound(consumable.getItem(), CustomSound.ON_CONSUME, player); + SoundStat.playSound(consumable.getItem(), CustomSound.ON_CONSUME, player); return true; } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ShieldPatternStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ShieldPatternStat.java index ad786a18..ba63ae82 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ShieldPatternStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/ShieldPatternStat.java @@ -51,6 +51,7 @@ public class ShieldPatternStat extends ItemStat { .icon(Material.SHIELD) .name("Layers") .trimdesc("Edit pattern layers here") + .flattened(true) .build()) .icon(Material.SHIELD) diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoundStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoundStat.java index 7d7fb8d1..5c9ce520 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoundStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/SoundStat.java @@ -1,215 +1,132 @@ package net.Indyuce.mmoitems.stat; -import net.Indyuce.mmoitems.stat.type.StringStat; +import io.lumine.mythic.lib.api.item.ItemTag; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.CustomSound; +import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder; +import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem; +import net.Indyuce.mmoitems.api.util.SoundReader; +import net.Indyuce.mmoitems.stat.annotation.HasCategory; +import net.Indyuce.mmoitems.stat.component.builtin.DoubleComponent; +import net.Indyuce.mmoitems.stat.component.builtin.ObjectComponent; +import net.Indyuce.mmoitems.stat.component.builtin.ObjectComponentImpl; +import net.Indyuce.mmoitems.stat.component.builtin.StringComponent; +import net.Indyuce.mmoitems.stat.component.type.builtin.NumberComponentType; +import net.Indyuce.mmoitems.stat.component.type.builtin.ObjectComponentType; +import net.Indyuce.mmoitems.stat.component.type.builtin.StringComponentType; +import net.Indyuce.mmoitems.stat.type.ItemStat; +import net.Indyuce.mmoitems.stat.yaml.SyntaxAdapter; +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class SoundStat extends StringStat { - public SoundStat(String id, String[] types) { - super("SOUND", null); +import java.util.logging.Level; + +/** + * The only not directly mapped stat. + */ +@HasCategory(cat = "sounds") +public class SoundStat extends ItemStat { + private final String pathSound, pathVolume, pathPitch; + + public SoundStat(CustomSound sound) { + super(String.format("MMOITEMS_SOUND_%s", sound.name()), null); + + pathSound = getNBTPath(); + pathVolume = getNBTPath() + "_VOL"; + pathPitch = getNBTPath() + "_PIT"; + + setComponentType(ObjectComponentType.init() + .addField("Sound", StringComponentType.init().build()) + .addField("Volume", NumberComponentType.decimal().build()) + .addField("Pitch", NumberComponentType.decimal().build()) + .stringSeparatedStringFormat(" ", false) + + .icon(Material.NOTE_BLOCK) + .name(String.format("%s Sound", sound.getName())) + .inputable(true) + .trimdesc(sound.getLore()) + .build()); + + setDisplayInLore(false); + registerAlternateYAMLSyntax(LEGACY_SYNTAX); } - -/* -@HasCategory(cat = "misc") -public class CustomSounds extends ItemStat implements GemStoneStat, PlayerConsumable { - public CustomSounds() { - super("SOUNDS", Material.JUKEBOX, "Custom Sounds", new String[]{"The custom sounds your item will use."}, - new String[0]); - } - - @Override - public SoundListData whenInitialized(Object object) { - Validate.isTrue(object instanceof ConfigurationSection, "Must specify a config section"); + private static final SyntaxAdapter LEGACY_SYNTAX = new SyntaxAdapter("sounds", (template, object) -> { + MMOItems.plugin.getLogger().log(Level.INFO, "got: " + object.toString()); + Validate.isTrue(object instanceof ConfigurationSection, "Expecting a config section"); ConfigurationSection config = (ConfigurationSection) object; - SoundListData sounds = new SoundListData(); - for (CustomSound sound : CustomSound.values()) { String path = sound.name().replace("_", "-").toLowerCase(); - if (config.contains(path)) - sounds.set(sound, new SoundData(config.get(path))); + Object configObject = config.get(path); + if (configObject == null) continue; + + String statId = String.format("MMOITEMS_SOUND_%s", sound.name()); + ItemStat soundStat = (ItemStat) MMOItems.plugin.getStats().get(statId); + Validate.notNull(soundStat, String.format("Could not find sound stat with ID '%s'", statId)); + template.getModels().put(soundStat, soundStat.getComponentType().fromConfig(configObject)); + } + }); + + @Nullable + @Override + @BackwardsCompatibility(version = "7.0") + public ObjectComponent read(ReadMMOItem mmoitem) { + + String found = mmoitem.getNBT().getString(pathSound); + if (found != null && !found.isEmpty()) { + ObjectComponent comp = new ObjectComponentImpl(); + + comp.set("Sound", new StringComponent(found)); + comp.set("Volume", new DoubleComponent(mmoitem.getNBT().getDouble(pathVolume))); + comp.set("Pitch", new DoubleComponent(mmoitem.getNBT().getDouble(pathPitch))); + + return comp; } - return sounds; - } - - @Deprecated - public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) { - String soundsPath = (String) info[0]; - String[] split = message.split(" "); - Validate.isTrue(split.length == 3, message + " is not a valid [SOUND NAME] [VOLUME] [PITCH]."); - - String soundName = split[0].replace("-", "_"); - double volume = MMOUtils.parseDouble(split[1]); - double pitch = MMOUtils.parseDouble(split[2]); - - inv.getEditedSection().set("sounds." + soundsPath + ".sound", soundName); - inv.getEditedSection().set("sounds." + soundsPath + ".volume", volume); - inv.getEditedSection().set("sounds." + soundsPath + ".pitch", pitch); - - inv.registerTemplateEdition(); - inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + ChatColor.RED + UtilityMethods.caseOnWords(soundsPath.replace(".", " ")) + ChatColor.GRAY - + " successfully changed to '" + soundName + "'."); - } - - public void whenDisplayed(List lore, Optional statData) { - - if (statData.isPresent()) { - lore.add(ChatColor.GRAY + "Current Value:"); - SoundListData data = (SoundListData) statData.get(); - data.mapData() - .forEach((sound, - soundData) -> lore.add(ChatColor.GRAY + "* " + ChatColor.GREEN - + UtilityMethods.caseOnWords(sound.getName().toLowerCase().replace("-", " ").replace("_", " ")) + ChatColor.GRAY + ": " - + ChatColor.RED + soundData.getVolume() + " " + soundData.getPitch())); - } else - lore.add(ChatColor.GRAY + "Current Value: " + ChatColor.RED + "None"); - - lore.add(""); - lore.add(ChatColor.YELLOW + AltChar.listDash + " Click to access the sounds edition menu."); - lore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to remove all custom sounds."); + return readJsonFromNbt(mmoitem); } @Override - public @NotNull SoundListData getClearStatData() { - return new SoundListData(); + @BackwardsCompatibility(version = "7.0") + public void write(ItemStackBuilder builder, @NotNull ObjectComponent component) { + builder.addItemTag(new ItemTag(pathSound, component.get("Sound"))); + builder.addItemTag(new ItemTag(pathVolume, component.get("Volume"))); + builder.addItemTag(new ItemTag(pathPitch, component.get("Pitch"))); } - @Override - public void whenApplied(@NotNull ItemStackBuilder item, @NotNull SoundListData data) { - item.addItemTag(getAppliedNBT(data)); + public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Player player) { + playSound(item, type, player.getLocation(), null); } - @Override - public @NotNull ArrayList getAppliedNBT(@NotNull SoundListData data) { - - // Make Array - ArrayList ret = new ArrayList<>(); - - // Well that - SoundListData sounds = (SoundListData) data; - - // Add - sounds.getCustomSounds().forEach(sound -> { - SoundData value = sounds.get(sound); - - ret.add(new ItemTag("MMOITEMS_SOUND_" + sound.name(), value.getSound())); - ret.add(new ItemTag("MMOITEMS_SOUND_" + sound.name() + "_VOL", value.getVolume())); - ret.add(new ItemTag("MMOITEMS_SOUND_" + sound.name() + "_PIT", value.getPitch())); - }); - - // Yes - return ret; + public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Player player, @Nullable Sound defaultSound) { + playSound(item, type, player.getLocation(), defaultSound); } - public @Nullable SoundListData getLoadedNBT(@NotNull ArrayList data) { - - // Something to build - SoundListData sounds = new SoundListData(); - - // For each value - for (CustomSound sound : CustomSound.values()) { - - // Find tag? - ItemTag soundTag = ItemTag.getTagAtPath("MMOITEMS_SOUND_" + sound.name(), data); - ItemTag volumeTag = ItemTag.getTagAtPath("MMOITEMS_SOUND_" + sound.name() + "_VOL", data); - ItemTag pitchTag = ItemTag.getTagAtPath("MMOITEMS_SOUND_" + sound.name() + "_PIT", data); - - // Not null righ - if (soundTag != null && volumeTag != null && pitchTag != null) { - - // Get as String - String soundName = (String) soundTag.getValue(); - Double volume = (Double) volumeTag.getValue(); - Double pitch = (Double) pitchTag.getValue(); - - // If valid - if (!soundName.isEmpty()) { - - // Set - sounds.set(sound, new SoundData(soundName, volume, pitch)); - } - } - } - - // Return that amount - if (sounds.getCustomSounds().size() > 0) { - - // Yes - return sounds; - } - - // Failure: No sounds - return null; + public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Location loc) { + playSound(item, type, loc, null); } - @Override - public void whenLoaded(@NotNull ReadMMOItem mmoitem) { + public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Location loc, @Nullable Sound defaultSound) { + if (item == null) return; - // Get tags - ArrayList relevantTags = new ArrayList<>(); - - for (CustomSound sound : CustomSound.values()) { - - // Find tag? - ItemTag soundTag = null; - ItemTag volumeTag = null; - ItemTag pitchTag = null; - - if (mmoitem.getNBT().hasTag("MMOITEMS_SOUND_" + sound.name())) - soundTag = ItemTag.getTagAtPath("MMOITEMS_SOUND_" + sound.name(), mmoitem.getNBT(), SupportedNBTTagValues.STRING); - - if (mmoitem.getNBT().hasTag("MMOITEMS_SOUND_" + sound.name() + "_VOL")) - volumeTag = ItemTag.getTagAtPath("MMOITEMS_SOUND_" + sound.name() + "_VOL", mmoitem.getNBT(), SupportedNBTTagValues.DOUBLE); - - if (mmoitem.getNBT().hasTag("MMOITEMS_SOUND_" + sound.name() + "_PIT")) - pitchTag = ItemTag.getTagAtPath("MMOITEMS_SOUND_" + sound.name() + "_PIT", mmoitem.getNBT(), SupportedNBTTagValues.DOUBLE); - - // All or none - if (soundTag != null && volumeTag != null && pitchTag != null) { - - // Include - relevantTags.add(soundTag); - relevantTags.add(volumeTag); - relevantTags.add(pitchTag); - } - } - - // Use that - SoundListData sounds = (SoundListData) getLoadedNBT(relevantTags); - - // Valid? - if (sounds != null) { - - // Set - mmoitem.setData(ItemStats.CUSTOM_SOUNDS, sounds); - } - } - - @Override - public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) { - - // No sound, straight up default-yo - if (!mmo.hasData(ItemStats.CUSTOM_SOUNDS)) { - playDefaultSound(player); + final NBTItem nbt = NBTItem.get(item); + final String soundName = nbt.getString("MMOITEMS_SOUND_" + type.name()); + if (soundName == null || soundName.isEmpty()) { + if (defaultSound != null) loc.getWorld().playSound(loc, defaultSound, 1, 1); return; } - // Find data - SoundListData slData = (SoundListData) mmo.getData(ItemStats.CUSTOM_SOUNDS); - SoundData cs = slData.get(CustomSound.ON_CONSUME); - - // Default sound :sleep: - if (cs == null) playDefaultSound(player); - - // Play custom sound lets go - else { - String fixedSoundName = cs.getSound().toLowerCase().replace("_", "."); - player.getWorld().playSound(player.getLocation(), fixedSoundName, (float) cs.getVolume(), (float) cs.getPitch()); - } + final SoundReader sound = new SoundReader(soundName, defaultSound); + sound.play(loc, (float) nbt.getDouble("MMOITEMS_SOUND_" + type.name() + "_VOL"), (float) nbt.getDouble("MMOITEMS_SOUND_" + type.name() + "_PIT")); } - - void playDefaultSound(@NotNull Player player) { - player.getWorld().playSound(player.getLocation(), Sound.ENTITY_GENERIC_EAT, 1, 1); - } - */ } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/ComponentType.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/ComponentType.java index 5393909c..e166469e 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/ComponentType.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/ComponentType.java @@ -49,6 +49,8 @@ public abstract class ComponentType, C extends StatComponent> */ private boolean internal; + private boolean flattened; + private boolean inputable; private Function icon; @@ -85,6 +87,10 @@ public abstract class ComponentType, C extends StatComponent> return internal; } + public boolean isFlattened() { + return flattened; + } + /* public void flatten(@NotNull List, StatComponent>> list, @Nullable S statComponent) { Validate.isTrue(terminal, "Basic impl for terminal components"); @@ -198,6 +204,11 @@ public abstract class ComponentType, C extends StatComponent> return this; } + public Builder flattened(boolean flattened) { + ComponentType.this.flattened = flattened; + return this; + } + public Builder inputable(boolean inputable) { ComponentType.this.inputable = inputable; return this; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/MapComponentType.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/MapComponentType.java index 11ba67c7..a512915f 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/MapComponentType.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/MapComponentType.java @@ -14,6 +14,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.function.Predicate; import java.util.function.Supplier; /** @@ -30,6 +31,8 @@ public class MapComponentType extends ComponentType subtype; + private Predicate keyValidator; + private MergeMethod mergeMethod = MergeMethod.MERGE_EACH; @NotNull @@ -53,8 +56,13 @@ public class MapComponentType extends ComponentType model = new MapModel<>(); ConfigurationSection config = (ConfigurationSection) object; - for (String key : config.getKeys(false)) + for (String key : config.getKeys(false)) { + + // Validate key + if (keyValidator != null && !keyValidator.test(key)) continue; + model.getModels().put(key, subtype.fromConfig(config.get(key))); + } return model; } @@ -158,6 +166,11 @@ public class MapComponentType extends ComponentType keyValidator) { + MapComponentType.this.keyValidator = keyValidator; + return this; + } + public Builder implementation(@NotNull Supplier> componentInstanciator) { Validate.notNull(componentInstanciator, "Component instanciator cannot be null"); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/ObjectComponentType.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/ObjectComponentType.java index 9d5ed48a..8d46f74f 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/ObjectComponentType.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/ObjectComponentType.java @@ -2,41 +2,41 @@ package net.Indyuce.mmoitems.stat.component.type.builtin; import io.lumine.mythic.lib.gson.JsonElement; import io.lumine.mythic.lib.gson.JsonObject; +import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility; import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder; import net.Indyuce.mmoitems.stat.component.LoreWrapper; import net.Indyuce.mmoitems.stat.component.builtin.ObjectComponent; import net.Indyuce.mmoitems.stat.component.builtin.ObjectComponentImpl; import net.Indyuce.mmoitems.stat.component.builtin.composite.ColorComponent; +import net.Indyuce.mmoitems.stat.component.model.Model; import net.Indyuce.mmoitems.stat.component.model.builtin.ObjectModel; import net.Indyuce.mmoitems.stat.component.type.ComponentType; -import net.Indyuce.mmoitems.stat.yaml.SyntaxAdapter; import net.Indyuce.mmoitems.util.Pair; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Supplier; public class ObjectComponentType extends ComponentType { private final Map> fields = new LinkedHashMap<>(); + private final Map legacyConfigKeys = new HashMap<>(); @NotNull private Supplier componentInstanciator = ObjectComponentImpl::new; //private Supplier modelInstanciator = ObjectModel::new; private String stringFormatSeparatorPattern; + private boolean strictSeparatedStringFormat; + + @Nullable + private String uniqueSerializable; private MergeMethod mergeMethod = MergeMethod.MERGE_EACH; - /** - * There are some stats - * - * @see SyntaxAdapter - */ - private boolean syntacticShortcut; - /* @Override @SuppressWarnings({"unchecked", "rawtypes"}) @@ -81,7 +81,7 @@ public class ObjectComponentType extends ComponentType ser = new HashMap<>(); @@ -100,16 +100,29 @@ public class ObjectComponentType extends ComponentType submodel = getChildType(uniqueSerializable).fromConfig(object); + model.getModels().put(uniqueSerializable, submodel); + + return model; + } + // Load object from a string, if allowed if (stringFormatSeparatorPattern != null && object instanceof String) { String format = object.toString(); String[] split = format.split(stringFormatSeparatorPattern); - Validate.isTrue(split.length == fields.size(), "Invalid number of parameters"); + if (strictSeparatedStringFormat) + Validate.isTrue(split.length == fields.size(), "Invalid number of parameters"); ObjectModel comp = new ObjectModel(); int counter = 0; for (Map.Entry> entry : fields.entrySet()) { + if (counter >= split.length) break; String sub = split[counter++]; comp.getModels().put(entry.getKey(), entry.getValue().fromConfig(sub)); } @@ -124,12 +137,25 @@ public class ObjectComponentType extends ComponentType> entry : fields.entrySet()) { + + // Flattened sub-components + if (entry.getValue().isFlattened()) { + comp.getModels().put(entry.getKey(), entry.getValue().fromConfig(section)); + continue; + } + // This snake-case-format is experimentally much better (and required) for backwards compatibility String configPath = entry.getKey().replace("_", "-").toLowerCase(); Object sub = section.get(configPath); + String legacyConfigPath; + + // [BACKWARDS COMPATIBILITY] Support older config syntax without the need to use a config adapter. + if (sub == null && (legacyConfigPath = legacyConfigKeys.get(entry.getKey())) != null) + sub = section.get(legacyConfigPath); + + // Null components are well handled in MMOItems if (sub == null) continue; - // TODO object validation comp.getModels().put(entry.getKey(), entry.getValue().fromConfig(sub)); } @@ -222,7 +248,7 @@ public class ObjectComponentType extends ComponentType componentType) { + ObjectComponentType.this.legacyConfigKeys.put(key, legacyConfigKey); + return addField(key, componentType); + } + public Builder addField(String key, ComponentType componentType) { fields.put(key, componentType); return this; } - public Builder stringSeparatedStringFormat(String separatorPattern) { + public Builder stringSeparatedStringFormat(String separatorPattern, boolean strict) { Validate.notNull(separatorPattern, "Separator cannot be null"); + + strictSeparatedStringFormat = strict; stringFormatSeparatorPattern = separatorPattern; return this; } @NotNull public ObjectComponentType build() { - // TODO rules + ObjectComponentType.this.uniqueSerializable = uniqueSerializable(); + return (ObjectComponentType) super.build(); } } + + @Nullable + private String uniqueSerializable() { + String unique = null; + + for (Map.Entry> entry : fields.entrySet()) + // Serializable = non-internal OR flattened + if (!entry.getValue().isInternal() || entry.getValue().isFlattened()) { + if (unique != null) return null; + else unique = entry.getKey(); + } + + return unique; + } + //endregion } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/StringComponentType.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/StringComponentType.java index 4e4e6d74..fc1adca1 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/StringComponentType.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/component/type/builtin/StringComponentType.java @@ -157,7 +157,6 @@ public class StringComponentType extends ComponentType { input = UtilityMethods.enumName(input); valueSupplier.apply(input); // Ignore result, just trigger an error if necessary - Particle.valueOf(input); return input; }).valueIndicator(valuesSupplier); } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/IntegerStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/IntegerStat.java index 069deb77..201df74d 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/IntegerStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/IntegerStat.java @@ -28,8 +28,6 @@ public class IntegerStat extends ItemStat implements Previewab .icon(mat) .trimdesc(lore) .build()); - - setMergeable(true); } @Nullable 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 368cda07..77ccc1f8 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 @@ -49,6 +49,8 @@ public abstract class ItemStat { * However, that does not mean they have no corresponding JSON formatting. * MMOItems still needs to keep the history of these stats. No NBT cache tag * is formed, but stat history still keeps track of it. + *

+ * TODO replace by a StatHistory policy that makes sense. */ private boolean itemMetaSaved = true; @@ -57,8 +59,6 @@ public abstract class ItemStat { */ private boolean templateOption; - private boolean mergeable; - private boolean gemstoneTransferable = true; private boolean removeOnReload; @@ -136,12 +136,12 @@ public abstract class ItemStat { this.displayInLore = displayInLore; } - public boolean isMergeable() { - return mergeable; + public boolean isTemplateOption() { + return templateOption; } - public void setMergeable(boolean mergeable) { - this.mergeable = mergeable; + public void setTemplateOption(boolean templateOption) { + this.templateOption = templateOption; } public boolean isRemovedOnReload() { @@ -182,6 +182,7 @@ public abstract class ItemStat { this.legacyLanguagePath = legacyLanguagePath; } + @NotNull public ComponentType getComponentType() { return componentType; } @@ -213,24 +214,24 @@ public abstract class ItemStat { /** * Directly writes data to a live generated MMOItem. This is used both when - * TODO finish description after understanding when this is even used - *

- * TODO check all implementations and maybe create a function #isEmpty() for components first for readability? * * @param builder Item being built * @param component Component to be applied onto the item */ public abstract void write(ItemStackBuilder builder, @NotNull C component); - // TODO allow to load from a nbttag directly to allow for better complexity when loading an entire item. - /** - * Not used in every stat - * TODO remove it from useless classes - * TODO honestly it's ok + * Used by most primitive type-based stats, including all numerical, + * boolean and string item stats. Composite types like array- or + * object-based types don't use it, but it's so efficient it's okay. */ protected String generalStatFormat; + @NotNull + public String getGeneralStatFormat() { + return generalStatFormat; + } + public void readTranslationFile(@NotNull ConfigurationSection translationFile) { String path = getPath(); Object obj = translationFile.get(path); @@ -238,10 +239,6 @@ public abstract class ItemStat { generalStatFormat = obj == null ? "" : String.valueOf(obj); } - public String getGeneralStatFormat() { - return generalStatFormat; - } - @Nullable public StatCategory getCategory() { return category; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/extra/TemplateOption.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/extra/TemplateOption.java deleted file mode 100644 index 84e72b8e..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/extra/TemplateOption.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.Indyuce.mmoitems.stat.type.extra; - -/** - * Some stats are just options related to the template and not the item - * directly. Such stats are called item options since they do not provide - * anything to the holder, and do not store any data inside the item NBT. - *

- * They can be edited just like a regular stat, but don't need to be loaded - * from the item when checking its NBT. - */ -@Deprecated -public interface TemplateOption { - -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java index 822378e2..27dd8f41 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java @@ -6,7 +6,7 @@ import net.Indyuce.mmoitems.api.event.item.RepairItemEvent; import net.Indyuce.mmoitems.api.interaction.Consumable; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.message.Message; -import net.Indyuce.mmoitems.listener.CustomSoundListener; +import net.Indyuce.mmoitems.stat.SoundStat; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -56,7 +56,7 @@ public class RepairUtils { "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(repairAmount)) .send(player); - CustomSoundListener.playSound(consumable.getItem(), CustomSound.ON_CONSUME, player); + SoundStat.playSound(consumable.getItem(), CustomSound.ON_CONSUME, player); return true; } } diff --git a/MMOItems-Dist/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java b/MMOItems-Dist/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java new file mode 100644 index 00000000..0f3009db --- /dev/null +++ b/MMOItems-Dist/src/main/java/net/Indyuce/mmoitems/listener/CustomSoundListener.java @@ -0,0 +1,77 @@ +package net.Indyuce.mmoitems.listener; + +import net.Indyuce.mmoitems.api.CustomSound; +import net.Indyuce.mmoitems.stat.SoundStat; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.FurnaceSmeltEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemBreakEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; + +public class CustomSoundListener implements Listener { + @EventHandler(priority = EventPriority.HIGH) + public void a(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player) || !(event.getEntity() instanceof LivingEntity)) return; + + Player player = (Player) event.getDamager(); + SoundStat.playSound(player.getInventory().getItemInMainHand(), CustomSound.ON_ATTACK, player); + } + + @EventHandler(priority = EventPriority.HIGH) + public void b(EntityPickupItemEvent event) { + if (event.getEntityType().equals(EntityType.PLAYER)) + SoundStat.playSound(event.getItem().getItemStack(), CustomSound.ON_PICKUP, (Player) event.getEntity()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void c(BlockBreakEvent event) { + SoundStat.playSound(event.getPlayer().getInventory().getItemInMainHand(), CustomSound.ON_BLOCK_BREAK, event.getPlayer()); + } + + @EventHandler + public void d(PlayerInteractEvent event) { + if (event.getAction() == Action.PHYSICAL || !event.hasItem()) return; + + if (event.getAction().name().contains("RIGHT_CLICK")) + SoundStat.playSound(event.getItem(), CustomSound.ON_RIGHT_CLICK, event.getPlayer()); + + if (event.getAction().name().contains("LEFT_CLICK")) + SoundStat.playSound(event.getItem(), CustomSound.ON_LEFT_CLICK, event.getPlayer()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void e(CraftItemEvent event) { + SoundStat.playSound(event.getInventory().getResult(), CustomSound.ON_CRAFT, event.getWhoClicked().getLocation()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void f(FurnaceSmeltEvent event) { + SoundStat.playSound(event.getResult(), CustomSound.ON_CRAFT, event.getBlock().getLocation()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void g(PlayerItemConsumeEvent event) { + SoundStat.playSound(event.getItem(), CustomSound.ON_CONSUME, event.getPlayer()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void h1(PlayerItemBreakEvent event) { + SoundStat.playSound(event.getBrokenItem(), CustomSound.ON_ITEM_BREAK, event.getPlayer()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void i(BlockPlaceEvent event) { + SoundStat.playSound(event.getItemInHand(), CustomSound.ON_PLACED, event.getPlayer()); + } +}