diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java index c5af0b8a..b04f8ba3 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java @@ -4,8 +4,8 @@ import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackMessage; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider; import io.lumine.mythic.lib.version.SpigotPlugin; -import net.Indyuce.mmoitems.api.ItemTier; import net.Indyuce.mmoitems.api.DeathItemsHandler; +import net.Indyuce.mmoitems.api.ItemTier; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.crafting.MMOItemUIFilter; import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; @@ -68,7 +68,6 @@ public class MMOItems extends JavaPlugin { private final LoreFormatManager loreManager = new LoreFormatManager(); private final TemplateManager templateManager = new TemplateManager(); private final SkillManager skillManager = new SkillManager(); - private final EntityManager entityManager = new EntityManager(); private final RecipeManager recipeManager = new RecipeManager(); private final LayoutManager layoutManager = new LayoutManager(); private final TypeManager typeManager = new TypeManager(); @@ -187,7 +186,6 @@ public class MMOItems extends JavaPlugin { // This ones are not implementing Reloadable MMOItemReforger.reload(); - Bukkit.getPluginManager().registerEvents(entityManager, this); Bukkit.getPluginManager().registerEvents(dropTableManager, this); // Load Dist module @@ -452,10 +450,6 @@ public class MMOItems extends JavaPlugin { return tierManager; } - public EntityManager getEntities() { - return entityManager; - } - public DropTableManager getDropTables() { return dropTableManager; } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java index a43fa714..73f694a6 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/Type.java @@ -42,7 +42,7 @@ public class Type implements CooldownObject { 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 CROSSBOW = new Type("CROSSBOW", true, 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); @@ -142,7 +142,7 @@ public class Type implements CooldownObject { } 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; + onLeftClick = config.contains("on-left-click") ? new SimpleSkill(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; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java index 32e42716..8fcc031f 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/UseItem.java @@ -7,7 +7,6 @@ import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.interaction.weapon.Weapon; -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; @@ -129,7 +128,6 @@ public class UseItem { if (type.corresponds(Type.SKIN)) return new ItemSkin(playerData, item); if (type.corresponds(Type.GEM_STONE)) return new GemStone(playerData, item); if (type.corresponds(Type.MUSKET)) return new Musket(playerData, item); - if (type.corresponds(Type.CROSSBOW)) return new Crossbow(playerData, item); if (type.corresponds(Type.LUTE)) return new Lute(playerData, item); return type.isWeapon() ? new Weapon(playerData, item) : new UseItem(playerData, item); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/projectile/ProjectileData.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/projectile/ProjectileData.java deleted file mode 100644 index 7d90fb76..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/projectile/ProjectileData.java +++ /dev/null @@ -1,81 +0,0 @@ -package net.Indyuce.mmoitems.api.interaction.projectile; - -import io.lumine.mythic.lib.MythicLib; -import io.lumine.mythic.lib.api.item.NBTItem; -import io.lumine.mythic.lib.player.PlayerMetadata; -import net.Indyuce.mmoitems.stat.data.PotionEffectData; -import org.apache.commons.lang.Validate; -import org.bukkit.entity.LivingEntity; -import org.bukkit.potion.PotionEffectType; - -/** - * Since MMOItems 6.7.5 vanilla bows and custom bows are - * not treated the same way: - * - vanilla bows see NO changes in their damage computations - * - custom bows override - */ -public class ProjectileData { - private final NBTItem sourceItem; - private final PlayerMetadata shooter; - private final double damageMultiplier; - - @Deprecated - public ProjectileData(PlayerMetadata shooter, NBTItem sourceItem, boolean customWeapon, double damageMultiplier) { - this(shooter, sourceItem, damageMultiplier); - } - - public ProjectileData(PlayerMetadata shooter, NBTItem sourceItem, double damageMultiplier) { - this.shooter = shooter; - this.sourceItem = sourceItem; - this.damageMultiplier = damageMultiplier; - } - - public NBTItem getSourceItem() { - return sourceItem; - } - - public PlayerMetadata getShooter() { - return shooter; - } - - public double getDamageMultiplier() { - return damageMultiplier; - } - - /** - * Used to check if that projectile data is linked to - * a projectile that want sent using a MMOItems bow. - *
- * If so, it needs to apply on-hit effects like
- * elemental damage or on-hit potion effects
- */
- @Deprecated
- public boolean isCustomWeapon() {
- return true;
- }
-
- /**
- * Will throw an error if it's not a custom bow
- *
- * @return Damage of custom bow
- */
- public double getDamage() {
- Validate.isTrue(isCustomWeapon(), "Not a custom bow");
- return shooter.getStat("ATTACK_DAMAGE") * damageMultiplier;
- }
-
- /**
- * @see {@link #getDamage()}
- */
- @Deprecated
- public void setDamage(double damage) {
- Validate.isTrue(isCustomWeapon(), "Not a custom bow");
- shooter.setStat("ATTACK_DAMAGE", damage);
- }
-
- public void applyPotionEffects(LivingEntity target) {
- if (sourceItem.hasTag("MMOITEMS_ARROW_POTION_EFFECTS"))
- for (ArrowPotionEffectArrayItem entry : MythicLib.plugin.getJson().parse(sourceItem.getString("MMOITEMS_ARROW_POTION_EFFECTS"), ArrowPotionEffectArrayItem[].class))
- target.addPotionEffect(new PotionEffectData(PotionEffectType.getByName(entry.type), entry.duration, entry.level).toEffect());
- }
-}
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java
deleted file mode 100644
index 249fa33a..00000000
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java
+++ /dev/null
@@ -1,62 +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 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;
-import org.bukkit.Sound;
-import org.bukkit.entity.Arrow;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-@Deprecated
-public class Crossbow extends Weapon implements LegacyWeapon {
- private boolean consumesArrow;
-
- @Deprecated
- public Crossbow(Player player, NBTItem item) {
- super(player, item);
- }
-
- public Crossbow(PlayerData player, NBTItem item) {
- super(player, item);
- }
-
- @Override
- 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);
- }
-
- @Override
- public void applyAttackEffect(PlayerMetadata stats, EquipmentSlot slot) {
-
- // Consume arrow
- if (getPlayer().getGameMode() != GameMode.CREATIVE && consumesArrow)
- getPlayer().getInventory().removeItem(new ItemStack(Material.ARROW));
-
- final Arrow arrow = getPlayer().launchProjectile(Arrow.class);
- arrow.setVelocity(getPlayer().getEyeLocation().getDirection().multiply(3 * requireNonZero(stats.getStat("ARROW_VELOCITY"), 1)));
- getPlayer().setVelocity(getPlayer().getVelocity().setX(0).setZ(0));
-
- // Play custom sound
- CustomSoundListener.playSound(getNBTItem().getItem(), CustomSound.ON_CROSSBOW, player, Sound.ENTITY_ARROW_SHOOT);
-
- // Register custom projectile
- MMOItems.plugin.getEntities().registerCustomProjectile(getNBTItem(), stats, arrow, 1);
-
- // Trigger abilities
- stats.getData().triggerSkills(TriggerType.SHOOT_BOW, slot, arrow);
- new CustomProjectile(stats.getData(), CustomProjectile.ProjectileType.ARROW, arrow, slot);
- }
-}
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java
index d541819f..1d95f00b 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/LegacyWeapon.java
@@ -4,7 +4,7 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.player.PlayerMetadata;
/**
- * These weapon types need to be adapted to
+ * These weapon types need to be adapted to raw YAML scripts.
*/
@Deprecated
public interface LegacyWeapon {
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java
index ed3d3ef0..39ebf3ed 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/mechanics/MMOItemsOnUseAura.java
@@ -222,11 +222,11 @@ public class MMOItemsOnUseAura extends Aura implements ITargetedEntitySkill {
}
enum UseItemTypes {
- CROSSBOW(Crossbow.class),
+ // CROSSBOW(Crossbow.class),
// GAUNTLET(Gauntlet.class),
LUTE(Lute.class),
MUSKET(Musket.class),
- STAFF(Staff.class),
+ // STAFF(Staff.class),
// WHIP(Whip.class);
;
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java
index 030b1434..ea0f2b70 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/listener/ItemUse.java
@@ -7,18 +7,18 @@ import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.comp.interaction.InteractionType;
import io.lumine.mythic.lib.damage.MeleeAttackMetadata;
+import io.lumine.mythic.lib.entity.ProjectileMetadata;
+import io.lumine.mythic.lib.entity.ProjectileType;
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.event.item.SpecialWeaponAttackEvent;
import net.Indyuce.mmoitems.api.interaction.*;
-import net.Indyuce.mmoitems.api.interaction.projectile.ProjectileData;
+import net.Indyuce.mmoitems.api.interaction.projectile.ArrowParticles;
import net.Indyuce.mmoitems.api.interaction.weapon.Weapon;
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;
@@ -223,8 +223,6 @@ public class ItemUse implements Listener {
/**
* This handler registers arrows from custom MMOItems bows
- *
- * @see {@link EntityManager#onHitEffects(PlayerAttackEvent)}
*/
@EventHandler
public void handleCustomBows(EntityShootBowEvent event) {
@@ -244,11 +242,16 @@ public class ItemUse implements Listener {
// Have to get hand manually because 1.15 and below does not have event.getHand()
final ItemStack itemInMainHand = playerData.getPlayer().getInventory().getItemInMainHand();
final EquipmentSlot bowSlot = itemInMainHand.isSimilar(event.getBow()) ? EquipmentSlot.MAIN_HAND : EquipmentSlot.OFF_HAND;
- final ProjectileData projData = MMOItems.plugin.getEntities().registerCustomProjectile(item, playerData.getStats().newTemporary(bowSlot), event.getProjectile(), event.getForce());
+ final ProjectileMetadata proj = ProjectileMetadata.create(playerData.getStats().newTemporary(bowSlot), ProjectileType.ARROW, event.getProjectile());
+ proj.setSourceItem(item);
+ proj.setCustomDamage(true);
+ proj.setDamageMultiplier(event.getForce());
+ if (item.hasTag("MMOITEMS_ARROW_PARTICLES"))
+ new ArrowParticles((AbstractArrow) event.getProjectile(), item);
final AbstractArrow arrow = (AbstractArrow) event.getProjectile();
// Apply arrow velocity
- final double arrowVelocity = projData.getShooter().getStat("ARROW_VELOCITY");
+ final double arrowVelocity = proj.getShooter().getStat("ARROW_VELOCITY");
if (arrowVelocity > 0) arrow.setVelocity(arrow.getVelocity().multiply(arrowVelocity));
}
}
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/EntityManager.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/EntityManager.java
deleted file mode 100644
index 02ebd2fc..00000000
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/EntityManager.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package net.Indyuce.mmoitems.manager;
-
-import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
-import io.lumine.mythic.lib.api.item.NBTItem;
-import io.lumine.mythic.lib.damage.ProjectileAttackMetadata;
-import io.lumine.mythic.lib.player.PlayerMetadata;
-import net.Indyuce.mmoitems.MMOItems;
-import net.Indyuce.mmoitems.api.interaction.projectile.ArrowParticles;
-import net.Indyuce.mmoitems.api.interaction.projectile.EntityData;
-import net.Indyuce.mmoitems.api.interaction.projectile.ProjectileData;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.*;
-import org.bukkit.enchantments.Enchantment;
-import org.bukkit.entity.AbstractArrow;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
-import org.bukkit.event.Listener;
-import org.bukkit.event.entity.EntityDamageByEntityEvent;
-import org.bukkit.event.entity.EntityDeathEvent;
-import org.bukkit.event.entity.ProjectileHitEvent;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.WeakHashMap;
-
-public class EntityManager implements Listener {
-
- /**
- * Entity data used by abilities or staff attacks that utilize entities like
- * evoker fangs or shulker missiles. It can correspond to the damage the
- * entity is supposed to deal, etc
- */
- private final Map
- * Event order: ProjectileHit -> EntityDamage / EntityDeathEvent
- */
- @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
- public void customProjectileDamage(EntityDamageByEntityEvent event) {
- if (!(event.getDamager() instanceof Projectile) || !(event.getEntity() instanceof LivingEntity) || event.getEntity().hasMetadata("NPC"))
- return;
-
- final Projectile projectile = (Projectile) event.getDamager();
- final ProjectileData data = projectiles.get(projectile.getEntityId());
- if (data == null)
- return;
-
- // Calculate custom base damage
- double baseDamage = data.getDamage();
-
- // Apply power vanilla enchant
- if (projectile instanceof AbstractArrow && data.getSourceItem().getItem().hasItemMeta()
- && data.getSourceItem().getItem().getItemMeta().getEnchants().containsKey(Enchantment.ARROW_DAMAGE))
- baseDamage *= 1.25 + (.25 * data.getSourceItem().getItem().getItemMeta().getEnchantLevel(Enchantment.ARROW_DAMAGE));
-
- event.setDamage(baseDamage);
- }
-
- @EventHandler(ignoreCancelled = true)
- public void onHitEffects(PlayerAttackEvent event) {
- if (!(event.getAttack() instanceof ProjectileAttackMetadata))
- return;
-
- final ProjectileAttackMetadata projAttack = (ProjectileAttackMetadata) event.getAttack();
- final @Nullable ProjectileData data = projectiles.get(projAttack.getProjectile().getEntityId());
- if (data == null)
- return;
-
- // Apply MMOItems specific modifications
- data.applyPotionEffects(event.getEntity());
- }
-
- @EventHandler(priority = EventPriority.MONITOR)
- public void unregisterProjectileData(ProjectileHitEvent event) {
- Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, () -> unregisterCustomProjectile(event.getEntity()));
- }
-
- @EventHandler(priority = EventPriority.MONITOR)
- public void unregisterEntityData(EntityDeathEvent event) {
- Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, () -> unregisterCustomEntity(event.getEntity()));
- }
-}
\ No newline at end of file
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java
index 259bc83c..789166fe 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java
@@ -6,7 +6,6 @@ import io.lumine.mythic.lib.skill.handler.SkillHandler;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.skill.RegisteredSkill;
-import net.Indyuce.mmoitems.skill.ShulkerMissile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -81,8 +80,6 @@ public class SkillManager {
if (clearBefore)
skills.clear();
- MythicLib.plugin.getSkills().registerSkillHandler(new ShulkerMissile());
-
File skillFolder = new File(MMOItems.plugin.getDataFolder() + "/skill");
if (!skillFolder.exists()) {
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/skill/ShulkerMissile.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/skill/ShulkerMissile.java
deleted file mode 100644
index a46ae90e..00000000
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/skill/ShulkerMissile.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package net.Indyuce.mmoitems.skill;
-
-import io.lumine.mythic.lib.UtilityMethods;
-import io.lumine.mythic.lib.api.item.NBTItem;
-import io.lumine.mythic.lib.comp.interaction.InteractionType;
-import io.lumine.mythic.lib.damage.DamageMetadata;
-import io.lumine.mythic.lib.damage.DamageType;
-import io.lumine.mythic.lib.player.PlayerMetadata;
-import io.lumine.mythic.lib.skill.SkillMetadata;
-import io.lumine.mythic.lib.skill.handler.SkillHandler;
-import io.lumine.mythic.lib.skill.result.def.VectorSkillResult;
-import net.Indyuce.mmoitems.MMOItems;
-import net.Indyuce.mmoitems.api.interaction.projectile.EntityData;
-import org.bukkit.Color;
-import org.bukkit.Location;
-import org.bukkit.Particle;
-import org.bukkit.Sound;
-import org.bukkit.entity.EntityType;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
-import org.bukkit.entity.ShulkerBullet;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.entity.EntityDamageByEntityEvent;
-import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
-import org.bukkit.scheduler.BukkitRunnable;
-import org.bukkit.util.Vector;
-import org.jetbrains.annotations.NotNull;
-
-import javax.annotation.Nullable;
-
-public class ShulkerMissile extends SkillHandler