Skip to content

Instantly share code, notes, and snippets.

@IllusionTheDev
Last active February 7, 2024 21:06
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IllusionTheDev/b770d8e2ffd7a7d80351686c5ea46963 to your computer and use it in GitHub Desktop.
Save IllusionTheDev/b770d8e2ffd7a7d80351686c5ea46963 to your computer and use it in GitHub Desktop.
Simulate realistic player knockback
// Ported from Exerosis' kotlin example
public class KnockbackUtil {
private static final double FRICTION = 1.0;
private static final double HORIZONTAL = 0.40;
private static final double VERTICAL = 0.36075;
private static final double EXTRA_VERTICAL = 0.1;
private static final double EXTRA_HORIZONTAL = 1.5;
public static Vector getKnockback(Location entityLoc, Entity attacker) {
if(attacker == null) {
return new Vector(0.0, -0.078375, 0.0);
}
ThreadLocalRandom random = ThreadLocalRandom.current();
Location from = attacker.getLocation();
double deltaX = entityLoc.getX() - from.getX();
double deltaZ = entityLoc.getZ() - from.getZ();
double y = VERTICAL;
// --- SECTION START ---
// Comment to add consistency and improve performance
while (deltaX * deltaX + deltaZ * deltaZ < 1.0E-4) {
deltaX = (random.nextDouble()) - random.nextDouble() * 0.01;
deltaZ = (random.nextDouble()) - random.nextDouble() * 0.01;
}
// --- SECTION END ---
double distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ) * FRICTION;
deltaX = deltaX / distance * HORIZONTAL;
deltaZ = deltaZ / distance * HORIZONTAL;
if(!attacker.isCrouching()) {
double yaw = from.getYaw() * Math.PI / 180;
deltaX += -Math.sin(yaw) * EXTRA_HORIZONTAL;
deltaZ = Math.cos(yaw) * EXTRA_HORIZONTAL;
y += EXTRA_VERTICAL;
deltaX *= 0.6;
deltaZ *= 0.6;
}
return new Vector(deltaX, y, deltaZ);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment