1.15.2 Question about snowball flight paths

Discussion in 'Spigot Plugin Development' started by ThePandaPlayer, Jan 17, 2020.

  1. Hi. I am creating a custom gun plugin for a server of mine. I've gotten most systems figured out, now I'm working on how to manage bullet velocity.

    I calculate it in a pretty usual way. Get the shooter's direction from eye location, normalize, then multiply by a constant that is the ammo type's defined velocity. It all works fine, but there's one small problem: The bullets appear to go off course then instantly curve back to their correct flight path.

    Here's a video demonstrating this issue:

    As you can see, the bullet snaps back onto the correct course of flight after a certain distance.

    The strange thing is, is that as you turn your head the effect gets less and less pronounced. Then at a certain point, it pretty much doesn't happen anymore. Then as you continue to turn your head the issue gets more and more pronounced.

    Here's my current code:
    Code (Java):
    Snowball snowball = holder.launchProjectile(Snowball.class);
    Vector playerDir = holder.getEyeLocation().getDirection();
    Vector bulletVelocity = playerDir.multiply(ammoType.speed);
    Note that AmmoType.speed for the gun in the video is the double value 4.8.

    Is there any way to combat this?
  2. That's a common problem with projectiles at high velocities.
    I think the packet contains a vector with 3 components, each represented by a signed short.
    What you are experiencing is probably overflow related. (i think ~4 Blocks per tick is max)

    There is maybe a way with the Entity Relative Move packet as it supports a change in position of up to 8 blocks per tick.
    This would mean that you have to compute the flight path by yourself.
    In this case it would probably be better to use a 'virtual' projectile, that is represented by particles.

    PS if you just need less bullet drop try to modify the gravity of the projectile.
  3. Thank you for your response.
    If I decided I wanted to go for the 'virtual' projectile, then I'd probably just design a hit-scan system with raytracing. That's not really how I've envisioned the guns to work though. I do want some sort of ballistics. However, calculating physics is beyond my skills. I guess I'll have to balance around the 4 blocks per tick limit.
  4. I mean... x'' = -a, which leads instantly to x = -0.5 at^2 + v0 * t + x0...
    That is the formula that gives you the position that has to be updated every tick.
    x is the position, a is the acceleration, v0 is the initial velocity, x0 is the initial point.

    Everything is given, x0 is the player's location (maybe plus one), v0 is the player's direction, normalized and multiplied to get your velocity and a is just an arbitrary number that you can make up to customize the bullet drop... it's not that hard.

    Alternatively, you adapt the velocity at each discrete time-step, which would lead to an even simpler solution:
    v = -a * t + v0
  5. You could always look into plugins that do this already, like CrackShot
    Or, you could make the snowball invisible then spawn particles wherever the snowball is.

    I know for a fact that the snowball is moving correctly, but it is rendering wrong, which is why particles work correctly here. CrackShotPlus is a good plugin that does this.
  6. I've looked into it, and It seems I'd have to do a lot of fiddling with NMS packets if I wanted to make the snowball invisible. Frankly, I'm not too familiar with NMS, and I've always found that when I've messed with it, It causes way to many problems than It would solve. Thank you though.

    EDIT: I decided to do some mucking about with NMS, and I found a solution where I can simply send a PacketPlayOutEntityDestroy, and then do a synchronous repeating task with PacketPlayOutWorldParticles within my bullet class. This will be my solution.

    Thanks for the help.
    #6 ThePandaPlayer, Jan 18, 2020
    Last edited: Jan 18, 2020
    • Like Like x 1