package de.oppermann.bastian.spleef.util;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import de.oppermann.bastian.spleef.SpleefMain;
/**
* Inspired by BlingGravity (http://sethbling.com/downloads/bukkit-plugins/blinggravity/)
*
* @author Bastian Oppermann
*
*/
public class GravityModifier {
private static final HashMap<UUID, Double> MODIFY = new HashMap<>();
private static final HashMap<UUID, Vector> OLD_VELOCITIES = new HashMap<>();
static {
Bukkit.getScheduler().runTaskTimer(SpleefMain.getInstance(), new Runnable() {
@Override
public void run() {
onTick();
}
}, 1, 1);
}
private GravityModifier() { } // singleton
/**
* Sets the gravity for the player with the given uuid.
*
* @param player The uuid of the player. Won't work for animals.
* @param gravity The gravity. A number less than 1 will decrease gravity.
*/
public static void modifyGravity(UUID player, double gravity) {
MODIFY.put(player, gravity);
}
/**
* Resets the gravity for the player with the given uuid.
*
* @param player The uuid of the player.
*/
public static void resetGravity(UUID player) {
MODIFY.remove(player);
OLD_VELOCITIES.remove(player);
}
private static void onTick() {
for (Entry<UUID, Double> entry : MODIFY.entrySet()) {
Player player = Bukkit.getPlayer(entry.getKey());
updateVelocities(entry.getValue(), player);
}
}
@SuppressWarnings("deprecation") // cause isOnGround() is deprecated
private static void updateVelocities(double gravity, Player player) {
UUID uuid = player.getUniqueId();
Vector newVector = player.getVelocity().clone();
if (OLD_VELOCITIES.containsKey(uuid) && !player.isInsideVehicle()) {
if (!player.isOnGround()) {
Vector oldVector = OLD_VELOCITIES.get(uuid);
Vector oldVectorClone = oldVector.clone();
oldVectorClone.subtract(newVector);
double oldVectorCloneY = oldVectorClone.getY();
if (oldVectorCloneY > 0.0D && (newVector.getY() < -0.01D || newVector.getY() > 0.01D)) {
newVector.setY(oldVector.getY() - oldVectorCloneY * gravity);
boolean newXChanged = newVector.getX() < -0.001D || newVector.getX() > 0.001D;
boolean oldXChanged = oldVector.getX() < -0.001D || oldVector.getX() > 0.001D;
if (newXChanged && oldXChanged) {
newVector.setX(oldVector.getX());
}
boolean newZChanged = newVector.getZ() < -0.001D || newVector.getZ() > 0.001D;
boolean oldZChanged = oldVector.getZ() < -0.001D || oldVector.getZ() > 0.001D;
if (newZChanged && oldZChanged) {
newVector.setZ(oldVector.getZ());
}
player.setVelocity(newVector.clone());
}
}
}
OLD_VELOCITIES.put(uuid, newVector.clone());
}
}