diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java index 71295c60d..d3f6b715b 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java @@ -961,31 +961,46 @@ public abstract class Ability implements IAbility, IAbilityAction { /** * Find the ground level at a given position. * Searches downward from the given Y to find a solid block. + * Uses default search range of 3 blocks — if no ground is found, + * returns slightly below the entity for airborne telegraph placement. * * @param world The world * @param x X coordinate * @param startY Starting Y coordinate (entity feet position) * @param z Z coordinate - * @return The Y coordinate of the ground surface + * @return The Y coordinate of the ground surface, or startY - 0.5 if airborne */ public static double findGroundLevel(World world, double x, double startY, double z) { - if (world == null) return startY; + return findGroundLevel(world, x, startY, z, 3); + } + + /** + * Find the ground level at a given position with configurable search range. + * Searches downward from the given Y to find a solid block. + * + * @param world The world + * @param x X coordinate + * @param startY Starting Y coordinate (entity feet position) + * @param z Z coordinate + * @param maxSearchDown Maximum blocks to search downward + * @return The Y coordinate of the ground surface, or startY - 0.5 if no ground found + */ + public static double findGroundLevel(World world, double x, double startY, double z, int maxSearchDown) { + if (world == null) return startY - 0.5; int blockX = (int) Math.floor(x); int blockZ = (int) Math.floor(z); int startBlockY = (int) Math.floor(startY); - // Search downward for solid ground (max 10 blocks down) - for (int checkY = startBlockY; checkY >= startBlockY - 10 && checkY >= 0; checkY--) { + for (int checkY = startBlockY; checkY >= startBlockY - maxSearchDown && checkY >= 0; checkY--) { Block block = world.getBlock(blockX, checkY, blockZ); if (block != null && block.getMaterial().isSolid()) { - // Found solid block, telegraph goes on top of it return checkY + 1; } } - // No ground found, use original position - return startY; + // No ground found within range — place slightly under entity + return startY - 0.5; } /** diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java index 21177a650..bf7f958fe 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java @@ -659,8 +659,8 @@ public class AbilitySlam extends Ability implements IAbilitySlam { targetZ = caster.posZ; } - // Create telegraph at the appropriate position - double groundY = findGroundLevel(caster.worldObj, targetX, targetY, targetZ); + // Create telegraph at the appropriate position — always project to actual ground for landing zone + double groundY = findGroundLevel(caster.worldObj, targetX, targetY, targetZ, 64); Telegraph telegraph = Telegraph.circle(radius); telegraph.setDurationTicks(windUpTicks); @@ -668,6 +668,7 @@ public class AbilitySlam extends Ability implements IAbilitySlam { telegraph.setWarningColor(activeColor); telegraph.setWarningStartTick(Math.max(5, windUpTicks / 4)); telegraph.setHeightOffset(telegraphHeightOffset); + telegraph.setGroundSearchRange(64); // Slam always projects to actual ground (landing zone) TelegraphInstance instance = new TelegraphInstance(telegraph, targetX, groundY, targetZ, caster.rotationYaw); instance.setCasterEntityId(caster.getEntityId()); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyProjectile.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyProjectile.java index d65c6e7e6..7367a742a 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyProjectile.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyProjectile.java @@ -538,7 +538,8 @@ public abstract class AbilityEnergyProjectile telegraph.setWarningStartTick(Math.max(5, windUpTicks / 4)); telegraph.setHeightOffset(telegraphHeightOffset); - TelegraphInstance instance = new TelegraphInstance(telegraph, target.posX, target.posY, target.posZ, caster.rotationYaw); + double groundY = findGroundLevel(caster.worldObj, target.posX, target.posY, target.posZ); + TelegraphInstance instance = new TelegraphInstance(telegraph, target.posX, groundY, target.posZ, caster.rotationYaw); instance.setCasterEntityId(caster.getEntityId()); instance.setEntityIdToFollow(target.getEntityId()); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityLaserShot.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityLaserShot.java index 49efb5ad1..53fe578f1 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityLaserShot.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityLaserShot.java @@ -89,7 +89,8 @@ public class AbilityLaserShot extends AbilityEnergyProjectile