diff --git a/src/main/java/noppes/npcs/config/ConfigMain.java b/src/main/java/noppes/npcs/config/ConfigMain.java index 4c44c35f2..bbd6e17b3 100644 --- a/src/main/java/noppes/npcs/config/ConfigMain.java +++ b/src/main/java/noppes/npcs/config/ConfigMain.java @@ -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); diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index ae4aba781..1c106d7f6 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -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"))) {