Solved Swifter Movement Through Water

Discussion in 'Spigot Plugin Development' started by Qruet, Jun 6, 2017.

  1. I'm creating a plugin that would mimic sort of like a pixie pet that follows you about etc. However when it comes to water the pixie pet which is actual an entity that's invisible can't swim fast in water. This removes the effect of some sort of hovering/flying fairy that's following you. I played around with velocity however when using the following code to change it's velocity when water, the entity (tamed wolf) simply travels in a direct straight line until it leaves the water. It looks a bit strange/unnatural. I'm wondering if there is a way to have the entity simply hover slightly above the water so they're not actually swimming and have control over where they are going. I understand velocity has to be used but I'd like it so that the entity can control their yaw so they follow the player as he swims across the water rather then simply passing the player in a straight line in the direction the entity was last facing.

    Code (Text):
                                      Vector dir = location.getDirection();
                                      Vector vec = new Vector(dir.getX()*0.1, dir.getY()*0.1, dir.getZ()*0.1);
                                      wolf.setVelocity(vec);
    ~Geekles
     
  2. I don't know how finely you can tune the position of your entity, but assuming you have as much control as a no-gravity armor stand (or you make it ride one):

    Teleport the entity along so that it follows a path you set, make the y component dependant on a sine curve and the x on relative position to the player / your path.

    Edit: actually finished typing
     
    #2 stormtrooper28, Jun 6, 2017
    Last edited: Jun 6, 2017
  3. I'm not exactly sure what you meant there but if I understand correctly you're asking that I set a specific path for the pet from point A to point B. The thing is though that again it'll look unnatural. The pet has to follow the player at all times (unless it's attacking an entity), there is no way to predict where the player will move. Unless you're asking me to constantly change point B to the position of the player. Also regarding to teleportation, from previous experiences teleportation hasn't necessarily been a very smooth option with creating some sort of natural movement. I'm hoping a simpler (cleaner) approach by simply using velocity.
    ~Geekles
     
  4. Still need help :/ *bump*
     
  5. Might be time to make your own entity using NMS. Since it's a flying fairy might I suggest using a bat, vex, or even parrot as a base to start from since those are already flying mobs.
     
  6. Well having these mobs attack an entity when that entity is hit would be challenging, and therefore wolves seem basic enough for now. I would have to play around with NMS to make what your saying work however I've never used NMS, and have almost to no clue as to how it works. This project I'm working on is actually something with a deadline for a server I'm helping out, therefore I don't believe I would have the time to learn NMS and then implement it into my plugin. I'm hoping that perhaps there's a simpler solution, or a more temporary workable solution.
    ~Geekles
     
  7. Perfectly understandable. ^_^

    Just in case you end up circling back to nms here are some things to research: extend a new mob from an existing mob, inject it into the biome data so it can spawn naturally (or just handle spawning it yourself how you see fit), and most I'm be sure to set your own Pathfinders or even make your own (Pathfinders aren't just how it moves/walks, but also how it targets and deals damage, etc).

    As for doing it all with the API, you're going to be very limited, and I'm afraid I can't be of assistance there.
     
  8. Hmm okay, I'll look into it in the future when I have time to work on updating/improving the plugin but I guess atm I just need some quick solution that uses the spigot api.
    ~Geekles
     
  9. Hmm, nms has lots of stubs and help points, it should prompt you how you should do stuff. Try importing craftbukkit.jar as External JAR and you get nms and org.bukkit.craftbukkit abilities
     
  10. Maybe you could pause your code every few ticks so the wolf can turn naturally for one tick. I think that you are modifying the velocity to quickly so the wolf won't turn to the player
     
  11. I've considered that, might be worth a try but I might risk have the wolf fall back into the water (the velocity allows to have the wolf hover over the water).
    ~Geekles
     
  12. Well after several tweaks I somewhat gotten the wolf to follow the player in water with a slight delay in a loop. It's a bit sloppy and the movement isn't as swift/accurate as I'd like it on land however it seems to do a decent job. (Doesn't just flow in a straight line)
    Loops every 3 ticks...

    Code (Text):
     
        @Override
        public void run() {
               for(World world: Bukkit.getWorlds()){
                   for(Entity entity: Bukkit.getWorld(world.getName()).getEntities()){
                       if(Listeners.isPixie(entity)){
                           Wolf wolf = (Wolf) entity;
                           
                           
                           Location location1 = wolf.getLocation();
                           location1.setY(location1.getY() - 1);
                           
                           Location location2= wolf.getLocation();
                           location2.setY(location2.getY() - 2);
                           
                           Vector dir;
                           Vector vec;
                           if(wolf.getLocation().getBlock().getType() == Material.WATER || wolf.getLocation().getBlock().getType() == Material.STATIONARY_WATER){
                               dir = wolf.getLocation().getDirection();
                               vec = new Vector(dir.getX()*0.16, dir.getY()*0.2, dir.getZ()*0.16);
                               wolf.setVelocity(vec);
                               
                               
                               
                               
                           if(location1.getBlock().getType() == Material.WATER || location1.getBlock().getType() == Material.STATIONARY_WATER){
                               dir = location1.getDirection();
                               vec = new Vector(dir.getX()*0.16, dir.getY()*0.2, dir.getZ()*0.16);
                               wolf.setVelocity(vec);
                           }
                           if(location2.getBlock().getType() == Material.WATER || location2.getBlock().getType() == Material.STATIONARY_WATER){
                               dir = location2.getDirection();
                               vec = new Vector(dir.getX()*0.16, dir.getY()*0.2, dir.getZ()*0.16);
                               wolf.setVelocity(vec);
                           }
                   }
                       }
                   }
               }
           
        }