From bb1eeed5019894aab9ae05ae7710b02b90829d49 Mon Sep 17 00:00:00 2001 From: Jules Date: Fri, 26 Jan 2024 12:26:59 +0100 Subject: [PATCH] Custom item types commit 1 --- MMOItems-API/pom.xml | 2 +- .../java/net/Indyuce/mmoitems/ItemStats.java | 2 +- .../java/net/Indyuce/mmoitems/MMOItems.java | 54 ++--- .../java/net/Indyuce/mmoitems/api/Type.java | 125 ++++++++---- .../net/Indyuce/mmoitems/api/TypeSet.java | 33 ++-- .../event/item/UntargetedWeaponUseEvent.java | 8 +- .../mmoitems/api/interaction/Consumable.java | 7 + .../mmoitems/api/interaction/GemStone.java | 9 +- .../mmoitems/api/interaction/ItemSkin.java | 21 +- .../mmoitems/api/interaction/UseItem.java | 47 ++--- .../api/interaction/WeaponAttackResult.java | 35 ++++ .../api/interaction/weapon/Gauntlet.java | 33 ---- .../api/interaction/weapon/Weapon.java | 150 +++++++++++--- .../weapon/untargeted/Crossbow.java | 16 +- .../weapon/untargeted/LegacyWeapon.java | 17 ++ .../interaction/weapon/untargeted/Lute.java | 19 +- .../interaction/weapon/untargeted/Musket.java | 17 +- .../interaction/weapon/untargeted/Staff.java | 72 ------- .../weapon/untargeted/UntargetedWeapon.java | 78 -------- .../untargeted/UntargetedWeaponType.java | 22 --- .../interaction/weapon/untargeted/Whip.java | 38 ---- .../untargeted/lute/BruteLuteAttack.java | 1 + .../untargeted/lute/CircularLuteAttack.java | 1 + .../untargeted/lute/LuteAttackHandler.java | 1 + .../untargeted/lute/SimpleLuteAttack.java | 1 + .../untargeted/lute/SlashLuteAttack.java | 1 + .../untargeted/lute/WaveLuteAttack.java | 1 + .../untargeted/staff/LightningSpirit.java | 25 --- .../weapon/untargeted/staff/ManaSpirit.java | 62 ------ .../weapon/untargeted/staff/NetherSpirit.java | 56 ------ .../untargeted/staff/StaffAttackHandler.java | 23 --- .../untargeted/staff/SunfireSpirit.java | 3 + .../untargeted/staff/ThunderSpirit.java | 3 + .../weapon/untargeted/staff/VoidSpirit.java | 38 ---- .../weapon/untargeted/staff/XRaySpirit.java | 25 --- .../mmoitems/api/player/PlayerData.java | 13 +- .../mmoitems/ReloadCommandTreeNode.java | 2 +- .../mmoitems/list/ListCommandTreeNode.java | 2 - .../list/StaffSpiritCommandTreeNode.java | 24 --- .../mechanics/MMOItemsOnUseAura.java | 6 +- .../Indyuce/mmoitems/listener/ItemUse.java | 186 +++++++----------- .../mmoitems/manager/ConfigManager.java | 10 +- .../Indyuce/mmoitems/manager/TypeManager.java | 183 +++++++++-------- .../mmoitems/stat/StaffSpiritStat.java | 2 + .../Indyuce/mmoitems/stat/type/ItemStat.java | 18 +- MMOItems-Dist/pom.xml | 4 +- pom.xml | 2 +- 47 files changed, 603 insertions(+), 895 deletions(-) create mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/WeaponAttackResult.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Gauntlet.java create mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeapon.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeaponType.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/StaffSpiritCommandTreeNode.java diff --git a/MMOItems-API/pom.xml b/MMOItems-API/pom.xml index fee419a4..778f4010 100644 --- a/MMOItems-API/pom.xml +++ b/MMOItems-API/pom.xml @@ -5,7 +5,7 @@ MMOItems net.Indyuce - 6.9.5-SNAPSHOT + 6.10-SNAPSHOT jar 4.0.0 diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java index ba9537c2..d4768cc2 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java @@ -154,7 +154,7 @@ public class ItemStats { CUSTOM_SOUNDS = new CustomSounds(), ELEMENTS = new Elements(), COMMANDS = new Commands(), - STAFF_SPIRIT = new StaffSpiritStat(), + // STAFF_SPIRIT = new StaffSpiritStat(), LUTE_ATTACK_SOUND = new LuteAttackSoundStat(), LUTE_ATTACK_EFFECT = new LuteAttackEffectStat(), NOTE_WEIGHT = new DoubleStat("NOTE_WEIGHT", VersionMaterial.MUSIC_DISC_MALL.toMaterial(), "Note Weight", new String[]{"Defines how the projectile cast", "by your lute tilts downwards."}, new String[]{"lute"}), diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java index 97d5dfed..c5af0b8a 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java @@ -120,7 +120,7 @@ public class MMOItems extends JavaPlugin { configManager = new ConfigManager(); statManager.load(); - typeManager.reload(); + typeManager.reload(false); templateManager.preloadObjects(); PluginUtils.isDependencyPresent("MMOCore", u -> new MMOCoreMMOLoader()); @@ -141,6 +141,8 @@ public class MMOItems extends JavaPlugin { MMOItemUIFilter.register(); RecipeTypeListGUI.registerNativeRecipes(); + typeManager.postload(); + skillManager.initialize(false); final int configVersion = getConfig().contains("config-version", true) ? getConfig().getInt("config-version") : -1; @@ -410,10 +412,10 @@ public class MMOItems extends JavaPlugin { * * @param value The player inventory subclass * @deprecated Rather than setting this to the only inventory MMOItems will - * search equipment within, you must add your inventory to the - * handler with getInventory().register(). This method - * will clear all other PlayerInventories for now, as to keep - * backwards compatibility. + * search equipment within, you must add your inventory to the + * handler with getInventory().register(). This method + * will clear all other PlayerInventories for now, as to keep + * backwards compatibility. */ @Deprecated public void setPlayerInventory(PlayerInventory value) { @@ -490,7 +492,7 @@ public class MMOItems extends JavaPlugin { return templateManager; } - public LoreFormatManager getLore(){ + public LoreFormatManager getLore() { return loreManager; } @@ -527,9 +529,9 @@ public class MMOItems extends JavaPlugin { /** * @return Generates an item given an item template. The item level will - * scale according to the player RPG level if the template has the - * 'level-item' option. The item will pick a random tier if the - * template has the 'tiered' option + * scale according to the player RPG level if the template has the + * 'level-item' option. The item will pick a random tier if the + * template has the 'tiered' option */ @Nullable public MMOItem getMMOItem(@Nullable Type type, @Nullable String id, @Nullable PlayerData player) { @@ -547,9 +549,9 @@ public class MMOItems extends JavaPlugin { /** * @return Generates an item given an item template. The item level will - * scale according to the player RPG level if the template has the - * 'level-item' option. The item will pick a random tier if the - * template has the 'tiered' option + * scale according to the player RPG level if the template has the + * 'level-item' option. The item will pick a random tier if the + * template has the 'tiered' option */ @Nullable public ItemStack getItem(@Nullable Type type, @Nullable String id, @NotNull PlayerData player) { @@ -566,7 +568,7 @@ public class MMOItems extends JavaPlugin { * @param itemLevel The desired item level * @param itemTier The desired item tier, can be null * @return Generates an item given an item template with a - * specific item level and item tier + * specific item level and item tier */ @Nullable public MMOItem getMMOItem(@Nullable Type type, @Nullable String id, int itemLevel, @Nullable ItemTier itemTier) { @@ -586,7 +588,7 @@ public class MMOItems extends JavaPlugin { * @param itemLevel The desired item level * @param itemTier The desired item tier, can be null * @return Generates an item given an item template with a - * specific item level and item tier + * specific item level and item tier */ @Nullable public ItemStack getItem(@Nullable Type type, @Nullable String id, int itemLevel, @Nullable ItemTier itemTier) { @@ -601,10 +603,10 @@ public class MMOItems extends JavaPlugin { /** * @return Generates an item given an item template. The item level will be - * 0 and the item will have no item tier unless one is specified in - * the base item data. - *

- * Will return null if such MMOItem does not exist. + * 0 and the item will have no item tier unless one is specified in + * the base item data. + *

+ * Will return null if such MMOItem does not exist. */ @Nullable public MMOItem getMMOItem(@Nullable Type type, @Nullable String id) { @@ -613,10 +615,10 @@ public class MMOItems extends JavaPlugin { /** * @return Generates an item given an item template. The item level will be - * 0 and the item will have no item tier unless one is specified in - * the base item data. - *

- * Will return null if such MMOItem does not exist. + * 0 and the item will have no item tier unless one is specified in + * the base item data. + *

+ * Will return null if such MMOItem does not exist. */ @Nullable @@ -629,10 +631,10 @@ public class MMOItems extends JavaPlugin { /** * @return Generates an item given an item template. The item level will be - * 0 and the item will have no item tier unless one is specified in - * the base item data. - *

- * Will return null if such MMOItem does not exist. + * 0 and the item will have no item tier unless one is specified in + * the base item data. + *

+ * Will return null if such MMOItem does not exist. */ @Nullable public ItemStack getItem(@Nullable Type type, @Nullable String id) { diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java index dea5a911..a43fa714 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java @@ -3,12 +3,17 @@ package net.Indyuce.mmoitems.api; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.player.cooldown.CooldownObject; import io.lumine.mythic.lib.player.modifier.ModifierSource; +import io.lumine.mythic.lib.skill.SimpleSkill; +import io.lumine.mythic.lib.skill.Skill; +import io.lumine.mythic.lib.skill.trigger.TriggerType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.item.util.identify.UnidentifiedItem; import net.Indyuce.mmoitems.manager.TypeManager; import net.Indyuce.mmoitems.stat.type.ItemStat; import org.apache.commons.lang.Validate; +import org.apache.maven.model.ConfigurationContainer; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -20,47 +25,46 @@ import java.util.List; import java.util.Objects; @SuppressWarnings("unused") -public class Type { +public class Type implements CooldownObject { // Slashing - public static final Type SWORD = new Type(TypeSet.SLASHING, "SWORD", true, ModifierSource.MELEE_WEAPON); + public static final Type SWORD = new Type("SWORD", true, ModifierSource.MELEE_WEAPON); // Piercing - public static final Type DAGGER = new Type(TypeSet.PIERCING, "DAGGER", true, ModifierSource.MELEE_WEAPON); - public static final Type SPEAR = new Type(TypeSet.PIERCING, "SPEAR", true, ModifierSource.MELEE_WEAPON); + public static final Type DAGGER = new Type("DAGGER", true, ModifierSource.MELEE_WEAPON); + public static final Type SPEAR = new Type("SPEAR", true, ModifierSource.MELEE_WEAPON); // Blunt - public static final Type HAMMER = new Type(TypeSet.BLUNT, "HAMMER", true, ModifierSource.MELEE_WEAPON); - public static final Type GAUNTLET = new Type(TypeSet.BLUNT, "GAUNTLET", true, ModifierSource.MELEE_WEAPON); + public static final Type HAMMER = new Type("HAMMER", true, ModifierSource.MELEE_WEAPON); + public static final Type GAUNTLET = new Type("GAUNTLET", true, ModifierSource.MELEE_WEAPON); // Range - public static final Type WHIP = new Type(TypeSet.RANGE, "WHIP", true, ModifierSource.RANGED_WEAPON); - public static final Type STAFF = new Type(TypeSet.RANGE, "STAFF", true, ModifierSource.RANGED_WEAPON); - public static final Type BOW = new Type(TypeSet.RANGE, "BOW", true, ModifierSource.RANGED_WEAPON); - public static final Type CROSSBOW = new Type(TypeSet.RANGE, "CROSSBOW", false, ModifierSource.RANGED_WEAPON); - public static final Type MUSKET = new Type(TypeSet.RANGE, "MUSKET", true, ModifierSource.RANGED_WEAPON); - public static final Type LUTE = new Type(TypeSet.RANGE, "LUTE", true, ModifierSource.RANGED_WEAPON); + public static final Type WHIP = new Type("WHIP", true, ModifierSource.RANGED_WEAPON); + public static final Type STAFF = new Type("STAFF", true, ModifierSource.RANGED_WEAPON); + public static final Type BOW = new Type("BOW", true, ModifierSource.RANGED_WEAPON); + public static final Type CROSSBOW = new Type("CROSSBOW", false, ModifierSource.RANGED_WEAPON); + public static final Type MUSKET = new Type("MUSKET", true, ModifierSource.RANGED_WEAPON); + public static final Type LUTE = new Type("LUTE", true, ModifierSource.RANGED_WEAPON); // Hand Accessories - public static final Type CATALYST = new Type(TypeSet.CATALYST, "CATALYST", false, ModifierSource.HAND_ITEM); - public static final Type OFF_CATALYST = new Type(TypeSet.CATALYST, "OFF_CATALYST", false, ModifierSource.OFFHAND_ITEM); - public static final Type MAIN_CATALYST = new Type(TypeSet.CATALYST, "MAIN_CATALYST", false, ModifierSource.MAINHAND_ITEM); + public static final Type CATALYST = new Type("CATALYST", false, ModifierSource.HAND_ITEM); + public static final Type OFF_CATALYST = new Type("OFF_CATALYST", false, ModifierSource.OFFHAND_ITEM); + public static final Type MAIN_CATALYST = new Type("MAIN_CATALYST", false, ModifierSource.MAINHAND_ITEM); // Any - public static final Type ORNAMENT = new Type(TypeSet.EXTRA, "ORNAMENT", false, ModifierSource.VOID); + public static final Type ORNAMENT = new Type("ORNAMENT", false, ModifierSource.VOID); // Extra - public static final Type ARMOR = new Type(TypeSet.EXTRA, "ARMOR", false, ModifierSource.ARMOR); - public static final Type TOOL = new Type(TypeSet.EXTRA, "TOOL", false, ModifierSource.MELEE_WEAPON); - public static final Type CONSUMABLE = new Type(TypeSet.EXTRA, "CONSUMABLE", false, ModifierSource.MAINHAND_ITEM); - public static final Type MISCELLANEOUS = new Type(TypeSet.EXTRA, "MISCELLANEOUS", false, ModifierSource.MAINHAND_ITEM); - public static final Type GEM_STONE = new Type(TypeSet.EXTRA, "GEM_STONE", false, ModifierSource.VOID); - public static final Type SKIN = new Type(TypeSet.EXTRA, "SKIN", false, ModifierSource.VOID); - public static final Type ACCESSORY = new Type(TypeSet.EXTRA, "ACCESSORY", false, ModifierSource.ACCESSORY); - public static final Type BLOCK = new Type(TypeSet.EXTRA, "BLOCK", false, ModifierSource.VOID); + public static final Type ARMOR = new Type("ARMOR", false, ModifierSource.ARMOR); + public static final Type TOOL = new Type("TOOL", false, ModifierSource.MELEE_WEAPON); + public static final Type CONSUMABLE = new Type("CONSUMABLE", false, ModifierSource.MAINHAND_ITEM); + public static final Type MISCELLANEOUS = new Type("MISCELLANEOUS", false, ModifierSource.MAINHAND_ITEM); + public static final Type GEM_STONE = new Type("GEM_STONE", false, ModifierSource.VOID); + public static final Type SKIN = new Type("SKIN", false, ModifierSource.VOID); + public static final Type ACCESSORY = new Type("ACCESSORY", false, ModifierSource.ACCESSORY); + public static final Type BLOCK = new Type("BLOCK", false, ModifierSource.VOID); private final String id; - private final TypeSet set; private final ModifierSource modifierSource; private final boolean weapon; @@ -69,6 +73,9 @@ public class Type { @Nullable private String loreFormat; + @NotNull + private String attackCooldownKey; + /** * Used to display the item in the item explorer and in the item recipes * list in the advanced workbench. can also be edited using the config @@ -77,13 +84,19 @@ public class Type { private ItemStack item; /** - * Any type can have a subtype which basically dictates what the item type - * does. + * The parent item type determines: + * - the item options compatible with this new item type + * - if this item type is a weapon or not + * - the lore format */ private Type parent; private UnidentifiedItem unidentifiedTemplate; + private Skill onLeftClick, onRightClick, onAttack, onEntityInteract; + + private boolean meleeAttacks; + /** * List of stats which can be applied onto an item which has this type. This * improves performance when generating an item by a significant amount. @@ -92,11 +105,10 @@ public class Type { @Deprecated public Type(TypeSet set, String id, boolean weapon, ModifierSource modSource, boolean fourGUIMode) { - this(set, id, weapon, modSource); + this(id, weapon, modSource); } - public Type(TypeSet set, String id, boolean weapon, ModifierSource modSource) { - this.set = set; + public Type(String id, boolean weapon, ModifierSource modSource) { this.id = id.toUpperCase().replace("-", "_").replace(" ", "_"); this.modifierSource = modSource; this.weapon = weapon; @@ -108,7 +120,6 @@ public class Type { parent = manager.get(config.getString("parent", "").toUpperCase().replace("-", "_").replace(" ", "_")); - set = (parent != null ? parent.set : TypeSet.EXTRA); weapon = (parent != null && parent.weapon); modifierSource = (parent != null ? parent.modifierSource : ModifierSource.OTHER); this.loreFormat = config.getString("LoreFormat", (parent != null ? parent.loreFormat : null)); @@ -123,7 +134,18 @@ public class Type { (unidentifiedTemplate = new UnidentifiedItem(this)).update(config.getConfigurationSection("unident-item")); // Getting overridden? - loreFormat = config.getString("LoreFormat", (parent != null ? parent.loreFormat : loreFormat)); + loreFormat = config.getString("LoreFormat", parent != null ? parent.loreFormat : null); + + attackCooldownKey = config.getString("attack-cooldown-key", "default"); + + meleeAttacks = !config.getBoolean("cancel-melee-attacks"); + } + + public void postload(ConfigurationSection config) { + onLeftClick = config.contains("on-left-click") ? new SimpleSkill(TriggerType.CAST, MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-left-click"))) : null; + onRightClick = config.contains("on-right-click") ? new SimpleSkill(MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-right-click"))) : null; + onAttack = config.contains("on-attack") ? new SimpleSkill(MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-attack"))) : null; + onEntityInteract = config.contains("on-entity-interact") ? new SimpleSkill(MythicLib.plugin.getSkills().loadSkillHandler(config.get("on-entity-interact"))) : null; } /** @@ -144,18 +166,19 @@ public class Type { return id; } - public TypeSet getItemSet() { - return set; - } - public boolean isWeapon() { return weapon; } + public boolean hasMeleeAttacks() { + return meleeAttacks; + } + public String getName() { return name; } + @NotNull public ModifierSource getModifierSource() { return modifierSource; } @@ -164,6 +187,31 @@ public class Type { return item.clone(); } + @Nullable + public Skill onLeftClick() { + return onLeftClick; + } + + @Override + public String getCooldownPath() { + return "mmoitems_weapons:" + attackCooldownKey; + } + + @Nullable + public Skill onRightClick() { + return onRightClick; + } + + @Nullable + public Skill onAttack() { + return onAttack; + } + + @Nullable + public Skill onEntityInteract() { + return onEntityInteract; + } + /** * @deprecated Use {@link #getSupertype()} */ @@ -213,11 +261,6 @@ public class Type { return getSupertype().equals(type); } - @Deprecated - public boolean corresponds(TypeSet set) { - return getSupertype().getItemSet() == set; - } - /** * @return The collection of all stats which can be applied onto this * specific item type. This list is cached when types are being diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java index 58edaf96..bd91557b 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/TypeSet.java @@ -1,35 +1,23 @@ package net.Indyuce.mmoitems.api; import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.comp.interaction.InteractionType; import io.lumine.mythic.lib.damage.AttackMetadata; -import io.lumine.mythic.lib.damage.DamageType; import io.lumine.mythic.lib.player.PlayerMetadata; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; import net.Indyuce.mmoitems.api.player.PlayerData; -import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.util.MMOUtils; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; -import java.util.Random; - +@Deprecated public enum TypeSet { /** * Slashing weapons deal damage in a cone behind the player's initial * target, which makes it a deadly AoE weapon for warriors */ + @Deprecated SLASHING((attack, attacker, attackerData, target, weapon) -> { - if (!MMOItems.plugin.getConfig().getBoolean("item-ability.slashing.enabled") + /*if (!MMOItems.plugin.getConfig().getBoolean("item-ability.slashing.enabled") || attackerData.isOnCooldown(CooldownType.SET_TYPE_ATTACK)) return; @@ -46,7 +34,7 @@ public enum TypeSet { && attacker.getPlayer().getEyeLocation().getDirection() .angle(entity.getLocation().subtract(attacker.getPlayer().getLocation()).toVector()) < Math.PI / 3 && UtilityMethods.canTarget(attacker.getPlayer(), entity, InteractionType.OFFENSE_ACTION) && !entity.equals(target)) - attacker.attack((LivingEntity) entity, attack.getDamage().getDamage() * .4, DamageType.WEAPON, DamageType.PHYSICAL); + attacker.attack((LivingEntity) entity, attack.getDamage().getDamage() * .4, DamageType.WEAPON, DamageType.PHYSICAL);*/ }), /** @@ -55,8 +43,9 @@ public enum TypeSet { * increased which makes it a perfect 'double or nothing' weapon for * assassins */ + @Deprecated PIERCING((attack, attacker, attackerData, target, weapon) -> { - if (!MMOItems.plugin.getConfig().getBoolean("item-ability.piercing.enabled") + /* if (!MMOItems.plugin.getConfig().getBoolean("item-ability.piercing.enabled") || attackerData.isOnCooldown(CooldownType.SET_TYPE_ATTACK)) return; @@ -73,15 +62,16 @@ public enum TypeSet { && attacker.getPlayer().getEyeLocation().getDirection() .angle(entity.getLocation().toVector().subtract(attacker.getPlayer().getLocation().toVector())) < Math.PI / 12 && UtilityMethods.canTarget(attacker.getPlayer(), entity, InteractionType.OFFENSE_ACTION)) - attacker.attack((LivingEntity) entity, attack.getDamage().getDamage() * .6, DamageType.WEAPON, DamageType.PHYSICAL); + attacker.attack((LivingEntity) entity, attack.getDamage().getDamage() * .6, DamageType.WEAPON, DamageType.PHYSICAL);*/ }), /** * Blunt weapons are like 1.9 sweep attacks. They damage * all enemies nearby and apply a slight knockback */ + @Deprecated BLUNT((attack, attacker, attackerData, target, weapon) -> { - final Random random = new Random(); + /* final Random random = new Random(); float pitchRange = 0.7f + random.nextFloat() * (0.9f - 0.7f); final double bluntPower; @@ -113,7 +103,7 @@ public enum TypeSet { Location loc = target.getLocation(); loc.setYaw((float) (loc.getYaw() + 2 * (random.nextDouble() - .5) * 90)); loc.setPitch((float) (loc.getPitch() + 2 * (random.nextDouble() - .5) * 30)); - } + }*/ }), /** @@ -121,17 +111,20 @@ public enum TypeSet { * the middle of the battle-field, these weapons allow him to take some * distance and still deal some good damage */ + @Deprecated RANGE, /** * Hand/Mainhand/Offhand catalysts */ + @Deprecated CATALYST, /** * Any other item type, like armor, consumables, etc. They all have their * very specific passive depending on their item type */ + @Deprecated EXTRA; private final SetAttackHandler attackHandler; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/UntargetedWeaponUseEvent.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/UntargetedWeaponUseEvent.java index c892a074..26189535 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/UntargetedWeaponUseEvent.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/UntargetedWeaponUseEvent.java @@ -1,14 +1,14 @@ package net.Indyuce.mmoitems.api.event.item; import net.Indyuce.mmoitems.api.event.PlayerDataEvent; -import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.UntargetedWeapon; +import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; import net.Indyuce.mmoitems.api.player.PlayerData; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; public class UntargetedWeaponUseEvent extends PlayerDataEvent implements Cancellable { - private final UntargetedWeapon weapon; + private final Weapon weapon; private boolean cancelled; @@ -20,7 +20,7 @@ public class UntargetedWeaponUseEvent extends PlayerDataEvent implements Cancell * @param who Player attacking * @param weapon Weapon being used */ - public UntargetedWeaponUseEvent(@NotNull PlayerData who, @NotNull UntargetedWeapon weapon) { + public UntargetedWeaponUseEvent(@NotNull PlayerData who, @NotNull Weapon weapon) { super(who); this.weapon = weapon; @@ -30,7 +30,7 @@ public class UntargetedWeaponUseEvent extends PlayerDataEvent implements Cancell * @return The weapon used by the player that fired this event */ @NotNull - public UntargetedWeapon getWeapon() { + public Weapon getWeapon() { return weapon; } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java index d4e0d7ca..7fc3945f 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/Consumable.java @@ -11,6 +11,7 @@ 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.type.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.type.PlayerConsumable; import org.bukkit.Bukkit; @@ -22,10 +23,16 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; public class Consumable extends UseItem { + + @Deprecated public Consumable(Player player, NBTItem item) { super(player, item); } + public Consumable(PlayerData player, NBTItem item) { + super(player, item); + } + @Override public boolean checkItemRequirements() { return MythicLib.plugin.getFlags().isFlagAllowed(player, CustomFlag.MI_CONSUMABLES) && playerData.getRPG().canUse(getNBTItem(), true); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java index e890069c..caead8d0 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java @@ -6,6 +6,7 @@ import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.event.item.ApplyGemStoneEvent; import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem; import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; +import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.stat.Enchants; import net.Indyuce.mmoitems.stat.GemUpgradeScaling; @@ -28,11 +29,15 @@ import org.jetbrains.annotations.Nullable; import java.util.UUID; public class GemStone extends UseItem { - + @Deprecated public GemStone(Player player, NBTItem item) { super(player, item); } + public GemStone(PlayerData player, NBTItem item) { + super(player, item); + } + @NotNull public ApplyResult applyOntoItem(@NotNull NBTItem target, @NotNull Type targetType) { @@ -60,7 +65,7 @@ public class GemStone extends UseItem { // Checks if the gem supports the item type, or the item set, or a weapon String appliableTypes = getNBTItem().getString(ItemStats.ITEM_TYPE_RESTRICTION.getNBTPath()); if (!appliableTypes.equals("") && (!targetType.isWeapon() || !appliableTypes.contains("WEAPON")) - && !appliableTypes.contains(targetType.getItemSet().name()) && !appliableTypes.contains(targetType.getId())) + && !appliableTypes.contains(targetType.getId())) return new ApplyResult(ResultType.NONE); // Check for success rate diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/ItemSkin.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/ItemSkin.java index 41994b0f..4abf9a9f 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/ItemSkin.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/ItemSkin.java @@ -7,6 +7,7 @@ import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; +import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.stat.data.SkullTextureData; import net.Indyuce.mmoitems.stat.data.StringListData; @@ -19,16 +20,20 @@ import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.LeatherArmorMeta; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; import java.util.List; public class ItemSkin extends UseItem { + @Deprecated public ItemSkin(Player player, NBTItem item) { super(player, item); } + public ItemSkin(PlayerData player, NBTItem item) { + super(player, item); + } + public ApplyResult applyOntoItem(NBTItem target, Type targetType) { if (targetType == Type.SKIN) return new ApplyResult(ResultType.NONE); @@ -42,9 +47,9 @@ public class ItemSkin extends UseItem { //SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a77 Applying onto " + MMOUtils.getDisplayName(target.getItem())); // Types compatibility check - if (getMMOItem().hasData(ItemStats.COMPATIBLE_TYPES)) { + if (mmoitem.hasData(ItemStats.COMPATIBLE_TYPES)) { //SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a77 Testing that TYPE is compatible: "); - final List acceptedTypes = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_TYPES)).getList(); + final List acceptedTypes = ((StringListData) mmoitem.getData(ItemStats.COMPATIBLE_TYPES)).getList(); if (acceptedTypes.size() > 0 && acceptedTypes.stream().noneMatch(s -> s.equalsIgnoreCase(targetType.getId()))) { player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); Message.SKIN_INCOMPATIBLE.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem())) @@ -54,9 +59,9 @@ public class ItemSkin extends UseItem { } // IDs compatibility check - if (getMMOItem().hasData(ItemStats.COMPATIBLE_IDS)) { + if (mmoitem.hasData(ItemStats.COMPATIBLE_IDS)) { //SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a77 Testing that ID is compatible: "); - final List acceptedIDs = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_IDS)).getList(); + final List acceptedIDs = ((StringListData) mmoitem.getData(ItemStats.COMPATIBLE_IDS)).getList(); final String targetId = target.getString("MMOITEMS_ITEM_ID"); if (acceptedIDs.size() > 0 && acceptedIDs.stream() @@ -69,9 +74,9 @@ public class ItemSkin extends UseItem { } // Material compatibility check - if (getMMOItem().hasData(ItemStats.COMPATIBLE_MATERIALS)) { + if (mmoitem.hasData(ItemStats.COMPATIBLE_MATERIALS)) { //SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a77 Testing that MATERIAL is compatible: "); - List acceptedMaterials = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_MATERIALS)).getList(); + List acceptedMaterials = ((StringListData) mmoitem.getData(ItemStats.COMPATIBLE_MATERIALS)).getList(); if (acceptedMaterials.size() > 0 && acceptedMaterials.stream() .noneMatch(s -> s.equalsIgnoreCase(target.getItem().getType().name()))) { @@ -93,7 +98,7 @@ public class ItemSkin extends UseItem { } // Apply skin - ItemStack item = applySkin(target, getMMOItem()); + ItemStack item = applySkin(target, mmoitem); player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2); Message.SKIN_APPLIED.format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem())).send(player); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java index b00c0c52..32e42716 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java @@ -6,9 +6,10 @@ import io.lumine.mythic.lib.comp.flags.CustomFlag; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; -import net.Indyuce.mmoitems.api.interaction.weapon.Gauntlet; import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; -import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.*; +import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.Crossbow; +import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.Lute; +import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.Musket; import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.stat.data.CommandData; @@ -27,11 +28,12 @@ public class UseItem { protected static final Random RANDOM = new Random(); - public UseItem(Player player, NBTItem nbtItem) { + @Deprecated + public UseItem(@NotNull Player player, @NotNull NBTItem nbtItem) { this(PlayerData.get(player), nbtItem); } - public UseItem(PlayerData playerData, NBTItem nbtItem) { + public UseItem(@NotNull PlayerData playerData, @NotNull NBTItem nbtItem) { this.player = playerData.getPlayer(); this.playerData = playerData; this.mmoitem = new VolatileMMOItem(nbtItem); @@ -85,11 +87,9 @@ public class UseItem { private void scheduleCommandExecution(CommandData command) { String parsed = MythicLib.plugin.getPlaceholderParser().parse(player, command.getCommand()); - if (!command.hasDelay()) - dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms()); + if (!command.hasDelay()) dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms()); else - Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () -> dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms()), - (long) command.getDelay() * 20); + Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () -> dispatchCommand(parsed, command.isConsoleCommand(), command.hasOpPerms()), (long) command.getDelay() * 20); } /** @@ -116,8 +116,7 @@ public class UseItem { } finally { player.setOp(false); } - } else - Bukkit.dispatchCommand(player, parsed); + } else Bukkit.dispatchCommand(player, parsed); } public static UseItem getItem(Player player, NBTItem item, String type) { @@ -125,24 +124,14 @@ public class UseItem { } public static UseItem getItem(@NotNull Player player, @NotNull NBTItem item, @NotNull Type type) { - if (type.corresponds(Type.CONSUMABLE)) - return new Consumable(player, item); - if (type.corresponds(Type.SKIN)) - return new ItemSkin(player, item); - if (type.corresponds(Type.GEM_STONE)) - return new GemStone(player, item); - if (type.corresponds(Type.MUSKET)) - return new Musket(player, item); - if (type.corresponds(Type.CROSSBOW)) - return new Crossbow(player, item); - if (type.corresponds(Type.GAUNTLET)) - return new Gauntlet(player, item); - if (type.corresponds(Type.WHIP)) - return new Whip(player, item); - if (type.corresponds(Type.LUTE)) - return new Lute(player, item); - if (type.corresponds(Type.STAFF)) - return new Staff(player, item); - return type.isWeapon() ? new Weapon(player, item) : new UseItem(player, item); + final PlayerData playerData = PlayerData.get(player); + if (type.corresponds(Type.CONSUMABLE)) return new Consumable(playerData, item); + if (type.corresponds(Type.SKIN)) return new ItemSkin(playerData, item); + if (type.corresponds(Type.GEM_STONE)) return new GemStone(playerData, item); + if (type.corresponds(Type.MUSKET)) return new Musket(playerData, item); + if (type.corresponds(Type.CROSSBOW)) return new Crossbow(playerData, item); + if (type.corresponds(Type.LUTE)) return new Lute(playerData, item); + + return type.isWeapon() ? new Weapon(playerData, item) : new UseItem(playerData, item); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/WeaponAttackResult.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/WeaponAttackResult.java new file mode 100644 index 00000000..f7c3594b --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/WeaponAttackResult.java @@ -0,0 +1,35 @@ +package net.Indyuce.mmoitems.api.interaction; + +public enum WeaponAttackResult { + + /** + * Attack was performed successfully + */ + SUCCESS, + + /** + * Attakc was not performed due to missing resource (mana or stamina) + * or ongoing cooldown. + */ + WEAPON_COSTS, + + /** + * Attack was canceled because the item is broken + */ + DURABILITY, + + /** + * Attack was canceled due to a precondition of the executed skill + */ + SKILL_SPECIFIC, + + /** + * Attack was canceled due to an event + */ + BUKKIT_EVENT, + + /** + * No attack effect was detected on the item. + */ + NO_ATTACK, +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Gauntlet.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Gauntlet.java deleted file mode 100644 index 21e9f2df..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Gauntlet.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon; - -import io.lumine.mythic.lib.api.item.NBTItem; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -public class Gauntlet extends Weapon { - public Gauntlet(Player player, NBTItem item) { - super(player, item); - } - - public void specialAttack(LivingEntity target) { - if (!MMOItems.plugin.getConfig().getBoolean("item-ability.gauntlet.enabled")) - return; - - if (!checkWeaponCosts(CooldownType.SPECIAL_ATTACK)) - return; - - applyWeaponCosts(MMOItems.plugin.getConfig().getDouble("item-ability.gauntlet.cooldown"), CooldownType.SPECIAL_ATTACK); - target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0); - target.getWorld().playSound(target.getLocation(), Sound.BLOCK_ANVIL_LAND, 1, 0); - target.removePotionEffect(PotionEffectType.BLINDNESS); - target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 40, 1)); - target.setVelocity(getPlayer().getEyeLocation().getDirection().setY(0).normalize().setY(.8)); - target.setVelocity(getPlayer().getEyeLocation().getDirection().setY(0).normalize().multiply(2).setY(.3)); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java index b7505f72..65d04d0f 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/Weapon.java @@ -2,13 +2,26 @@ package net.Indyuce.mmoitems.api.interaction.weapon; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.comp.flags.CustomFlag; import io.lumine.mythic.lib.damage.AttackMetadata; import io.lumine.mythic.lib.player.PlayerMetadata; +import io.lumine.mythic.lib.skill.Skill; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.handler.SkillHandler; +import io.lumine.mythic.lib.skill.result.SkillResult; +import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; +import io.lumine.mythic.lib.skill.trigger.TriggerType; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.Type; +import net.Indyuce.mmoitems.api.event.item.UntargetedWeaponUseEvent; import net.Indyuce.mmoitems.api.interaction.UseItem; +import net.Indyuce.mmoitems.api.interaction.WeaponAttackResult; +import net.Indyuce.mmoitems.api.interaction.util.UntargetedDurabilityItem; +import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.LegacyWeapon; import net.Indyuce.mmoitems.api.player.PlayerData; -import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; import net.Indyuce.mmoitems.api.util.message.Message; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.LivingEntity; @@ -18,6 +31,8 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; public class Weapon extends UseItem { + + @Deprecated public Weapon(Player player, NBTItem item) { this(PlayerData.get(player), item); } @@ -43,18 +58,17 @@ public class Weapon extends UseItem { * @return If the attack was cast successfully */ public boolean checkAndApplyWeaponCosts() { - if (!checkWeaponCosts(null)) return false; - applyWeaponCosts(0, null); + if (!checkWeaponCosts(false)) return false; + applyWeaponCosts(null); return true; } /** - * Checks for cooldown, mana and stamina weapon costs - * - * @return If requirements were met ie the attack can be cast successfully + * @return If instantaneous weapon costs are met. + * @see {@link #applyWeaponCosts(Double)} */ - public boolean checkWeaponCosts(@Nullable CooldownType cooldown) { - if (cooldown != null && getPlayerData().isOnCooldown(cooldown)) + public boolean checkWeaponCosts(boolean cooldowns) { + if (cooldowns && getPlayerData().getMMOPlayerData().getCooldownMap().isOnCooldown(mmoitem.getType())) return false; double manaCost = getNBTItem().getStat("MANA_COST"); @@ -73,22 +87,25 @@ public class Weapon extends UseItem { } /** - * Applies cooldown, mana and stamina weapon costs + * Hard coded instantaneous weapon costs are as follows: + * - mana and stamina (resources) + * - cooldown (given by the item type attack cooldown key) + *

+ * Other weapon costs are inherent to the item type and are + * fully configurable inside of the types config file. * - * @param attackDelay The weapon attack period/delay - * @param cooldown The weapon cooldown type. When set to null, no - * cooldown will be applied. This is made to handle - * custom weapons + * @see {@link #checkWeaponCosts(boolean)} */ - public void applyWeaponCosts(double attackDelay, @Nullable CooldownType cooldown) { + public void applyWeaponCosts(@Nullable Double attackDelay) { - double manaCost = getNBTItem().getStat("MANA_COST"); + final double manaCost = getNBTItem().getStat("MANA_COST"); if (manaCost > 0) playerData.getRPG().giveMana(-manaCost); - double staminaCost = getNBTItem().getStat("STAMINA_COST"); + final double staminaCost = getNBTItem().getStat("STAMINA_COST"); if (staminaCost > 0) playerData.getRPG().giveStamina(-staminaCost); - if (cooldown != null) getPlayerData().applyCooldown(cooldown, attackDelay); + if (attackDelay != null) + getPlayerData().getMMOPlayerData().getCooldownMap().applyCooldown(mmoitem.getType(), attackDelay); } /** @@ -103,20 +120,103 @@ public class Weapon extends UseItem { public boolean handleTargetedAttack(AttackMetadata attackMeta, @NotNull PlayerMetadata attacker, LivingEntity target) { // Handle weapon mana and stamina costs ONLY - if (!checkAndApplyWeaponCosts()) - return false; + if (!checkAndApplyWeaponCosts()) return false; - // Handle item set attack effects - if (getMMOItem().getType().getItemSet().hasAttackEffect() && !getNBTItem().getBoolean("MMOITEMS_DISABLE_ATTACK_PASSIVE")) - getMMOItem().getType().getItemSet().applyAttackEffect(attackMeta, attacker, playerData, target, this); + // Handle on-hit attack effects + final Skill onHitScript = mmoitem.getType().onAttack(); + if (onHitScript != null && !getNBTItem().getBoolean("MMOITEMS_DISABLE_ATTACK_PASSIVE")) + onHitScript.cast(new TriggerMetadata(attacker, TriggerType.API, target, attackMeta)); return true; } + /** + * Called when the player interacts with the item. This method is used to + * apply durability and cast the weapon attack + * + * @param rightClick Is the click a right click? If false, it's a left click. + * @param actionHand Slot being interacted with + * @return Null if there are no attack detected + * @implNote Since MI 6.7.3 this method handles custom durability, cooldown + * checks and player stat snapshots. + */ + @Nullable + public WeaponAttackResult handleUntargetedAttack(boolean rightClick, @NotNull EquipmentSlot actionHand) { + if (this instanceof LegacyWeapon) return legacyHandleUntargetedAttack(rightClick, actionHand); + + // Check for item type attack effect + final Type itemType = mmoitem.getType(); + final Skill attackEffect = rightClick ? itemType.onRightClick() : itemType.onLeftClick(); + if (attackEffect == null) return WeaponAttackResult.NO_ATTACK; + + // Check for attack effect conditions + final SkillHandler handler = attackEffect.getHandler(); + final SkillMetadata meta = new TriggerMetadata(getPlayerData().getMMOPlayerData(), TriggerType.API).toSkillMetadata(attackEffect); + final SkillResult result = handler.getResult(meta); + if (!result.isSuccessful(meta)) return WeaponAttackResult.NO_ATTACK; + + // Check for durability + UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), actionHand); + if (durItem.isBroken()) return WeaponAttackResult.DURABILITY; + + // Apply weapon instantaneous costs + PlayerMetadata stats = getPlayerData().getStats().newTemporary(actionHand); + if (!checkWeaponCosts(true)) return WeaponAttackResult.WEAPON_COSTS; + + // Check for Bukkit event + UntargetedWeaponUseEvent called = new UntargetedWeaponUseEvent(playerData, this); + Bukkit.getPluginManager().callEvent(called); + if (called.isCancelled()) return WeaponAttackResult.BUKKIT_EVENT; + + // Attack is ready to be performed. + // Apply weapon costs + final double attackDelay = 1 / requireNonZero(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")); + applyWeaponCosts(attackDelay); + + // Apply weapon attack effect + handler.whenCast(result, meta); + + // Apply durability loss + if (durItem.isValid()) durItem.decreaseDurability(1).inventoryUpdate(); + return WeaponAttackResult.SUCCESS; + } + + @Deprecated + private WeaponAttackResult legacyHandleUntargetedAttack(boolean rightClick, @NotNull EquipmentSlot actionHand) { + + // Check for attack effect conditions + if (((LegacyWeapon) this).canAttack(rightClick, actionHand)) return WeaponAttackResult.NO_ATTACK; + + // Check for durability + UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), actionHand); + if (durItem.isBroken()) return WeaponAttackResult.DURABILITY; + + // Apply weapon instantaneous costs + PlayerMetadata stats = getPlayerData().getStats().newTemporary(actionHand); + if (!checkWeaponCosts(true)) return WeaponAttackResult.WEAPON_COSTS; + + // Check for Bukkit event + UntargetedWeaponUseEvent called = new UntargetedWeaponUseEvent(playerData, this); + Bukkit.getPluginManager().callEvent(called); + if (called.isCancelled()) return WeaponAttackResult.BUKKIT_EVENT; + + // Attack is ready to be performed. + // Apply weapon costs + final double attackDelay = 1 / requireNonZero(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")); + applyWeaponCosts(attackDelay); + + // Apply weapon attack effect + final PlayerMetadata caster = playerData.getMMOPlayerData().getStatMap().cache(actionHand); + ((LegacyWeapon) this).applyAttackEffect(caster, actionHand); + + // Apply durability loss + if (durItem.isValid()) durItem.decreaseDurability(1).inventoryUpdate(); + return WeaponAttackResult.SUCCESS; + } + protected Location getGround(Location loc) { for (int j = 0; j < 20; j++) { - if (loc.getBlock().getType().isSolid()) - return loc; + if (loc.getBlock().getType().isSolid()) return loc; loc.add(0, -1, 0); } return loc; @@ -125,7 +225,7 @@ public class Weapon extends UseItem { /** * @return First argument, or second if zero or lower */ - public double requireNonZero(double number, double elseNumber) { + protected double requireNonZero(double number, double elseNumber) { return number <= 0 ? elseNumber : number; } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java index 67cd08a2..249fa33a 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java @@ -7,6 +7,8 @@ import io.lumine.mythic.lib.skill.trigger.TriggerType; import io.lumine.mythic.lib.util.CustomProjectile; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.CustomSound; +import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; +import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.listener.CustomSoundListener; import org.bukkit.GameMode; import org.bukkit.Material; @@ -15,15 +17,23 @@ import org.bukkit.entity.Arrow; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class Crossbow extends UntargetedWeapon { +@Deprecated +public class Crossbow extends Weapon implements LegacyWeapon { private boolean consumesArrow; + @Deprecated public Crossbow(Player player, NBTItem item) { - super(player, item, UntargetedWeaponType.RIGHT_CLICK); + super(player, item); + } + + public Crossbow(PlayerData player, NBTItem item) { + super(player, item); } @Override - public boolean canAttack(EquipmentSlot slot) { + public boolean canAttack(boolean rightClick, EquipmentSlot slot) { + if (!rightClick) return false; + consumesArrow = !getNBTItem().getBoolean("MMOITEMS_DISABLE_ARROW_CONSUMPTION"); return player.getGameMode() == GameMode.CREATIVE || !consumesArrow || getPlayer().getInventory().containsAtLeast(new ItemStack(Material.ARROW), 1); } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java new file mode 100644 index 00000000..d541819f --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java @@ -0,0 +1,17 @@ +package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; + +import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.player.PlayerMetadata; + +/** + * These weapon types need to be adapted to + */ +@Deprecated +public interface LegacyWeapon { + + @Deprecated + boolean canAttack(boolean rightClick, EquipmentSlot slot); + + @Deprecated + void applyAttackEffect(PlayerMetadata stats, EquipmentSlot slot); +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java index dccaf816..5d6f756d 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java @@ -8,6 +8,8 @@ import io.lumine.mythic.lib.damage.DamageType; import io.lumine.mythic.lib.player.PlayerMetadata; import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; +import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.SoundReader; import net.Indyuce.mmoitems.stat.LuteAttackEffectStat.LuteAttackEffect; import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData; @@ -23,14 +25,20 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.List; -public class Lute extends UntargetedWeapon { +@Deprecated +public class Lute extends Weapon implements LegacyWeapon { + @Deprecated public Lute(Player player, NBTItem item) { - super(player, item, UntargetedWeaponType.RIGHT_CLICK); + super(player, item); + } + + public Lute(PlayerData player, NBTItem item) { + super(player, item); } @Override - public boolean canAttack(EquipmentSlot slot) { - return true; + public boolean canAttack(boolean rightClick, EquipmentSlot slot) { + return rightClick; } @Override @@ -40,8 +48,7 @@ public class Lute extends UntargetedWeapon { final Vector weight = new Vector(0, -.003 * stats.getStat("NOTE_WEIGHT"), 0); final @Nullable LuteAttackEffect effect = LuteAttackEffect.get(getNBTItem()); - @Deprecated - final SoundReader sound = new SoundReader(getNBTItem().getString("MMOITEMS_LUTE_ATTACK_SOUND"), VersionSound.BLOCK_NOTE_BLOCK_BELL.toSound()); + @Deprecated final SoundReader sound = new SoundReader(getNBTItem().getString("MMOITEMS_LUTE_ATTACK_SOUND"), VersionSound.BLOCK_NOTE_BLOCK_BELL.toSound()); final @NotNull ProjectileParticlesData projParticle = getNBTItem().hasTag("MMOITEMS_PROJECTILE_PARTICLES") ? new ProjectileParticlesData(getNBTItem().getString("MMOITEMS_PROJECTILE_PARTICLES")) : ProjectileParticlesData.DEFAULT; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java index e1eb6a59..3503a757 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java @@ -7,21 +7,28 @@ import io.lumine.mythic.lib.comp.interaction.InteractionType; import io.lumine.mythic.lib.damage.DamageType; import io.lumine.mythic.lib.player.PlayerMetadata; import io.lumine.mythic.lib.util.RayTrace; -import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; +import net.Indyuce.mmoitems.api.player.PlayerData; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; -public class Musket extends UntargetedWeapon { +@Deprecated +public class Musket extends Weapon implements LegacyWeapon { + @Deprecated public Musket(Player player, NBTItem item) { - super(player, item, UntargetedWeaponType.RIGHT_CLICK); + super(player, item); + } + + public Musket(PlayerData player, NBTItem item) { + super(player, item); } @Override - public boolean canAttack(EquipmentSlot slot) { - return true; + public boolean canAttack(boolean rightClick, EquipmentSlot slot) { + return rightClick; } @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java deleted file mode 100644 index 876c4cdf..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; - -import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.comp.interaction.InteractionType; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.player.PlayerMetadata; -import io.lumine.mythic.lib.util.RayTrace; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmoitems.ItemStats; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.player.PlayerData.CooldownType; -import net.Indyuce.mmoitems.stat.StaffSpiritStat.StaffSpirit; -import org.bukkit.EntityEffect; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -public class Staff extends UntargetedWeapon { - public Staff(Player player, NBTItem item) { - super(player, item, UntargetedWeaponType.LEFT_CLICK); - } - - @Override - public boolean canAttack(EquipmentSlot slot) { - return true; - } - - @Override - public void applyAttackEffect(PlayerMetadata stats, EquipmentSlot slot) { - - double attackDamage = requireNonZero(stats.getStat("ATTACK_DAMAGE"), 1); - double range = requireNonZero(stats.getStat("RANGE"), MMOItems.plugin.getConfig().getDouble("default.range")); - - StaffSpirit spirit = StaffSpirit.get(getNBTItem()); - if (spirit != null) { - spirit.getAttack().handle(stats, attackDamage, getNBTItem(), slot, range); - return; - } - - RayTrace trace = new RayTrace(stats.getPlayer(), slot, range, entity -> UtilityMethods.canTarget(stats.getPlayer(), entity, InteractionType.OFFENSE_ACTION)); - if (trace.hasHit()) - stats.attack(trace.getHit(), attackDamage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE); - trace.draw(.5, tick -> tick.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, tick, 0, .1, .1, .1, 0)); - getPlayer().getWorld().playSound(getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 2, 2); - - } - - public void specialAttack(LivingEntity target) { - if (!MMOItems.plugin.getConfig().getBoolean("item-ability.staff.enabled")) - return; - - if (!checkWeaponCosts(CooldownType.SPECIAL_ATTACK)) - return; - - applyWeaponCosts(MMOItems.plugin.getConfig().getDouble("item-ability.staff.cooldown"), CooldownType.SPECIAL_ATTACK); - double power = MMOItems.plugin.getConfig().getDouble("item-ability.staff.power"); - - try { - Vector vec = target.getLocation().toVector().subtract(getPlayer().getLocation().toVector()).setY(0).normalize().multiply(1.75 * power).setY(.65 * power); - target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().add(0, 1, 0), 0); - target.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, target.getLocation().add(0, 1, 0), 16, 0, 0, 0, .1); - target.setVelocity(vec); - target.playEffect(EntityEffect.HURT); - target.getWorld().playSound(target.getLocation(), Sound.BLOCK_ANVIL_LAND, 1, 2); - } catch (IllegalArgumentException ignored) { - } - } -} \ No newline at end of file diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeapon.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeapon.java deleted file mode 100644 index 36bd3ca1..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeapon.java +++ /dev/null @@ -1,78 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; - -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.player.PlayerMetadata; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.api.event.item.UntargetedWeaponUseEvent; -import net.Indyuce.mmoitems.api.interaction.util.UntargetedDurabilityItem; -import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; -import net.Indyuce.mmoitems.api.player.PlayerData; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -public abstract class UntargetedWeapon extends Weapon { - protected final UntargetedWeaponType weaponType; - - public UntargetedWeapon(Player player, NBTItem item, UntargetedWeaponType weaponType) { - super(player, item); - - this.weaponType = weaponType; - } - - /** - * Called when the player interacts with the item. This method is used to - * apply durability and cast the weapon attack - * - * @param slot Slot being interacted with - * @implNote Since MI 6.7.3 this method handles custom durability, cooldown - * checks and player stat snapshots. - */ - public void handleTargetFreeAttack(EquipmentSlot slot) { - if (!canAttack(slot)) - return; - - // Check for durability - UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); - if (durItem.isBroken()) - return; - - // Apply weapon mana/stamina costs and cooldown - PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); - if (!checkWeaponCosts(PlayerData.CooldownType.BASIC_ATTACK)) - return; - - // Check for Bukkit event - UntargetedWeaponUseEvent called = new UntargetedWeaponUseEvent(playerData, this); - Bukkit.getPluginManager().callEvent(called); - if (called.isCancelled()) - return; - - // Apply weapon costs - double attackDelay = 1 / requireNonZero(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")); - applyWeaponCosts(attackDelay, PlayerData.CooldownType.BASIC_ATTACK); - - // Specific weapon attack effect - applyAttackEffect(stats, slot); - - // Apply durability loss - if (durItem.isValid()) - durItem.decreaseDurability(1).inventoryUpdate(); - } - - /** - * Used for instance by the Crossbow item type to apply - * ammo requirements. This is the first ever condition checked - * when trying to perform an untargeted attack - * - * @param slot Slot used to attack - * @return Extra attack condition, specific to the untargeted weapon type - */ - public abstract boolean canAttack(EquipmentSlot slot); - - public abstract void applyAttackEffect(PlayerMetadata stats, EquipmentSlot slot); - - public UntargetedWeaponType getWeaponType() { - return weaponType; - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeaponType.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeaponType.java deleted file mode 100644 index 651d0d37..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/UntargetedWeaponType.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; - -import org.bukkit.event.block.Action; -import org.jetbrains.annotations.NotNull; - -/** - * Used to determine if the item must be left or right clicked in order to - * cast a basic attack. Whips, staffs are left click weapons whereas muskets - * are right click weapons - * - * @author cympe - */ -public enum UntargetedWeaponType { - RIGHT_CLICK, - LEFT_CLICK; - - public boolean corresponds(@NotNull Action action) { - return this == RIGHT_CLICK ? - action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK : - action == Action.LEFT_CLICK_AIR || action == Action.LEFT_CLICK_BLOCK; - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java deleted file mode 100644 index 6badb296..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted; - -import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.comp.interaction.InteractionType; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.player.PlayerMetadata; -import io.lumine.mythic.lib.util.RayTrace; -import io.lumine.mythic.lib.version.VersionSound; -import net.Indyuce.mmoitems.ItemStats; -import net.Indyuce.mmoitems.MMOItems; -import org.bukkit.Particle; -import org.bukkit.entity.Player; - -public class Whip extends UntargetedWeapon { - public Whip(Player player, NBTItem item) { - super(player, item, UntargetedWeaponType.LEFT_CLICK); - } - - @Override - public boolean canAttack(EquipmentSlot slot) { - return true; - } - - @Override - public void applyAttackEffect(PlayerMetadata stats, EquipmentSlot slot) { - - double attackDamage = requireNonZero(stats.getStat("ATTACK_DAMAGE"), 7); - double range = requireNonZero(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); - - RayTrace trace = new RayTrace(getPlayer(), slot, range, entity -> UtilityMethods.canTarget(stats.getPlayer(), entity, InteractionType.OFFENSE_ACTION)); - if (trace.hasHit()) - stats.attack(trace.getHit(), attackDamage, DamageType.WEAPON, DamageType.PROJECTILE, DamageType.PHYSICAL); - trace.draw(.5, tick -> tick.getWorld().spawnParticle(Particle.CRIT, tick, 0, .1, .1, .1, 0)); - getPlayer().getWorld().playSound(getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 2); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java index 2f2e969f..2f957674 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/BruteLuteAttack.java @@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@Deprecated public class BruteLuteAttack implements LuteAttackHandler { @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java index 2a3aa4cd..bab9288a 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/CircularLuteAttack.java @@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@Deprecated public class CircularLuteAttack implements LuteAttackHandler { @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java index 5d84ce00..61fd2dcb 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/LuteAttackHandler.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Random; +@Deprecated public interface LuteAttackHandler { static final Random RANDOM = new Random(); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java index cf4e80f2..33432942 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SimpleLuteAttack.java @@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@Deprecated public class SimpleLuteAttack implements LuteAttackHandler { @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java index 30961ccb..a9cf0441 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/SlashLuteAttack.java @@ -16,6 +16,7 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; +@Deprecated public class SlashLuteAttack implements LuteAttackHandler { @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java index c14862c1..61968a96 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/lute/WaveLuteAttack.java @@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@Deprecated public class WaveLuteAttack implements LuteAttackHandler { @Override diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java deleted file mode 100644 index 3aa546b5..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/LightningSpirit.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; - -import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.comp.interaction.InteractionType; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.player.PlayerMetadata; -import io.lumine.mythic.lib.util.RayTrace; -import io.lumine.mythic.lib.version.VersionSound; -import org.bukkit.Particle; - -public class LightningSpirit implements StaffAttackHandler { - - @Override - public void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range) { - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 2); - - RayTrace trace = new RayTrace(caster.getPlayer(), slot, range, entity -> UtilityMethods.canTarget(caster.getPlayer(), entity, InteractionType.OFFENSE_ACTION)); - - if (trace.hasHit()) - caster.attack(trace.getHit(), damage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE); - trace.draw(.5, loc1 -> loc1.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc1, 0)); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java deleted file mode 100644 index 57873c67..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ManaSpirit.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; - -import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.comp.interaction.InteractionType; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.player.PlayerMetadata; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.util.MMOUtils; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import java.util.List; - -public class ManaSpirit implements StaffAttackHandler { - - @Override - public void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range) { - new BukkitRunnable() { - final Vector vec = caster.getPlayer().getEyeLocation().getDirection().multiply(.4); - final Location loc = caster.getPlayer().getEyeLocation(); - int ti = 0; - final double r = .2; - - public void run() { - if (ti++ > range) - cancel(); - - if (ti % 2 == 0) - loc.getWorld().playSound(loc, Sound.BLOCK_SNOW_BREAK, 2, 2); - List targets = MMOUtils.getNearbyChunkEntities(loc); - for (int j = 0; j < 3; j++) { - loc.add(vec); - if (loc.getBlock().getType().isSolid()) { - cancel(); - break; - } - - for (double item = 0; item < Math.PI * 2; item += Math.PI / 3.5) { - Vector vec = MMOUtils.rotateFunc(new Vector(r * Math.cos(item), r * Math.sin(item), 0), loc); - if (RANDOM.nextDouble() <= .6) - loc.getWorld().spawnParticle(Particle.REDSTONE, loc.clone().add(vec), 1, new Particle.DustOptions(Color.AQUA, 1)); - } - for (Entity target : targets) - if (UtilityMethods.canTarget(caster.getPlayer(), loc, target, InteractionType.OFFENSE_ACTION)) { - caster.attack((LivingEntity) target, damage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE); - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); - cancel(); - return; - } - } - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java deleted file mode 100644 index fd3db017..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/NetherSpirit.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; - -import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.comp.interaction.InteractionType; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.player.PlayerMetadata; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.util.MMOUtils; -import org.bukkit.Location; -import org.bukkit.Particle; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import java.util.List; - -public class NetherSpirit implements StaffAttackHandler { - - @Override - public void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range) { - new BukkitRunnable() { - final Vector vec = caster.getPlayer().getEyeLocation().getDirection().multiply(.3); - final Location loc = caster.getPlayer().getEyeLocation(); - int ti = 0; - - public void run() { - if (ti++ % 2 == 0) - loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 2); - List targets = MMOUtils.getNearbyChunkEntities(loc); - for (int j = 0; j < 3; j++) { - loc.add(vec); - if (loc.getBlock().getType().isSolid()) { - cancel(); - break; - } - - loc.getWorld().spawnParticle(Particle.FLAME, loc, 2, .07, .07, .07, 0); - loc.getWorld().spawnParticle(Particle.SMOKE_NORMAL, loc, 0); - for (Entity target : targets) - if (UtilityMethods.canTarget(caster.getPlayer(), loc, target, InteractionType.OFFENSE_ACTION)) { - caster.attack((LivingEntity) target, damage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE); - loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc, 0); - cancel(); - return; - } - } - if (ti >= range) - cancel(); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java deleted file mode 100644 index 45975bcf..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/StaffAttackHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; - -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.player.PlayerMetadata; -import org.bukkit.Location; - -import java.util.Random; - -public interface StaffAttackHandler { - static final Random RANDOM = new Random(); - - void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range); - - default Location getGround(Location loc) { - for (int j = 0; j < 20; j++) { - if (loc.getBlock().getType().isSolid()) - return loc; - loc.add(0, -1, 0); - } - return loc; - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java index 836d9c2f..25fe2269 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/SunfireSpirit.java @@ -16,7 +16,9 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; +/* +@Deprecated public class SunfireSpirit implements StaffAttackHandler { @Override @@ -57,3 +59,4 @@ public class SunfireSpirit implements StaffAttackHandler { }.runTaskTimer(MMOItems.plugin, 0, 1); } } +*/ diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java index 4d9e7820..f3aec73a 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/ThunderSpirit.java @@ -16,7 +16,9 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; +/* +@Deprecated public class ThunderSpirit implements StaffAttackHandler { @Override @@ -55,3 +57,4 @@ public class ThunderSpirit implements StaffAttackHandler { }.runTaskTimer(MMOItems.plugin, 0, 1); } } +*/ diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java deleted file mode 100644 index b479ce7b..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/VoidSpirit.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; - -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.damage.DamageMetadata; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.player.PlayerMetadata; -import net.Indyuce.mmoitems.MMOItems; -import net.Indyuce.mmoitems.skill.ShulkerMissile; -import org.bukkit.Sound; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.ShulkerBullet; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -public class VoidSpirit implements StaffAttackHandler { - - @Override - public void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range) { - Vector vec = caster.getPlayer().getEyeLocation().getDirection(); - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.ENTITY_WITHER_SHOOT, 2, 2); - ShulkerBullet shulkerBullet = (ShulkerBullet) caster.getPlayer().getWorld().spawnEntity(caster.getPlayer().getLocation().add(0, 1, 0), EntityType.valueOf("SHULKER_BULLET")); - shulkerBullet.setShooter(caster.getPlayer()); - new BukkitRunnable() { - double ti = 0; - - public void run() { - ti += .1; - if (shulkerBullet.isDead() || ti >= range / 4) { - shulkerBullet.remove(); - cancel(); - } - shulkerBullet.setVelocity(vec); - } - }.runTaskTimer(MMOItems.plugin, 0, 1); - MMOItems.plugin.getEntities().registerCustomEntity(shulkerBullet, new ShulkerMissile.ShulkerMissileEntityData(caster, new DamageMetadata(damage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE), 0, nbt)); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java deleted file mode 100644 index 982973d7..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/staff/XRaySpirit.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.weapon.untargeted.staff; - -import io.lumine.mythic.lib.UtilityMethods; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.api.player.EquipmentSlot; -import io.lumine.mythic.lib.comp.interaction.InteractionType; -import io.lumine.mythic.lib.damage.DamageType; -import io.lumine.mythic.lib.player.PlayerMetadata; -import io.lumine.mythic.lib.util.RayTrace; -import org.bukkit.Color; -import org.bukkit.Sound; - -public class XRaySpirit implements StaffAttackHandler { - - @Override - public void handle(PlayerMetadata caster, double damage, NBTItem nbt, EquipmentSlot slot, double range) { - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 2, 2); - - RayTrace trace = new RayTrace(caster.getPlayer(), slot, range, entity -> UtilityMethods.canTarget(caster.getPlayer(), entity, InteractionType.OFFENSE_ACTION)); - if (trace.hasHit()) - caster.attack(trace.getHit(), damage, DamageType.WEAPON, DamageType.MAGIC, DamageType.PROJECTILE); - trace.draw(.5, Color.BLACK); - caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 0.40f, 2); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java index a510caa5..78c20940 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java @@ -408,11 +408,6 @@ public class PlayerData extends SynchronizedDataHolder implements Closeable { public enum CooldownType { - /** - * Basic attack cooldown like staffs and lutes - */ - BASIC_ATTACK, - /** * Elemental attacks cooldown */ @@ -431,12 +426,6 @@ public class PlayerData extends SynchronizedDataHolder implements Closeable { * * @see {@link Tool#miningEffects(Block)} */ - BOUNCING_CRACK, - - /** - * Special item set attack effects including slashing, piercing and - * blunt attack effects - */ - SET_TYPE_ATTACK + BOUNCING_CRACK; } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java index 1912512f..edecf95a 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java @@ -59,7 +59,7 @@ public class ReloadCommandTreeNode extends CommandTreeNode { MMOItems.plugin.getLanguage().reload(); MMOItems.plugin.getDropTables().reload(); - MMOItems.plugin.getTypes().reload(); + MMOItems.plugin.getTypes().reload(true); MMOItems.plugin.getTiers().reload(); MMOItems.plugin.getSets().reload(); MMOItems.plugin.getUpgrades().reload(); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/ListCommandTreeNode.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/ListCommandTreeNode.java index eaac7789..74de7d21 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/ListCommandTreeNode.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/ListCommandTreeNode.java @@ -12,7 +12,6 @@ public class ListCommandTreeNode extends CommandTreeNode { addChild(new AbilityCommandTreeNode(this)); addChild(new LuteAttackCommandTreeNode(this)); - addChild(new StaffSpiritCommandTreeNode(this)); addChild(new TypeCommandTreeNode(this)); } @@ -21,7 +20,6 @@ public class ListCommandTreeNode extends CommandTreeNode { sender.sendMessage(ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "-----------------[" + ChatColor.LIGHT_PURPLE + " MMOItems: lists " + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "]-----------------"); sender.sendMessage(ChatColor.LIGHT_PURPLE + "/mi list type " + ChatColor.WHITE + "shows all item types (sword, axe...)"); - sender.sendMessage(ChatColor.LIGHT_PURPLE + "/mi list spirit " + ChatColor.WHITE + "shows all available staff spirits"); sender.sendMessage(ChatColor.LIGHT_PURPLE + "/mi list lute " + ChatColor.WHITE + "shows all available lute attack effects"); sender.sendMessage(ChatColor.LIGHT_PURPLE + "/mi list ability " + ChatColor.WHITE + "shows all available abilities"); if (sender instanceof Player) { diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/StaffSpiritCommandTreeNode.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/StaffSpiritCommandTreeNode.java deleted file mode 100644 index 35d697a3..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/command/mmoitems/list/StaffSpiritCommandTreeNode.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.Indyuce.mmoitems.command.mmoitems.list; - -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; - -import net.Indyuce.mmoitems.stat.StaffSpiritStat.StaffSpirit; -import io.lumine.mythic.lib.command.api.CommandTreeNode; - -public class StaffSpiritCommandTreeNode extends CommandTreeNode { - public StaffSpiritCommandTreeNode(CommandTreeNode parent) { - super(parent, "spirit"); - } - - @Override - public CommandResult execute(CommandSender sender, String[] args) { - sender.sendMessage(ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "-----------------[" + ChatColor.LIGHT_PURPLE + " Staff Spirits " - + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "]-----------------"); - for (StaffSpirit ss : StaffSpirit.values()) { - String lore = ss.hasLore() ? " " + ChatColor.WHITE + ">> " + ChatColor.GRAY + "" + ChatColor.ITALIC + ss.getDefaultLore() : ""; - sender.sendMessage("* " + ChatColor.LIGHT_PURPLE + ss.name() + lore); - } - return CommandResult.SUCCESS; - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java index 465393e3..ed3d3ef0 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java @@ -12,7 +12,6 @@ import io.lumine.mythic.core.skills.auras.Aura; import io.lumine.mythic.bukkit.utils.Events; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.event.item.SpecialWeaponAttackEvent; -import net.Indyuce.mmoitems.api.interaction.weapon.Gauntlet; import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.*; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; @@ -224,11 +223,12 @@ public class MMOItemsOnUseAura extends Aura implements ITargetedEntitySkill { enum UseItemTypes { CROSSBOW(Crossbow.class), - GAUNTLET(Gauntlet.class), + // GAUNTLET(Gauntlet.class), LUTE(Lute.class), MUSKET(Musket.class), STAFF(Staff.class), - WHIP(Whip.class); + // WHIP(Whip.class); + ; /** * @return Class to use InstanceOf and identify a weapon. diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java index 1c9bd17a..030b1434 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java @@ -7,18 +7,18 @@ import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.comp.interaction.InteractionType; import io.lumine.mythic.lib.damage.MeleeAttackMetadata; +import io.lumine.mythic.lib.skill.Skill; +import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; +import io.lumine.mythic.lib.skill.trigger.TriggerType; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; -import net.Indyuce.mmoitems.api.TypeSet; import net.Indyuce.mmoitems.api.event.item.SpecialWeaponAttackEvent; import net.Indyuce.mmoitems.api.interaction.*; import net.Indyuce.mmoitems.api.interaction.projectile.ProjectileData; -import net.Indyuce.mmoitems.api.interaction.weapon.Gauntlet; import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; -import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.Staff; -import net.Indyuce.mmoitems.api.interaction.weapon.untargeted.UntargetedWeapon; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.util.message.Message; +import net.Indyuce.mmoitems.manager.EntityManager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -31,6 +31,7 @@ import org.bukkit.event.Event; 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.entity.EntityShootBowEvent; import org.bukkit.event.inventory.InventoryAction; @@ -49,8 +50,7 @@ public class ItemUse implements Listener { return; NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getItem()); - if (!item.hasType()) - return; + if (!item.hasType()) return; /* * Some consumables must be fully eaten through the vanilla eating @@ -58,8 +58,7 @@ public class ItemUse implements Listener { */ final Player player = event.getPlayer(); final UseItem useItem = UseItem.getItem(player, item, item.getType()); - if (useItem instanceof Consumable && ((Consumable) useItem).hasVanillaEating()) - return; + if (useItem instanceof Consumable && ((Consumable) useItem).hasVanillaEating()) return; // (BUG FIX) Cancel the event to prevent things like shield blocking if (!useItem.checkItemRequirements()) { @@ -68,12 +67,11 @@ public class ItemUse implements Listener { } // Commands & consummables - if (event.getAction().name().contains("RIGHT_CLICK")) { + final boolean rightClick = event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK; + if (rightClick) { if (useItem.getPlayerData().getMMOPlayerData().getCooldownMap().isOnCooldown(useItem.getMMOItem())) { final double cd = useItem.getPlayerData().getMMOPlayerData().getCooldownMap().getCooldown(useItem.getMMOItem()); - Message.ITEM_ON_COOLDOWN - .format(ChatColor.RED, "#left#", MythicLib.plugin.getMMOConfig().decimal.format(cd), "#s#", cd >= 2 ? "s" : "") - .send(player); + Message.ITEM_ON_COOLDOWN.format(ChatColor.RED, "#left#", MythicLib.plugin.getMMOConfig().decimal.format(cd), "#s#", cd >= 2 ? "s" : "").send(player); event.setUseItemInHand(Event.Result.DENY); return; } @@ -81,8 +79,7 @@ public class ItemUse implements Listener { if (useItem instanceof Consumable) { event.setUseItemInHand(Event.Result.DENY); Consumable.ConsumableConsumeResult result = ((Consumable) useItem).useOnPlayer(event.getHand(), false); - if (result == Consumable.ConsumableConsumeResult.CANCEL) - return; + if (result == Consumable.ConsumableConsumeResult.CANCEL) return; else if (result == Consumable.ConsumableConsumeResult.CONSUME) event.getItem().setAmount(event.getItem().getAmount() - 1); @@ -92,48 +89,42 @@ public class ItemUse implements Listener { useItem.executeCommands(); } - // Target free weapon attack - if (useItem instanceof UntargetedWeapon) { - UntargetedWeapon weapon = (UntargetedWeapon) useItem; - if (weapon.getWeaponType().corresponds(event.getAction())) - weapon.handleTargetFreeAttack(EquipmentSlot.fromBukkit(event.getHand())); - } + // Target-free weapon effects + if (useItem instanceof Weapon) + ((Weapon) useItem).handleUntargetedAttack(rightClick, EquipmentSlot.fromBukkit(event.getHand())); } @EventHandler(ignoreCancelled = true) public void meleeAttacks(PlayerAttackEvent event) { - // Checks if it's a melee attack - if (!(event.getAttack() instanceof MeleeAttackMetadata)) + // Make sure it's a melee attack + if (!(event.getAttack() instanceof MeleeAttackMetadata)) return; + + final Player player = event.getPlayer(); + final PlayerData playerData = PlayerData.get(player); + final ItemStack weaponUsed = player.getInventory().getItem(((MeleeAttackMetadata) event.getAttack()).getHand().toBukkit()); + final NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(weaponUsed); + if (!item.hasType()) return; + + final Type itemType = Type.get(item.getType()); + if (itemType == Type.BLOCK) return; + + // Prevent melee attacks with non-melee weapons + if (!itemType.hasMeleeAttacks()) { + event.setCancelled(true); return; - - /* - * Must apply attack conditions before apply any effects. the event must - * be cancelled before anything is applied - */ - Player player = event.getPlayer(); - PlayerData playerData = PlayerData.get(player); - ItemStack weaponUsed = player.getInventory().getItem(((MeleeAttackMetadata) event.getAttack()).getHand().toBukkit()); - NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(weaponUsed); - - if (item.hasType() && Type.get(item.getType()) != Type.BLOCK) { - Weapon weapon = new Weapon(playerData, item); - - if (weapon.getMMOItem().getType().getItemSet() == TypeSet.RANGE) { - event.setCancelled(true); - return; - } - - if (!weapon.checkItemRequirements()) { - event.setCancelled(true); - return; - } - - if (!weapon.handleTargetedAttack(event.getAttack(), event.getAttacker(), event.getEntity())) { - event.setCancelled(true); - return; - } } + + // Check item requirements + final Weapon weapon = new Weapon(playerData, item); + if (!weapon.checkItemRequirements()) { + event.setCancelled(true); + return; + } + + // Apply melee attack + if (!weapon.handleTargetedAttack(event.getAttack(), event.getAttacker(), event.getEntity())) + event.setCancelled(true); } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @@ -142,12 +133,10 @@ public class ItemUse implements Listener { final Player player = event.getPlayer(); final Block block = event.getBlock(); - if (player.getGameMode() == GameMode.CREATIVE) - return; + if (player.getGameMode() == GameMode.CREATIVE) return; NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(player.getInventory().getItemInMainHand()); - if (!item.hasType()) - return; + if (!item.hasType()) return; Tool tool = new Tool(player, item); if (!tool.checkItemRequirements()) { @@ -155,42 +144,31 @@ public class ItemUse implements Listener { return; } - if (tool.miningEffects(block)) - event.setCancelled(true); + if (tool.miningEffects(block)) event.setCancelled(true); } @EventHandler public void rightClickWeaponInteractions(PlayerInteractEntityEvent event) { Player player = event.getPlayer(); - if (!(event.getRightClicked() instanceof LivingEntity)) - return; + if (!(event.getRightClicked() instanceof LivingEntity)) return; NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(player.getInventory().getItemInMainHand()); - if (!item.hasType()) - return; + if (!item.hasType()) return; LivingEntity target = (LivingEntity) event.getRightClicked(); - if (!UtilityMethods.canTarget(player, target, InteractionType.OFFENSE_ACTION)) - return; + if (!UtilityMethods.canTarget(player, target, InteractionType.OFFENSE_ACTION)) return; - UseItem weapon = UseItem.getItem(player, item, item.getType()); - if (!weapon.checkItemRequirements()) - return; + // Check for usability + final UseItem usableItem = UseItem.getItem(player, item, item.getType()); + if (!usableItem.checkItemRequirements()) return; - // Special staff attack - if (weapon instanceof Staff) { - SpecialWeaponAttackEvent attackEvent = new SpecialWeaponAttackEvent(weapon.getPlayerData(), (Weapon) weapon, target); - Bukkit.getPluginManager().callEvent(attackEvent); - if (!attackEvent.isCancelled()) - ((Staff) weapon).specialAttack(target); - } - - // Special gauntlet attack - if (weapon instanceof Gauntlet) { - SpecialWeaponAttackEvent attackEvent = new SpecialWeaponAttackEvent(weapon.getPlayerData(), (Weapon) weapon, target); - Bukkit.getPluginManager().callEvent(attackEvent); - if (!attackEvent.isCancelled()) - ((Gauntlet) weapon).specialAttack(target); + // Apply type-specific entity interactions + final Skill onEntityInteract = usableItem.getMMOItem().getType().onEntityInteract(); + if (onEntityInteract != null) { + SpecialWeaponAttackEvent called = new SpecialWeaponAttackEvent(usableItem.getPlayerData(), (Weapon) usableItem, target); + Bukkit.getPluginManager().callEvent(called); + if (!called.isCancelled()) + onEntityInteract.cast(new TriggerMetadata(usableItem.getPlayerData().getMMOPlayerData(), TriggerType.API)); } } @@ -198,49 +176,40 @@ public class ItemUse implements Listener { @EventHandler public void gemStonesAndItemStacks(InventoryClickEvent event) { Player player = (Player) event.getWhoClicked(); - if (event.getAction() != InventoryAction.SWAP_WITH_CURSOR) - return; + if (event.getAction() != InventoryAction.SWAP_WITH_CURSOR) return; NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getCursor()); - if (!item.hasType()) - return; + if (!item.hasType()) return; UseItem useItem = UseItem.getItem(player, item, item.getType()); - if (!useItem.checkItemRequirements()) - return; + if (!useItem.checkItemRequirements()) return; if (useItem instanceof ItemSkin) { NBTItem picked = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getCurrentItem()); - if (!picked.hasType()) - return; + if (!picked.hasType()) return; ItemSkin.ApplyResult result = ((ItemSkin) useItem).applyOntoItem(picked, Type.get(picked.getType())); - if (result.getType() == ItemSkin.ResultType.NONE) - return; + if (result.getType() == ItemSkin.ResultType.NONE) return; event.setCancelled(true); item.getItem().setAmount(item.getItem().getAmount() - 1); - if (result.getType() == ItemSkin.ResultType.FAILURE) - return; + if (result.getType() == ItemSkin.ResultType.FAILURE) return; event.setCurrentItem(result.getResult()); } if (useItem instanceof GemStone) { NBTItem picked = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getCurrentItem()); - if (!picked.hasType()) - return; + if (!picked.hasType()) return; GemStone.ApplyResult result = ((GemStone) useItem).applyOntoItem(picked, Type.get(picked.getType())); - if (result.getType() == GemStone.ResultType.NONE) - return; + if (result.getType() == GemStone.ResultType.NONE) return; event.setCancelled(true); item.getItem().setAmount(item.getItem().getAmount() - 1); - if (result.getType() == GemStone.ResultType.FAILURE) - return; + if (result.getType() == GemStone.ResultType.FAILURE) return; event.setCurrentItem(result.getResult()); } @@ -253,17 +222,13 @@ public class ItemUse implements Listener { } /** - * This handler listens to ALL bow shootings, including both - * custom bows from MMOItems AND vanilla bows, since MMOItems needs to - * apply on-hit effects like crits, elemental damage... even if the - * player is using a vanilla bow. - *

- * Fixing commit 4aec1433 + * This handler registers arrows from custom MMOItems bows + * + * @see {@link EntityManager#onHitEffects(PlayerAttackEvent)} */ @EventHandler public void handleCustomBows(EntityShootBowEvent event) { - if (!(event.getProjectile() instanceof AbstractArrow) || !(event.getEntity() instanceof Player)) - return; + if (!(event.getProjectile() instanceof AbstractArrow) || !(event.getEntity() instanceof Player)) return; final NBTItem item = NBTItem.get(event.getBow()); final Type type = Type.get(item.getType()); @@ -284,8 +249,7 @@ public class ItemUse implements Listener { // Apply arrow velocity final double arrowVelocity = projData.getShooter().getStat("ARROW_VELOCITY"); - if (arrowVelocity > 0) - arrow.setVelocity(arrow.getVelocity().multiply(arrowVelocity)); + if (arrowVelocity > 0) arrow.setVelocity(arrow.getVelocity().multiply(arrowVelocity)); } } @@ -296,8 +260,7 @@ public class ItemUse implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void handleVanillaEatenConsumables(PlayerItemConsumeEvent event) { NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getItem()); - if (!item.hasType()) - return; + if (!item.hasType()) return; Player player = event.getPlayer(); UseItem useItem = UseItem.getItem(player, item, item.getType()); @@ -310,9 +273,7 @@ public class ItemUse implements Listener { if (useItem.getPlayerData().getMMOPlayerData().getCooldownMap().isOnCooldown(useItem.getMMOItem())) { final double cd = useItem.getPlayerData().getMMOPlayerData().getCooldownMap().getCooldown(useItem.getMMOItem()); - Message.ITEM_ON_COOLDOWN - .format(ChatColor.RED, "#left#", MythicLib.plugin.getMMOConfig().decimal.format(cd), "#s#", cd >= 2 ? "s" : "") - .send(player); + Message.ITEM_ON_COOLDOWN.format(ChatColor.RED, "#left#", MythicLib.plugin.getMMOConfig().decimal.format(cd), "#s#", cd >= 2 ? "s" : "").send(player); event.setCancelled(true); return; } @@ -326,8 +287,7 @@ public class ItemUse implements Listener { } // Item is not consumed but its effects are applied anyways - if (result == Consumable.ConsumableConsumeResult.NOT_CONSUME) - event.setCancelled(true); + if (result == Consumable.ConsumableConsumeResult.NOT_CONSUME) event.setCancelled(true); useItem.getPlayerData().getMMOPlayerData().getCooldownMap().applyCooldown(useItem.getMMOItem(), useItem.getNBTItem().getStat("ITEM_COOLDOWN")); useItem.executeCommands(); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java index a0c4f872..be614881 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java @@ -11,7 +11,7 @@ import net.Indyuce.mmoitems.api.util.NumericStatFormula; import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.stat.GemUpgradeScaling; import net.Indyuce.mmoitems.stat.LuteAttackEffectStat.LuteAttackEffect; -import net.Indyuce.mmoitems.stat.StaffSpiritStat.StaffSpirit; +//import net.Indyuce.mmoitems.stat.StaffSpiritStat.StaffSpirit; import net.Indyuce.mmoitems.util.LanguageFile; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -138,9 +138,9 @@ public class ConfigManager implements Reloadable { // Staff spirits final LanguageFile attackEffects = new LanguageFile("attack-effects"); - for (StaffSpirit sp : StaffSpirit.values()) + /* for (StaffSpirit sp : StaffSpirit.values()) sp.setName(attackEffects.computeTranslation("staff-spirit." + sp.name().toLowerCase().replace("_", "-"), - () -> UtilityMethods.caseOnWords(sp.name().toLowerCase().replace("_", " ")))); + () -> UtilityMethods.caseOnWords(sp.name().toLowerCase().replace("_", " "))));*/ // Lute attack effects for (LuteAttackEffect eff : LuteAttackEffect.values()) @@ -262,11 +262,11 @@ public class ConfigManager implements Reloadable { public String getLuteAttackEffectName(LuteAttackEffect effect) { return effect.getName(); } - +/* @Deprecated public String getStaffSpiritName(StaffSpirit spirit) { return spirit.getName(); - } + }*/ /** * @deprecated See {@link net.Indyuce.mmoitems.api.item.util.LoreUpdate} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/TypeManager.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/TypeManager.java index b2cbbec6..65610423 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/TypeManager.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/TypeManager.java @@ -5,6 +5,8 @@ import net.Indyuce.mmoitems.api.ConfigFile; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.manager.ConfigManager.DefaultFile; import org.apache.commons.lang.Validate; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,100 +15,117 @@ import java.lang.reflect.Modifier; import java.util.*; import java.util.logging.Level; -public class TypeManager implements Reloadable { - private final Map map = new LinkedHashMap<>(); +public class TypeManager { + private final Map map = new LinkedHashMap<>(); - /** - * Reloads the type manager. It entirely empties the currently registered - * item types, registers default item types again and reads item-types.yml - */ - public void reload() { - map.clear(); + /** + * Reloads the type manager. It entirely empties the currently registered + * item types, registers default item types again and reads item-types.yml + */ + public void reload(boolean clearBefore) { + if (clearBefore) map.clear(); - // Load default types - for (Field field : Type.class.getFields()) - try { - if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && field.get(null) instanceof Type) - register((Type) field.get(null)); - } catch (Exception exception) { - MMOItems.plugin.getLogger().log(Level.WARNING, "Couldn't register type called '" + field.getName() + "': " + exception.getMessage()); - } + // Load default types + for (Field field : Type.class.getFields()) + try { + if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && field.get(null) instanceof Type) + register((Type) field.get(null)); + } catch (Exception exception) { + MMOItems.plugin.getLogger().log(Level.WARNING, "Couldn't register type called '" + field.getName() + "': " + exception.getMessage()); + } - /* - * Register all other types. Important: check if the map already - * contains the id, this way the DEFAULT types are not registered twice, - * and only custom types are registered with a parent. - */ - DefaultFile.ITEM_TYPES.checkFile(); + /* + * Register all other types. Important: check if the map already + * contains the id, this way the DEFAULT types are not registered twice, + * and only custom types are registered with a parent. + */ + DefaultFile.ITEM_TYPES.checkFile(); - ConfigFile config = new ConfigFile("item-types"); - for (String id : config.getConfig().getKeys(false)) - if (!map.containsKey(id)) - try { - register(new Type(this, config.getConfig().getConfigurationSection(id))); - } catch (IllegalArgumentException exception) { - MMOItems.plugin.getLogger().log(Level.WARNING, "Could not register type '" + id + "': " + exception.getMessage()); - } + FileConfiguration config = new ConfigFile("item-types").getConfig(); + for (String id : config.getKeys(false)) + if (!map.containsKey(id)) + try { + register(new Type(this, config.getConfigurationSection(id))); + } catch (IllegalArgumentException exception) { + MMOItems.plugin.getLogger().log(Level.WARNING, "Could not register type '" + id + "': " + exception.getMessage()); + } - for (Iterator iterator = map.values().iterator(); iterator.hasNext();) { - Type type = iterator.next(); + for (Iterator iterator = map.values().iterator(); iterator.hasNext(); ) { + Type type = iterator.next(); - try { - type.load(config.getConfig().getConfigurationSection(type.getId())); - } catch (IllegalArgumentException exception) { - MMOItems.plugin.getLogger().log(Level.WARNING, "Could not register type '" + type.getId() + "': " + exception.getMessage()); - iterator.remove(); - continue; - } + try { + ConfigurationSection section = config.getConfigurationSection(type.getId()); + type.load(section); + if (clearBefore) type.postload(section); + } catch (RuntimeException exception) { + MMOItems.plugin.getLogger().log(Level.WARNING, "Could not register type '" + type.getId() + "': " + exception.getMessage()); + iterator.remove(); + continue; + } - /* - * caches all the stats which the type can have to reduce future - * both item generation (and GUI) calculations. probably the thing - * which takes the most time when loading item types. - */ - type.getAvailableStats().clear(); - MMOItems.plugin.getStats().getAll().stream().filter(stat -> stat.isCompatible(type)).forEach(stat -> type.getAvailableStats().add(stat)); - } - } + /* + * caches all the stats which the type can have to reduce future + * both item generation (and GUI) calculations. probably the thing + * which takes the most time when loading item types. + */ + type.getAvailableStats().clear(); + MMOItems.plugin.getStats().getAll().stream().filter(stat -> stat.isCompatible(type)).forEach(stat -> type.getAvailableStats().add(stat)); + } + } - public void register(Type type) { - map.put(type.getId(), type); - } + public void postload() { + FileConfiguration config = new ConfigFile("item-types").getConfig(); + for (Type type : map.values()) + try { + type.postload(config.getConfigurationSection(type.getId())); + } catch (RuntimeException exception) { + MMOItems.plugin.getLogger().log(Level.WARNING, "An error occured while loading type '" + type.getId() + "': " + exception.getMessage()); + } + } - public void registerAll(Type... types) { - for (Type type : types) - register(type); - } + public void register(Type type) { + map.put(type.getId(), type); + } - /** - * @param id Internal ID of the type - * - * @return The MMOItem Type if it found. - */ - @Nullable public Type get(@Nullable String id) { - if (id == null) { return null; } - return map.get(id); - } + public void registerAll(Type... types) { + for (Type type : types) + register(type); + } - @NotNull public Type getOrThrow(@Nullable String id) { - Validate.isTrue(map.containsKey(id), "Could not find item type with ID '" + id + "'"); - return map.get(id); - } + /** + * @param id Internal ID of the type + * @return The MMOItem Type if it found. + */ + @Nullable + public Type get(@Nullable String id) { + if (id == null) { + return null; + } + return map.get(id); + } - public boolean has(String id) { - return map.containsKey(id); - } + @NotNull + public Type getOrThrow(@Nullable String id) { + Validate.isTrue(map.containsKey(id), "Could not find item type with ID '" + id + "'"); + return map.get(id); + } - public Collection getAll() { - return map.values(); - } + public boolean has(String id) { + return map.containsKey(id); + } - /** - * @return The names of all loaded types. - */ - public ArrayList getAllTypeNames() { - ArrayList ret = new ArrayList<>(); - for (Type t : getAll()) { ret.add(t.getId()); } - return ret; - } + public Collection getAll() { + return map.values(); + } + + /** + * @return The names of all loaded types. + */ + public ArrayList getAllTypeNames() { + ArrayList ret = new ArrayList<>(); + for (Type t : getAll()) { + ret.add(t.getId()); + } + return ret; + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StaffSpiritStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StaffSpiritStat.java index 04d2ffa7..6ebeb404 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StaffSpiritStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/StaffSpiritStat.java @@ -13,6 +13,7 @@ import net.Indyuce.mmoitems.stat.type.StringStat; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/* public class StaffSpiritStat extends StringStat { public StaffSpiritStat() { @@ -92,3 +93,4 @@ public class StaffSpiritStat extends StringStat { } } } +*/ diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java index b8c9bb9c..4b06dfb3 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java @@ -196,7 +196,7 @@ public abstract class ItemStat, S extends StatData> /** * @return The stat ID * @deprecated Use getId() instead. Type is no longer an util since they can - * now be registered from external plugins + * now be registered from external plugins */ @Deprecated @NotNull @@ -214,8 +214,8 @@ public abstract class ItemStat, S extends StatData> /** * @return The NBT path used by the stat to save data in an item's NBTTags. - * The format is 'MMOITEMS_' followed by the stat name in capital - * letters only using _ + * The format is 'MMOITEMS_' followed by the stat name in capital + * letters only using _ */ @NotNull public String getNBTPath() { @@ -234,6 +234,7 @@ public abstract class ItemStat, S extends StatData> return lore; } + @NotNull public List getCompatibleTypes() { return compatibleTypes; } @@ -243,10 +244,13 @@ public abstract class ItemStat, S extends StatData> * @return If a certain item type is compatible with this item stat */ public boolean isCompatible(Type type) { - String lower = type.getId().toLowerCase(); - return type.isSubtype() ? isCompatible(type.getParent()) - : !compatibleTypes.contains("!" + lower) && (compatibleTypes.contains("all") || compatibleTypes.contains(lower) - || compatibleTypes.contains(type.getItemSet().getName().toLowerCase())); + + // Recursive call with root types + if (type.isSubtype()) return isCompatible(type.getParent()); + + // Root item types + final String lower = type.getId().toLowerCase(); + return !compatibleTypes.contains("!" + lower) && (compatibleTypes.contains("all") || compatibleTypes.contains(lower)); } public boolean hasValidMaterial(ItemStack item) { diff --git a/MMOItems-Dist/pom.xml b/MMOItems-Dist/pom.xml index f761d6c1..1b8ac20b 100644 --- a/MMOItems-Dist/pom.xml +++ b/MMOItems-Dist/pom.xml @@ -5,7 +5,7 @@ MMOItems net.Indyuce - 6.9.5-SNAPSHOT + 6.10-SNAPSHOT jar 4.0.0 @@ -28,7 +28,7 @@ net.Indyuce MMOItems-API - 6.9.5-SNAPSHOT + 6.10-SNAPSHOT true diff --git a/pom.xml b/pom.xml index a3bed672..4bc7b097 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ net.Indyuce MMOItems pom - 6.9.5-SNAPSHOT + 6.10-SNAPSHOT MMOItems-API