issue with ".isOnGround()"

Discussion in 'Plugin Development' started by u_mad_bros, Nov 17, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    u_mad_bros

    Hello! I can't seem to resolve this issue. I was able to do this with a while loop, but that obviously crashed my sever. I want an explosion to happen when the arrow hits the ground. With this code, it should do it whenever the arrow is on the ground, but that doesn't happen. (I will tweak it once I can figure out how to tell if the arrow has hit the ground).
    Any help is appreciated! Also, please don't interpret this as another randy trying to get someone to spoon feed me code.. I see that on here every so often, and I wouldn't like to be deemed that lol
    Code:
    
        @EventHandler(priority = EventPriority.HIGH)
        public void ShootBow(EntityShootBowEvent e) {
            if(e.getEntity() instanceof Player) {
            Player p = (Player) e.getEntity();
            Entity arrow = (Entity) e.getEntity();
           
            if(arrow.isOnGround() == true){
            arrow.getWorld().createExplosion(arrow.getLocation(), 3);
            } else {
                return;
            }
    
     
  2. Offline

    oceantheskatr

    It's one thing for a person to ask for the code, it's another for them to first try it themselves and then ask for assistance :)

    You should try something like this:

    Bukkit.scheduler({
    if (arrow.isOnGround) {
    create explosion;
    }
    },1L);

    Hopefully that sorta explains it. Remove the == true, as isOnGround will already return a boolean.

    What I'm suggesting is put the if statement in a scheduler that files every tick. Optionally, you could change it from 1 to 3 ticks or something if 1 is too intensive on the server. If I need to elaborate let me know, good luck!

    EDIT: Btw, your if statement can be simplified like this:

    Code:
    if(arrow.isOnGround())
        arrow.getWorld().createExplosion(arrow.getLocation(), 3);
    Also, I could be wrong, but if you're able to it'd be better to change it from arrow.getWorld to getServer.getWorld.
     
  3. Offline

    jlin13

    Have you looked into ProjectileHitEvent? I'm pretty sure that gets called when an arrow hits the ground too
     
    oceantheskatr likes this.
  4. Offline

    oceantheskatr

    @jlin13

    public class ProjectileHitEvent
    extends EntityEvent
    Called when a projectile hits an object

    I don't think the ground counts as an object but I don't know for sure. It seems unlikely though.

    @u_mad_bros You could test this quickly by making an event that simply sends a string to you onProjectileHit, and shoot an arrow at the ground. If it sends the string, then it works, else try my suggestion.
     
  5. Offline

    u_mad_bros

    @jlin13 I saw that, but I wanted to also add velocity to the player who shot the arrow, so I figured eh, let's put it all in one event lol

    @oceantheskatr I haven't ever used Bukkit Schedulers, actually.. This is something quite new.. Can't find a thorough explanation on the matter anywhere, care to give a simple one for my scenario? I tried to do it myself, and this is where I got (lmao it's probably completely wrong)
    Code:
    public class PlayerListener implements Listener {
        @EventHandler(priority = EventPriority.HIGH)
        public void ShootBow(EntityShootBowEvent e) {
            if(e.getEntity() instanceof Player) {
            Player p = (Player) e.getEntity();
            Entity arrow = (Entity) e.getEntity();
            Bukkit.getScheduler().scheduleSyncRepeatingTask((Plugin) this, new Runnable() {
                public void run(){
            if(arrow.isOnGround()){
            arrow.getWorld().createExplosion(arrow.getLocation(), 3);
            return;
            } else {
                return;
            }
                }
            }, 60, 60);
            }
        }
    }
    
    
     
  6. Offline

    jlin13

    Add velocity to the shot with EntityShootBowEvent - store a reference to the UUID of the arrow in an ArrayList, then on ProjectileHitEvent check if the projectile hit a player or mob, if not explode at the arrow's location if the arrow's UUID is in the ArrayList.
     
  7. Offline

    u_mad_bros

    @jlin13 Will try this, and will update if solved or not. Thanks for the help! :)
    @jlin13
    Alright, I am completely stumped. I thought that I could do this no problem, but I messed up somewhere and just not noticing. I took a long break from coding in general, so I am very rusty. I wanted to get into the swing of things by coding a simple "Blast" enchantment plugin, so right now I am just doing the basics. I dunno what's wrong with this code, but the explosion is not happening. (Velocity is though).
    Code:
    package com.umadbros.test;
    
    import java.util.ArrayList;
    import java.util.UUID;
    
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.EventPriority;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityShootBowEvent;
    import org.bukkit.event.entity.ProjectileHitEvent;
    import org.bukkit.util.Vector;
    
    public class PlayerListener implements Listener {
        ArrayList<UUID> arrowlist = new ArrayList<UUID>();
       
        @EventHandler(priority = EventPriority.HIGH)
        public void ShootBow(EntityShootBowEvent e) {
            if(e.getEntity() instanceof Player) {
            Player p = (Player) e.getEntity();
            Entity arrow = (Entity) e.getEntity();
            arrowlist.add(arrow.getUniqueId());
            double pitch = ((90 - p.getLocation().getPitch()) * Math.PI) / 180;
            double yaw  = ((p.getLocation().getYaw() + 90 + 180) * Math.PI) / 180;
            double x = Math.sin(pitch) * Math.cos(yaw);
            double y = Math.sin(pitch) * Math.sin(yaw);
            double z = Math.cos(pitch);
            Vector vector = new Vector(x, z, y);
            p.setVelocity(vector);
    }
        }
        @EventHandler
        public void arrowExplode(ProjectileHitEvent e) {
            Entity arrow = (Entity) e.getEntity();
            if(!(arrowlist.contains(arrow.getUniqueId()))) {
                return;
            }
            if (arrowlist.contains(arrow.getUniqueId())) {
                arrow.getWorld().createExplosion(arrow.getLocation(), 3);
                arrowlist.remove(arrow.getUniqueId());
            }
        }
    }
    
    
    
     
    Last edited: Nov 17, 2016
  8. Offline

    jlin13

    @u_mad_bros
    Your problem is you are initializing Entity arrow as (Entity) e.getEntity(). This will get the UUID of the player, I'm sure it was a careless mistake!

    Code:
    Entity arrow = (Entity) e.getProjectile();
     
  9. Offline

    u_mad_bros

    @jlin13 Well damn, I thought that was right too, but it says that is undefined ? I use Eclipse, and it doesn't show up there either.. I wonder..?
     
  10. Offline

    jlin13

    What version are you developing with?

    Code:
    @EventHandler
        public void onArrowShoot(EntityShootBowEvent event) {
            if (event.getEntity() instanceof Player) {
                Entity arrow = event.getProjectile();
                arrowList.add(arrow.getUniqueId());
                double pitch = ((event.getEntity().getLocation().getPitch()) * Math.PI) / 180;
                double yaw = ((event.getEntity().getLocation().getYaw()) * Math.PI) / 180;
                double x = Math.sin(pitch) * Math.cos(yaw);
                double y = Math.sin(pitch) * Math.sin(yaw);
                double z = Math.cos(pitch);
                Vector vector = new Vector(x, z, y);
                event.getEntity().setVelocity(vector);
            }
        }
       
        @EventHandler
        public void onProjectileHit(ProjectileHitEvent event) {
            if (arrowList.contains(event.getEntity().getUniqueId())) {
                event.getEntity().getWorld().createExplosion(event.getEntity().getLocation(), 5);
                arrowList.remove(event.getEntity().getUniqueId());
            }
        }
    This built on 1.10.2 and ran fine
     
  11. Offline

    pretocki3

    @jlin13
    btw, You can use Metadata instead UUID ArrayList.
    Use Arrow.setMetadata("shootedArrow", new FixedMetadataValue(INSTANCE, 1)),
    Arrow.hasMetadata("shootedArrow")
    Arrow.removeMetadata("shootedArrow", INSTANCE),
     
    jlin13 likes this.
  12. Offline

    u_mad_bros

  13. Offline

    jlin13

  14. Offline

    u_mad_bros

  15. Offline

    oceantheskatr

    Dat onPlayerMove message

    Does it make a difference if you cast to Arrow instead of Entity?
     
  16. Offline

    u_mad_bros

    @oceantheskatr Got my hopes up, but negative.. Sorry about that onPlayerMove message lmao my best friend came over and he is fascinated about coding and such, so I made him apart of my plugin.
     
  17. Offline

    oceantheskatr

    @u_mad_bros Ugh you made me open Eclipse! lol


    Maybe give this a shot?

    Code:
        @EventHandler
        public void on(ProjectileHitEvent e) {
            if (!(e.getEntity() instanceof Arrow))
                return;
        
            Arrow arrow = (Arrow) e.getEntity();
            // Other stuff here
        }
     
  18. Offline

    u_mad_bros

Thread Status:
Not open for further replies.

Share This Page