Return npcs to their start position when they fall out of the world

This commit is contained in:
KAMKEEL committed 2026-08-11 12:29:56 -04:00
1 parent 32c5cc78c7
commit 605907681c
2 files changed
+45

No files matched your search

@@ -127,6 +127,9 @@ public class ConfigMain {
public static Property HitBoxScaleMaxProperty;
public static int HitBoxScaleMax = 15;
public static Property NpcVoidRecoveryProperty;
public static boolean NpcVoidRecovery = true;
/**
* Update Properties
**/
@@ -184,6 +187,9 @@ public class ConfigMain {
OpsOnlyProperty = config.get(NPC, "Only Ops Edit NPCs", false, "Only ops can create and edit npcs");
OpsOnly = OpsOnlyProperty.getBoolean(false);
NpcVoidRecoveryProperty = config.get(NPC, "NPC Void Recovery", true, "Teleport npcs that fall out of the world back to their start position instead of letting them fall forever");
NpcVoidRecovery = NpcVoidRecoveryProperty.getBoolean(true);
NpcUseOpCommandsProperty = config.get(NPC, "NPC Use Op Commands", false, "Set to true if you want the dialog command option to be able to use op commands like tp etc");
NpcUseOpCommands = NpcUseOpCommandsProperty.getBoolean(false);
@@ -657,6 +657,45 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
return null;
}
@Override
protected void kill() {
if (!worldObj.isRemote && ConfigMain.NpcVoidRecovery && posY < -64.0D && returnFromVoid())
return;
super.kill();
}
/**
* Puts the npc back on its start position after it has dropped out of the world.
* Offset by one block so a hole in the floor underneath does not drop it straight back down.
*/
private boolean returnFromVoid() {
int[] start = getStartPos();
int x = start[0];
int y = start[1];
int z = start[2];
// A npc that fell before its start position was ever stored has the void baked into it.
if (y < 1 || y > worldObj.getHeight()) {
y = worldObj.getTopSolidOrLiquidBlock(x, z);
if (y < 1)
return false;
ais.startPos = new int[]{x, y, z};
}
setLocationAndAngles(x + 1.5D, y + 1.0D, z + 0.5D, rotationYaw, rotationPitch);
motionX = motionY = motionZ = 0;
fallDistance = 0;
isAirBorne = false;
ySize = 0;
extinguish();
getNavigator().clearPathEntity();
if (canFly()) {
((PathNavigateFlying) getNavigator()).targetPos = null;
((FlyingMoveHelper) getMoveHelper()).update = false;
}
return true;
}
@Override
public boolean attackEntityFrom(DamageSource damagesource, float i) {
if (this.worldObj.isRemote || CustomNpcs.FreezeNPCs || (damagesource.damageType != null && damagesource.damageType.equals("inWall"))) {