1.8.8 Grappling hook

Discussion in 'Spigot Plugin Development' started by Minimigamer, Sep 28, 2020.

  1. Hey i have a problem with my grappling hook plugin.
    I need to find a way to detect if the player is reeling in his line ?
    so if he rightclicked a second time I need to get the location of the hook but how?
  2. I'd assume you can use the PlayerFishEvent and then check the state of it. Maybe something like this?:
    Code (Java):
    public void....(PlayerFishEvent event) {
        if (event.getState() != IN_GROUND) return;
        // Do stuff
  3. And for the velocity direction I'm pretty sure you take the new vector (bobber location) minus the from vector (player loc) and get direction multiply 3(for more launch) and setY(2)

  4. thats clear but i want to make it possible to activate the grappling hook in the air so it doesnt havt to hit the ground.
  5. You should be able to use the PlayerInteractEvent. Check if the player is using a rod, if so get the bobber location (if possible?) and then launch the player.
  6. You can get the bobber location under the event and get hook and then get loc
  7. you can get the bobber in the Fishing event but not in the interact event.
    or is that possible ?
  8. I don't think that you can get the bobber location 'until' it has landed upon a suitable solid block.
    Also, using a second right-click usually re-casts the rod. So, that would need accounting for within your code.
  9. The simple way:
    I wrote something like this before. Here is my code:
    Code (Text):

    @EventHandler(priority = EventPriority.HIGH)
    void onPlayerFish(PlayerFishEvent e) {
        if (e.getState() == PlayerFishEvent.State.IN_GROUND) {

    public void grapplingHook(FishHook fishhook) {
        Location location = fishhook.getLocation();
        double dx = location.getX() - p.getLocation().getX();
        double dy = location.getY() - p.getLocation().getY();
        double dz = location.getZ() - p.getLocation().getZ();
        double distance = Math.sqrt((dx * dx) + (dy * dy) + (dz * dz));
        double multiplier = 0.200;
        Vector velocity = new Vector(dx * multiplier, (dy * multiplier) + (double) Math.sqrt(distance) * 0.10, dz * multiplier);
    I don't mean to spoon-feed you code, but it seems like you know what to do and your questions are just on how vectors are defined so this should save you some time.

    Also note that the numbers in
    Code (Text):

    double multiplier = 0.200;
        Vector velocity = new Vector(dx * multiplier, (dy * multiplier) + (double) Math.sqrt(distance) * 0.10, dz * multiplier);
    are somewhat arbitrary. I just played with the numbers until the grappling hook did about what I wanted.

    The much more complicated way:
    If you want the player to land on a very precise point, you would need to do some kinematics:
    • First off, the problem can be converted to 2D by rotating our basis so that one of our basis vectors is in the direction of the velocity.
    • So we're converting (x,y,z) -> (u,y,w) where I'll say u is the horizontal direction we're going and w is just some vector perpendicular to y and u (we won't use w)
    • un-normalized, u = <(x_f-x_0),0,(z_f-z_0)> = <Δx,0,Δz>
    • Lastly, minecraft has a downward force depending on the entity and a drag force proportional to velocity (again depending on the entity), so we're going to need the direction of the velocity and it's magnitude. Our equations of motion still are confined to the u-y plane though
    • We'll call the constant proportional to downward acceleration g, and the constant proportional to drag for b.
    • c66618bb7c22598dc48d797c9dea4b4c.png
    Ex of what this looks like our rotation of basis may look like:

    The kinematics are a bit messy, but the results I got are:

    Which look complicated because, well they are. But they are workable. We want to find what our initial velocities should be This just takes some algebra:

    where T is a free parameter, meaning you can choose how long it takes the player to reach the position. This is basically the same as a pitcher throwing a ball to home plate so it arrives at different times. A fast ball will have higher initial velocity, while a curve ball will have slower initial velocity. The pitcher makes the choice in T and adjusts the velocities appropriately.

    The last problem to work out is to convert u velocity to x and z velocity. We have two unknowns and two equations:

    gif.gif (total speed matches)
    gif.gif (velocity directions agree)

    Which leaves you with the following quadratic equations to solve:
    Which is a cartesian mess! It simplifies in polar coordinates, but you're just going to get something along the lines of the solution below.

    Alternatively, you can avoid the quadratic since you have the direction of u, the direction of x, and the direction of z
    Use theta = u.angle(x) to get the rotation of x to u.
    and the conditions listed above will still be satisfied.

    Some final remarks:
    - I haven't checked my work, but I believe at worst I made an algebra mistake. The principles all should be correct.
    - These equations assume continuous motion, minecraft motion is NOT continuous so there will be slight error
    - b = 0.02 and g=0.08 for a player entity.
    - Time T is measure in ticks with the above values of b and g. You can multiple b by 20 and g by 400 to get the time T in seconds.

    Yes I understand this is needlessly complicated, but isn't that the fun of it?
    #9 suppusmac, Oct 12, 2020
    Last edited: Oct 14, 2020
    • Informative Informative x 2

  10. Thank you very much for your help. I think ill use the code you provided. I dont even understand half of the math you are doing xD im still in school and still learning and havent had algebra yet so there's that xD