Solved Launch Players with Item Enchantment

Discussion in 'Spigot Plugin Development' started by Dusk_2_Dawn, Jan 19, 2020.

  1. So I am making a plugin with Custom Enchantments and I have an enchantment which is supposed to have a chance to launch players. The enchantment itself kind of works, except for the fact that it only launches them under specific circumstances. Like it will only launch them if you switch to another slot and switch back and then attack them almost immediately after switching back.

    Here is the code that I am using:

    Code (Java):
        public void onAttack(EntityDamageByEntityEvent e) {
            Entity ent = e.getEntity();
            Entity d = e.getDamager();

            if(!(ent instanceof Player)) return;
            if(!(d instanceof Player)) return;

            Player damaged = (Player) ent;
            Player damager = (Player) d;

            ItemStack item = damager.getItemInHand();
            Material weapon = item.getType();

            if(cem.hasEnchantment(damager.getItemInHand(), "Launch", 1)) {
                if (weapon == Material.WOOD_SWORD) {
                } else if (weapon == Material.STONE_SWORD) {
                } else if (weapon == Material.IRON_SWORD) {
                } else if (weapon == Material.DIAMOND_SWORD) {
                } else {


        public void launchPlayer(Player p) {
            p.setVelocity(new Vector(0, 2, 0));
    If you need the method that I use to check if they have the enchantment:
    Code (Java):
    public boolean hasEnchantment(ItemStack item, String enchantment, Integer level) {
            if(item.hasItemMeta()) {
                if(item.getItemMeta().hasLore()) {
                    for(int i = 0; i < item.getItemMeta().getLore().size(); i++) {
                        String[] lore = ChatColor.stripColor(item.getItemMeta().getLore().get(i)).split(" ");
                        if(lore.length == 2) {
                            String ench = lore[0];
                            String lvl = lore[1];
                            String enchantmentLevel = numberToRoman(level);

                            if (!(enchantment.equalsIgnoreCase(ench))) continue;
                            if (!(enchantmentLevel.equalsIgnoreCase(lvl))) continue;
                            return true;
                    return false;
                } else return false;
            } else return false;
    Any idea why this isn't working?

    EDIT: Also forgot to mention that for some reason whenever the enchantment launches them it doesn't do any damage to them for some reason. If someone could help me with that as well
  2. Uploaded a little clip to demonstrate what's happening
  3. Try adding some debug to see where it is going wrong. IE write in System.out.println(1), 2, 3 in different areas of the code to see where it fails.
    • Agree Agree x 2
  4. Okay, I'll let you know if I find any issues
  5. So I did some debugging and for some reason it is hitting the player twice. Not quite sure why. But from the debugging, I have determined that it detects the attack, it knows that I am hitting a player, it knows I am holding the right weapon, it knows it has the enchant, and it executes the launch method. The problem appears to be with the actual launch thing.

    Code (Java):
        public void launchPlayer(Player p) {
            p.sendMessage("Launching You");
            p.setVelocity(new Vector(0, 2, 0));
    This is what I have for the launch method and it sends the message to the player I am hitting, but it doesn't launch them.
    Here is also an image of the debugging thing and it shows the double hit thing
  6. What if you add ignoreCancelled in the EventHandler annotation
  7. What exactly do you mean by that?

  8. Code (Java):
    @EventHandler(ignoreCancelled = true)
    • Agree Agree x 1
  9. Still didn't do anything
  10. Code (Text):
    public void launch(EntityDamageByEntityEvent e) {
    double launchBoost = 1.2;
    double x = e.getEntity().getVelocity().getX();
    double z = e.getEntity().getVelocity().getZ();
    double y = e.getEntity().getVelocity().getY() + launchBoost;
    Bukkit.getScheduler().runTaskLater(plugin, () -> e.getEntity().setVelocity(new Vector(x,y,z)), 1);
    Try this.
    Change the value of launchBoost to your liking
  11. Thanks! This works! Is it possible to push the player back a little from me whenever I hit them, instead of just launching them straight up. So like maybe back 2 blocks or something away from me
  12. Code (Text):
        public void launch(EntityDamageByEntityEvent e) {
        double velocityBoostX = 1.2;
        double velocityBoostY = 5;
        double velocityBoostZ = 1.2;
        double x = e.getEntity().getVelocity().getX() + velocityBoostX;
        double z = e.getEntity().getVelocity().getZ() + velocityBoostZ;
        double y = e.getEntity().getVelocity().getY() + velocityBoostY;
        Bukkit.getScheduler().runTaskLater(plugin, () -> e.getEntity().setVelocity(new Vector(x,y,z)), 1);
    Realized that multiplying the velocity could cause problems, because it's not accelaration lol. Try this
  13. Doing that only launches them in one particular direction regardless of which way I am facing. Can you use my direction to determine where it will fling them?
  14. Check your direction and do the opposite way should be the easiest way to know which way to fling them
    • Agree Agree x 1
  15. Well that’s because the vector is always adding the value, so it’ll always be a certain direction. If you want to modify the x and z this way, just multiply by a magnitude and remember the value will be a lot higher if a player gets while running away from you. Vectors are just Magnitude and Direction, so you need to modify it correctly.

    Edit: Solodevelopment above me explained a simpler way of doing it.
  16. And how would I do that exactly?
  17. Well you could grab the current direction and make a method to return the new direction on it should be facing (currently not my on my pc to see if there’s a method built into the direction to find the new one)
  18. I can get the direction they are facing easily it just that I can get it to send them in that direction. I would do like p.getEyeLocation().getDirection().getX() + 1.2 but still sends them in 1 direction
  19. All you are modifying is the X... not changing the direction
    • Funny Funny x 1
  20. I was using X as an example. The issue is I don't know how to change the direction