diff --git a/src/main/java/net/countercraft/movecraft/combat/features/directors/AADirectors.java b/src/main/java/net/countercraft/movecraft/combat/features/directors/AADirectors.java index 1ccbcb67..7da4c653 100644 --- a/src/main/java/net/countercraft/movecraft/combat/features/directors/AADirectors.java +++ b/src/main/java/net/countercraft/movecraft/combat/features/directors/AADirectors.java @@ -4,6 +4,7 @@ import net.countercraft.movecraft.combat.features.directors.events.CraftDirectEvent; import net.countercraft.movecraft.combat.localisation.I18nSupport; import net.countercraft.movecraft.combat.utils.DirectorUtils; +import net.countercraft.movecraft.combat.utils.MathHelper; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.PlayerCraft; @@ -97,14 +98,15 @@ private void processFireball(@NotNull SmallFireball fireball) { double speed = fireballVector.length() ; // store the speed to add it back in later, since all the values we will be using are "normalized", IE: have a speed of 1 fireballVector = fireballVector.normalize(); // you normalize it for comparison with the new direction to see if we are trying to steer too far - Block targetBlock = DirectorUtils.getDirectorBlock(p, AADirectorRange); - Vector targetVector; + // the player is looking at nothing, shoot in that general direction + Vector targetVector = p.getLocation().getDirection(); - if (targetBlock == null || targetBlock.getType().isAir()) // the player is looking at nothing, shoot in that general direction - targetVector = p.getLocation().getDirection(); - else { // shoot directly at the block the player is looking at (IE: with convergence) - targetVector = targetBlock.getLocation().toVector().subtract(fireball.getLocation().toVector()); - targetVector = targetVector.normalize(); + if (AADirectorRange >= 0) { + Block targetBlock = DirectorUtils.getDirectorBlock(p, AADirectorRange); + if (targetBlock != null && !targetBlock.getType().isAir()) { + targetVector = targetBlock.getLocation().toVector().subtract(fireball.getLocation().toVector()); + targetVector = targetVector.normalize(); + } } if (targetVector.getX() - fireballVector.getX() > 0.5) @@ -129,6 +131,9 @@ else if (targetVector.getZ() - fireballVector.getZ() < -0.5) fireballVector.setZ(targetVector.getZ()); fireballVector = fireballVector.multiply(speed); // put the original speed back in, but now along a different trajectory + + MathHelper.clampVectorModify(fireballVector); + try { fireballVector.checkFinite(); } diff --git a/src/main/java/net/countercraft/movecraft/combat/features/directors/ArrowDirectors.java b/src/main/java/net/countercraft/movecraft/combat/features/directors/ArrowDirectors.java index 56d6bfad..5e87d539 100644 --- a/src/main/java/net/countercraft/movecraft/combat/features/directors/ArrowDirectors.java +++ b/src/main/java/net/countercraft/movecraft/combat/features/directors/ArrowDirectors.java @@ -4,6 +4,7 @@ import net.countercraft.movecraft.combat.features.directors.events.CraftDirectEvent; import net.countercraft.movecraft.combat.localisation.I18nSupport; import net.countercraft.movecraft.combat.utils.DirectorUtils; +import net.countercraft.movecraft.combat.utils.MathHelper; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.PlayerCraft; @@ -95,13 +96,15 @@ private void processArrow(@NotNull Arrow arrow) { double speed = arrowVector.length(); // store the speed to add it back in later, since all the values we will be using are "normalized", IE: have a speed of 1 arrowVector = arrowVector.normalize(); // you normalize it for comparison with the new direction to see if we are trying to steer too far - Block targetBlock = DirectorUtils.getDirectorBlock(p, ArrowDirectorRange); - Vector targetVector; - if (targetBlock == null || targetBlock.getType().equals(Material.AIR)) // the player is looking at nothing, shoot in that general direction - targetVector = p.getLocation().getDirection(); - else { // shoot directly at the block the player is looking at (IE: with convergence) - targetVector = targetBlock.getLocation().toVector().subtract(arrow.getLocation().toVector()); - targetVector = targetVector.normalize(); + // the player is looking at nothing, shoot in that general direction + Vector targetVector = p.getLocation().getDirection(); + if (ArrowDirectorRange >= 0) { + Block targetBlock = DirectorUtils.getDirectorBlock(p, ArrowDirectorRange); + if (targetBlock != null && !targetBlock.getType().equals(Material.AIR)) { + // shoot directly at the block the player is looking at (IE: with convergence) + targetVector = targetBlock.getLocation().toVector().subtract(arrow.getLocation().toVector()); + targetVector = targetVector.normalize(); + } } if (targetVector.getX() - arrowVector.getX() > 0.5) @@ -126,6 +129,9 @@ else if (targetVector.getZ() - arrowVector.getZ() < -0.5) arrowVector.setZ(targetVector.getZ()); arrowVector = arrowVector.multiply(speed); // put the original speed back in, but now along a different trajectory + + MathHelper.clampVectorModify(arrowVector); + try { arrowVector.checkFinite(); } diff --git a/src/main/java/net/countercraft/movecraft/combat/features/directors/CannonDirectors.java b/src/main/java/net/countercraft/movecraft/combat/features/directors/CannonDirectors.java index 98f66510..7f7f7058 100644 --- a/src/main/java/net/countercraft/movecraft/combat/features/directors/CannonDirectors.java +++ b/src/main/java/net/countercraft/movecraft/combat/features/directors/CannonDirectors.java @@ -6,6 +6,7 @@ import net.countercraft.movecraft.combat.features.tracking.DamageTracking; import net.countercraft.movecraft.combat.localisation.I18nSupport; import net.countercraft.movecraft.combat.utils.DirectorUtils; +import net.countercraft.movecraft.combat.utils.MathHelper; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.PlayerCraft; @@ -124,12 +125,16 @@ private void processTNT(@NotNull TNTPrimed tnt) { double horizontalSpeed = tntVector.length(); tntVector = tntVector.normalize(); // you normalize it for comparison with the new direction to see if we are trying to steer too far - Block targetBlock = DirectorUtils.getDirectorBlock(p, CannonDirectorRange); - Vector targetVector; - if (targetBlock == null || targetBlock.getType().equals(Material.AIR)) // the player is looking at nothing, shoot in that general direction - targetVector = p.getLocation().getDirection(); - else // shoot directly at the block the player is looking at (IE: with convergence) - targetVector = targetBlock.getLocation().toVector().subtract(tnt.getLocation().toVector()); + // the player is looking at nothing, shoot in that general direction + Vector targetVector = p.getLocation().getDirection(); + + if (CannonDirectorRange >= 0) { + Block targetBlock = DirectorUtils.getDirectorBlock(p, CannonDirectorRange); + if (targetBlock != null && targetBlock.getType().equals(Material.AIR)) { + // shoot directly at the block the player is looking at (IE: with convergence) + targetVector = targetBlock.getLocation().toVector().subtract(tnt.getLocation().toVector()); + } + } // Remove the y-component from the TargetVector and normalize targetVector = (new Vector(targetVector.getX(), 0, targetVector.getZ())).normalize(); @@ -139,6 +144,9 @@ private void processTNT(@NotNull TNTPrimed tnt) { tntVector.setZ(Math.min(Math.max(targetVector.getZ(), tntVector.getZ() - 0.7), tntVector.getZ() + 0.7)); tntVector = tntVector.multiply(horizontalSpeed); // put the original speed back in, but now along a different trajectory + + MathHelper.clampVectorModify(tntVector); + tntVector.setY(tnt.getVelocity().getY()); // you leave the original Y (or vertical axis) trajectory as it was try { diff --git a/src/main/java/net/countercraft/movecraft/combat/utils/MathHelper.java b/src/main/java/net/countercraft/movecraft/combat/utils/MathHelper.java new file mode 100644 index 00000000..7935943d --- /dev/null +++ b/src/main/java/net/countercraft/movecraft/combat/utils/MathHelper.java @@ -0,0 +1,63 @@ +package net.countercraft.movecraft.combat.utils; + +import org.bukkit.Axis; +import org.bukkit.util.Vector; + +public class MathHelper { + + public static double clamp(double value) { + // Double.MIN_VALUE represents the lowest POSITIVE double value to match IEEE754 format + return clamp(-Double.MAX_VALUE, Double.MAX_VALUE, value); + } + + // Same as with doubles! + public static float clamp(float value) { + return clamp(-Float.MAX_VALUE, Float.MAX_VALUE, value); + } + + public static int clamp(int value) { + return clamp(Integer.MIN_VALUE, Integer.MAX_VALUE, value); + } + + public static double clamp(double min, double max, double value) { + if (value > max) { + return max; + } + if (value < min) { + return min; + } + return value; + } + + public static int clamp(int min, int max, int value) { + if (value > max) { + return max; + } + if (value < min) { + return min; + } + return value; + } + + public static float clamp(float min, float max, float value) { + if (value > max) { + return max; + } + if (value < min) { + return min; + } + return value; + } + + public static void clampVectorModify(final Vector vector) { + vector.setX(clamp(vector.getX())); + vector.setY(clamp(vector.getY())); + vector.setZ(clamp(vector.getZ())); + } + public static Vector clampVector(final Vector vector) { + Vector result = vector.clone(); + clampVectorModify(result); + return result; + } + +}