mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-21 04:27:45 +01:00
Custom item types commit 1
This commit is contained in:
parent
5117c77229
commit
bb1eeed501
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>MMOItems</artifactId>
|
||||
<groupId>net.Indyuce</groupId>
|
||||
<version>6.9.5-SNAPSHOT</version>
|
||||
<version>6.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -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"}),
|
||||
|
@ -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 <code>getInventory().register()</code>. 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 <code>getInventory().register()</code>. 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.
|
||||
* <p></p>
|
||||
* Will return <code>null</code> if such MMOItem does not exist.
|
||||
* 0 and the item will have no item tier unless one is specified in
|
||||
* the base item data.
|
||||
* <p></p>
|
||||
* Will return <code>null</code> 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.
|
||||
* <p></p>
|
||||
* Will return <code>null</code> if such MMOItem does not exist.
|
||||
* 0 and the item will have no item tier unless one is specified in
|
||||
* the base item data.
|
||||
* <p></p>
|
||||
* Will return <code>null</code> 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.
|
||||
* <p></p>
|
||||
* Will return <code>null</code> if such MMOItem does not exist.
|
||||
* 0 and the item will have no item tier unless one is specified in
|
||||
* the base item data.
|
||||
* <p></p>
|
||||
* Will return <code>null</code> if such MMOItem does not exist.
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStack getItem(@Nullable Type type, @Nullable String id) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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<String> acceptedTypes = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_TYPES)).getList();
|
||||
final List<String> 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<String> acceptedIDs = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_IDS)).getList();
|
||||
final List<String> 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<String> acceptedMaterials = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_MATERIALS)).getList();
|
||||
List<String> 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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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)
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public class BruteLuteAttack implements LuteAttackHandler {
|
||||
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public class CircularLuteAttack implements LuteAttackHandler {
|
||||
|
||||
@Override
|
||||
|
@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@Deprecated
|
||||
public interface LuteAttackHandler {
|
||||
static final Random RANDOM = new Random();
|
||||
|
||||
|
@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public class SimpleLuteAttack implements LuteAttackHandler {
|
||||
|
||||
@Override
|
||||
|
@ -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
|
||||
|
@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public class WaveLuteAttack implements LuteAttackHandler {
|
||||
|
||||
@Override
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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<Entity> 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);
|
||||
}
|
||||
}
|
@ -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<Entity> 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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();
|
||||
|
@ -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}
|
||||
|
@ -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<String, Type> map = new LinkedHashMap<>();
|
||||
public class TypeManager {
|
||||
private final Map<String, Type> 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<Type> iterator = map.values().iterator(); iterator.hasNext();) {
|
||||
Type type = iterator.next();
|
||||
for (Iterator<Type> 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<Type> getAll() {
|
||||
return map.values();
|
||||
}
|
||||
public boolean has(String id) {
|
||||
return map.containsKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The names of all loaded types.
|
||||
*/
|
||||
public ArrayList<String> getAllTypeNames() {
|
||||
ArrayList<String> ret = new ArrayList<>();
|
||||
for (Type t : getAll()) { ret.add(t.getId()); }
|
||||
return ret;
|
||||
}
|
||||
public Collection<Type> getAll() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The names of all loaded types.
|
||||
*/
|
||||
public ArrayList<String> getAllTypeNames() {
|
||||
ArrayList<String> ret = new ArrayList<>();
|
||||
for (Type t : getAll()) {
|
||||
ret.add(t.getId());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -196,7 +196,7 @@ public abstract class ItemStat<R extends RandomStatData<S>, 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<R extends RandomStatData<S>, 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<R extends RandomStatData<S>, S extends StatData>
|
||||
return lore;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getCompatibleTypes() {
|
||||
return compatibleTypes;
|
||||
}
|
||||
@ -243,10 +244,13 @@ public abstract class ItemStat<R extends RandomStatData<S>, 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) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>MMOItems</artifactId>
|
||||
<groupId>net.Indyuce</groupId>
|
||||
<version>6.9.5-SNAPSHOT</version>
|
||||
<version>6.10-SNAPSHOT</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -28,7 +28,7 @@
|
||||
<dependency>
|
||||
<groupId>net.Indyuce</groupId>
|
||||
<artifactId>MMOItems-API</artifactId>
|
||||
<version>6.9.5-SNAPSHOT</version>
|
||||
<version>6.10-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user