Better Ground Telegraph Handling

This commit is contained in:
Kam committed 2026-02-24 00:31:20 -05:00
1 parent abc34b3f6f
commit 7d4157774a
7 files changed
+48 -14

No files matched your search

@@ -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;
}
/**
@@ -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());
@@ -538,7 +538,8 @@ public abstract class AbilityEnergyProjectile<E extends EntityEnergyProjectile>
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());
@@ -89,7 +89,8 @@ public class AbilityLaserShot extends AbilityEnergyProjectile<EntityAbilityLaser
telegraph.setWarningStartTick(Math.max(5, windUpTicks / 4));
telegraph.setHeightOffset(telegraphHeightOffset);
TelegraphInstance instance = new TelegraphInstance(telegraph, caster.posX, caster.posY, caster.posZ, caster.rotationYaw);
double groundY = findGroundLevel(caster.worldObj, caster.posX, caster.posY, caster.posZ);
TelegraphInstance instance = new TelegraphInstance(telegraph, caster.posX, groundY, caster.posZ, caster.rotationYaw);
instance.setCasterEntityId(caster.getEntityId());
instance.setEntityIdToFollow(caster.getEntityId());
if (target != null) {
@@ -157,8 +157,9 @@ public class AbilitySweeper extends AbilityEnergy implements IAbilitySweeper {
telegraph.setWarningStartTick(Math.max(5, windUpTicks / 4));
telegraph.setHeightOffset(telegraphHeightOffset);
// Position at caster, not target
TelegraphInstance instance = new TelegraphInstance(telegraph, caster.posX, caster.posY, caster.posZ, caster.rotationYaw);
// Position at caster ground level, not target
double groundY = findGroundLevel(caster.worldObj, caster.posX, caster.posY, caster.posZ);
TelegraphInstance instance = new TelegraphInstance(telegraph, caster.posX, groundY, caster.posZ, caster.rotationYaw);
instance.setCasterEntityId(caster.getEntityId());
instance.setEntityIdToFollow(caster.getEntityId()); // Follow caster
@@ -28,6 +28,7 @@ public class Telegraph {
private int warningStartTick = 10;
private boolean animated = true;
private float heightOffset = 0.1f;
private int groundSearchRange = 3;
// Positioning
private boolean atTarget = true;
@@ -57,6 +58,7 @@ public class Telegraph {
this.warningStartTick = other.warningStartTick;
this.animated = other.animated;
this.heightOffset = other.heightOffset;
this.groundSearchRange = other.groundSearchRange;
this.atTarget = other.atTarget;
this.followsTarget = other.followsTarget;
this.followsCaster = other.followsCaster;
@@ -82,6 +84,7 @@ public class Telegraph {
nbt.setInteger("warningStartTick", warningStartTick);
nbt.setBoolean("animated", animated);
nbt.setFloat("heightOffset", heightOffset);
nbt.setInteger("groundSearchRange", groundSearchRange);
nbt.setBoolean("atTarget", atTarget);
nbt.setBoolean("followsTarget", followsTarget);
nbt.setBoolean("followsCaster", followsCaster);
@@ -109,6 +112,9 @@ public class Telegraph {
this.warningStartTick = nbt.getInteger("warningStartTick");
this.animated = nbt.getBoolean("animated");
this.heightOffset = nbt.getFloat("heightOffset");
if (nbt.hasKey("groundSearchRange")) {
this.groundSearchRange = nbt.getInteger("groundSearchRange");
}
this.atTarget = nbt.getBoolean("atTarget");
this.followsTarget = nbt.getBoolean("followsTarget");
this.followsCaster = nbt.getBoolean("followsCaster");
@@ -264,6 +270,14 @@ public class Telegraph {
this.heightOffset = heightOffset;
}
public int getGroundSearchRange() {
return groundSearchRange;
}
public void setGroundSearchRange(int groundSearchRange) {
this.groundSearchRange = groundSearchRange;
}
public boolean isAtTarget() {
return atTarget;
}
@@ -96,7 +96,8 @@ public class TelegraphInstance {
this.x = entity.posX;
this.z = entity.posZ;
// Find ground level below the entity for proper telegraph placement
this.y = Ability.findGroundLevel(world, entity.posX, entity.posY, entity.posZ);
int searchRange = (telegraph != null) ? telegraph.getGroundSearchRange() : 3;
this.y = Ability.findGroundLevel(world, entity.posX, entity.posY, entity.posZ, searchRange);
// Track followed entity's yaw for directional telegraphs (player casters)
if (trackFollowedEntityYaw && targetEntityId < 0) {