mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2025-02-12 13:01:26 +01:00
More bugfixing
This commit is contained in:
parent
46652835ef
commit
766affefab
@ -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<ArrayComponent<StringComponent>> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> SKILL_DAMAGE = new DoubleStat("SKILL_DAMAGE", Material.BOOK, "Skill Damage", new String[]{"Additional ability damage in %."}).setCategory(StatCategories.DAMAGE_MITIGATION);
|
||||
public static final ItemStat<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<DoubleComponent> 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<BooleanComponent> 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<StringComponent> 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<BooleanComponent> 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<DoubleComponent> 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<BooleanComponent> HIDE_DYE = new HideDye();
|
||||
public static final ItemStat<ObjectComponent> ARMOR_TRIM = new ArmorTrimStat();
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
@ -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<String, Object> 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;
|
||||
}
|
||||
|
||||
|
@ -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<ArrayComponent<AbilityComponent>> {
|
||||
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<ArrayComponent<AbilityComponent>> {
|
||||
|
||||
return lore;
|
||||
})
|
||||
//.setFlattened(true)
|
||||
.build();
|
||||
|
||||
// TODO ui display rules
|
||||
@ -81,8 +85,6 @@ public class Abilities extends ItemStat<ArrayComponent<AbilityComponent>> {
|
||||
.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;
|
||||
|
@ -38,7 +38,7 @@ public class ArrowPotionEffects extends ItemStat<ArrayComponent<ObjectComponent>
|
||||
.addField("duration", NumberComponentType.decimal()
|
||||
.icon(Material.CLOCK)
|
||||
.name("Effect Duration").build())
|
||||
.stringSeparatedStringFormat(" ")
|
||||
.stringSeparatedStringFormat(" ", false)
|
||||
.icon(Material.TIPPED_ARROW)
|
||||
.name("Potion Effect")
|
||||
.build();
|
||||
|
@ -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(); }
|
||||
|
@ -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<VoidComponent> implements TemplateOption {
|
||||
public class Crafting extends ItemStat<VoidComponent> {
|
||||
public Crafting() {
|
||||
super("CRAFTING", null);
|
||||
|
||||
@ -35,6 +34,8 @@ public class Crafting extends ItemStat<VoidComponent> 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<VoidComponent> implements TemplateOption
|
||||
@Nullable
|
||||
@Override
|
||||
public VoidComponent read(ReadMMOItem mmoitem) {
|
||||
throw new RuntimeException("Not supported");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ public class Effects extends ItemStat<ArrayComponent<ObjectComponent>> 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")
|
||||
|
@ -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<String> lore, Optional<RandomElementListData> 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<ElementStatType, String> statFormat = new HashMap<>();
|
||||
|
||||
@Override
|
||||
@BackwardsCompatibility(version = "unspecified")
|
||||
public void readTranslationFile(@NotNull ConfigurationSection translationFile) {
|
||||
String ifError = String.format("<TranslationNotFound:%s_%s>", 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(), "<TranslationNotFound:" + 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(), "<TranslationNotFound:" + statType.name().toLowerCase() + ">"));
|
||||
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<String> lore = new ArrayList<>();
|
||||
|
||||
// Write Lore
|
||||
for (Pair<Element, ElementStatType> 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<ItemTag> getAppliedNBT(@NotNull ElementListData data) {
|
||||
|
||||
// Create Array
|
||||
ArrayList<ItemTag> ret = new ArrayList<>();
|
||||
for (Pair<Element, ElementStatType> 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<ItemTag> 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<ItemTag> 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<String> 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));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -34,10 +34,14 @@ public class GemSockets extends ItemStat<GemstonesComponent> {
|
||||
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<GemstonesComponent> {
|
||||
.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<GemstonesComponent> {
|
||||
// Find upgrade level
|
||||
int itemLevel = builder.getMMOItem().hasUpgradeTemplate() ? builder.getMMOItem().getUpgradeLevel() : 0;
|
||||
|
||||
// Applied gemstones
|
||||
List<String> lore = new ArrayList<>();
|
||||
if (component.getGemstones() != null) for (GemstoneComponent gem : component.getGemstones()) {
|
||||
|
||||
// Applied gemstones
|
||||
for (GemstoneComponent gem : component.getGemstones()) {
|
||||
String gemName = gem.getName();
|
||||
|
||||
// Upgrades?
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ public class ShieldPatternStat extends ItemStat<ShieldStyleComponent> {
|
||||
.icon(Material.SHIELD)
|
||||
.name("Layers")
|
||||
.trimdesc("Edit pattern layers here")
|
||||
.flattened(true)
|
||||
.build())
|
||||
|
||||
.icon(Material.SHIELD)
|
||||
|
@ -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<ObjectComponent> {
|
||||
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<SoundListData, SoundListData> 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<ObjectComponent> soundStat = (ItemStat<ObjectComponent>) 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<String> lore, Optional<SoundListData> 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<ItemTag> getAppliedNBT(@NotNull SoundListData data) {
|
||||
|
||||
// Make Array
|
||||
ArrayList<ItemTag> 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<ItemTag> 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<ItemTag> 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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ public abstract class ComponentType<M extends Model<C>, C extends StatComponent>
|
||||
*/
|
||||
private boolean internal;
|
||||
|
||||
private boolean flattened;
|
||||
|
||||
private boolean inputable;
|
||||
|
||||
private Function<M, ItemStack> icon;
|
||||
@ -85,6 +87,10 @@ public abstract class ComponentType<M extends Model<C>, C extends StatComponent>
|
||||
return internal;
|
||||
}
|
||||
|
||||
public boolean isFlattened() {
|
||||
return flattened;
|
||||
}
|
||||
|
||||
/*
|
||||
public void flatten(@NotNull List<Pair<ComponentType<?>, StatComponent>> list, @Nullable S statComponent) {
|
||||
Validate.isTrue(terminal, "Basic impl for terminal components");
|
||||
@ -198,6 +204,11 @@ public abstract class ComponentType<M extends Model<C>, 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;
|
||||
|
@ -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<C extends StatComponent> extends ComponentType<Map
|
||||
*/
|
||||
private ComponentType<?, C> subtype;
|
||||
|
||||
private Predicate<String> keyValidator;
|
||||
|
||||
private MergeMethod mergeMethod = MergeMethod.MERGE_EACH;
|
||||
|
||||
@NotNull
|
||||
@ -53,8 +56,13 @@ public class MapComponentType<C extends StatComponent> extends ComponentType<Map
|
||||
MapModel<C> 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<C extends StatComponent> extends ComponentType<Map
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder validateKeys(Predicate<String> keyValidator) {
|
||||
MapComponentType.this.keyValidator = keyValidator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder implementation(@NotNull Supplier<? extends MapComponent<C>> componentInstanciator) {
|
||||
Validate.notNull(componentInstanciator, "Component instanciator cannot be null");
|
||||
|
||||
|
@ -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<ObjectModel, ObjectComponent> {
|
||||
private final Map<String, ComponentType<?, ?>> fields = new LinkedHashMap<>();
|
||||
private final Map<String, String> legacyConfigKeys = new HashMap<>();
|
||||
|
||||
@NotNull
|
||||
private Supplier<ObjectComponent> componentInstanciator = ObjectComponentImpl::new;
|
||||
//private Supplier<ObjectModel> 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<ObjectModel, ObjectCompon
|
||||
// Load input from a string, if allowed
|
||||
if (stringFormatSeparatorPattern != null) {
|
||||
String[] split = playerInput.split(stringFormatSeparatorPattern, fields.size());
|
||||
//Validate.isTrue(split.length == fields.size(), "Invalid number of parameters");
|
||||
Validate.isTrue(split.length == fields.size(), "Invalid number of parameters");
|
||||
|
||||
int counter = 0;
|
||||
Map<String, Object> ser = new HashMap<>();
|
||||
@ -100,16 +100,29 @@ public class ObjectComponentType extends ComponentType<ObjectModel, ObjectCompon
|
||||
@Override
|
||||
public ObjectModel fromConfig(@NotNull Object object) {
|
||||
|
||||
// If there's only one subfield that is not internal, should be edited/loaded from config.
|
||||
// Example: gemstones/gemsockets
|
||||
if (uniqueSerializable != null) {
|
||||
ObjectModel model = new ObjectModel();
|
||||
|
||||
Model<?> 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<String, ComponentType<?, ?>> 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<ObjectModel, ObjectCompon
|
||||
ObjectModel comp = new ObjectModel();
|
||||
|
||||
for (Map.Entry<String, 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<ObjectModel, ObjectCompon
|
||||
.addField("Red", NumberComponentType.integer().icon(Material.RED_WOOL).name("Red").build())
|
||||
.addField("Green", NumberComponentType.integer().icon(Material.GREEN_WOOL).name("Green").build())
|
||||
.addField("Blue", NumberComponentType.integer().icon(Material.BLUE_WOOL).name("Blue").build())
|
||||
.stringSeparatedStringFormat(" ");
|
||||
.stringSeparatedStringFormat(" ", true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -263,22 +289,46 @@ public class ObjectComponentType extends ComponentType<ObjectModel, ObjectCompon
|
||||
return this;
|
||||
}
|
||||
|
||||
@BackwardsCompatibility(version = "7.0")
|
||||
public Builder addField(String key, @NotNull String legacyConfigKey, 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<String, ComponentType<?, ?>> 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
|
||||
}
|
||||
|
@ -157,7 +157,6 @@ public class StringComponentType extends ComponentType<StringModel, StringCompon
|
||||
return new StringComponentType().new Builder().adaptor(input -> {
|
||||
input = UtilityMethods.enumName(input);
|
||||
valueSupplier.apply(input); // Ignore result, just trigger an error if necessary
|
||||
Particle.valueOf(input);
|
||||
return input;
|
||||
}).valueIndicator(valuesSupplier);
|
||||
}
|
||||
|
@ -28,8 +28,6 @@ public class IntegerStat extends ItemStat<IntegerComponent> implements Previewab
|
||||
.icon(mat)
|
||||
.trimdesc(lore)
|
||||
.build());
|
||||
|
||||
setMergeable(true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -49,6 +49,8 @@ public abstract class ItemStat<C extends StatComponent> {
|
||||
* 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.
|
||||
* <p>
|
||||
* TODO replace by a StatHistory policy that makes sense.
|
||||
*/
|
||||
private boolean itemMetaSaved = true;
|
||||
|
||||
@ -57,8 +59,6 @@ public abstract class ItemStat<C extends StatComponent> {
|
||||
*/
|
||||
private boolean templateOption;
|
||||
|
||||
private boolean mergeable;
|
||||
|
||||
private boolean gemstoneTransferable = true;
|
||||
|
||||
private boolean removeOnReload;
|
||||
@ -136,12 +136,12 @@ public abstract class ItemStat<C extends StatComponent> {
|
||||
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<C extends StatComponent> {
|
||||
this.legacyLanguagePath = legacyLanguagePath;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ComponentType getComponentType() {
|
||||
return componentType;
|
||||
}
|
||||
@ -213,24 +214,24 @@ public abstract class ItemStat<C extends StatComponent> {
|
||||
|
||||
/**
|
||||
* Directly writes data to a live generated MMOItem. This is used both when
|
||||
* TODO finish description after understanding when this is even used
|
||||
* <p>
|
||||
* 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<C extends StatComponent> {
|
||||
generalStatFormat = obj == null ? "<TranslationNotFound:" + path + ">" : String.valueOf(obj);
|
||||
}
|
||||
|
||||
public String getGeneralStatFormat() {
|
||||
return generalStatFormat;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public StatCategory getCategory() {
|
||||
return category;
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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 {
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user