From 93c78bb41887d677cca8db813416ba3d5d07a480 Mon Sep 17 00:00:00 2001 From: fullwall Date: Mon, 19 Aug 2024 00:04:04 +0800 Subject: [PATCH] Attempt fix for boat pathfinding - slightly hacky --- .../entity/nonliving/BoatController.java | 18 +- .../entity/nonliving/BoatController.java | 18 +- .../entity/nonliving/BoatController.java | 18 +- .../entity/nonliving/BoatController.java | 18 +- .../entity/nonliving/BoatController.java | 230 ++++++++++-------- 5 files changed, 172 insertions(+), 130 deletions(-) diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/nonliving/BoatController.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/nonliving/BoatController.java index 6b58b45a3..294c734af 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/nonliving/BoatController.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/entity/nonliving/BoatController.java @@ -49,12 +49,10 @@ public class BoatController extends MobEntityController { public static class EntityBoatNPC extends Boat implements NPCHolder { private double aC; - private float aD; private Status aE; private Status aF; private double ap; - private double ar; private final CitizensNPC npc; public EntityBoatNPC(EntityType types, Level level) { @@ -174,7 +172,18 @@ public class BoatController extends MobEntityController { @Override public void tick() { if (npc != null) { + baseTick(); + if (getControllingPassenger() instanceof NPCHolder + && ((NPCHolder) getControllingPassenger()).getNPC().getNavigator().isNavigating()) { + setDeltaMovement(getControllingPassenger().getDeltaMovement().multiply(20, 1, 20)); + } npc.update(); + if (getHurtTime() > 0) { + setHurtTime(getHurtTime() - 1); + } + if (getDamage() > 0.0F) { + setDamage(getDamage() - 1.0F); + } this.aF = this.aE; aE = getStatus(); double d1 = isNoGravity() ? 0.0D : -0.04D; @@ -205,16 +214,13 @@ public class BoatController extends MobEntityController { } Vec3 vec3d = getDeltaMovement(); setDeltaMovement(vec3d.x * this.ap, vec3d.y + d1, vec3d.z * this.ap); - this.ar *= this.ap; if (d2 > 0.0D) { Vec3 vec3d1 = getDeltaMovement(); setDeltaMovement(vec3d1.x, vec3d1.y + d2 * 0.0615D, vec3d1.z); } } move(MoverType.SELF, getDeltaMovement()); - if (isVehicle()) { - setYRot((float) (getYRot() + this.ar)); - } + checkInsideBlocks(); } else { super.tick(); } diff --git a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/entity/nonliving/BoatController.java b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/entity/nonliving/BoatController.java index 0044b2714..f30d13029 100644 --- a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/entity/nonliving/BoatController.java +++ b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/entity/nonliving/BoatController.java @@ -50,12 +50,10 @@ public class BoatController extends MobEntityController { public static class EntityBoatNPC extends Boat implements NPCHolder { private double aC; - private float aD; private Status aE; private Status aF; private double ap; - private double ar; private final CitizensNPC npc; public EntityBoatNPC(EntityType types, Level level) { @@ -182,7 +180,18 @@ public class BoatController extends MobEntityController { @Override public void tick() { if (npc != null) { + baseTick(); + if (getControllingPassenger() instanceof NPCHolder + && ((NPCHolder) getControllingPassenger()).getNPC().getNavigator().isNavigating()) { + setDeltaMovement(getControllingPassenger().getDeltaMovement().multiply(20, 1, 20)); + } npc.update(); + if (getHurtTime() > 0) { + setHurtTime(getHurtTime() - 1); + } + if (getDamage() > 0.0F) { + setDamage(getDamage() - 1.0F); + } this.aF = this.aE; aE = getStatus(); double d1 = isNoGravity() ? 0.0D : -0.04D; @@ -213,16 +222,13 @@ public class BoatController extends MobEntityController { } Vec3 vec3d = getDeltaMovement(); setDeltaMovement(vec3d.x * this.ap, vec3d.y + d1, vec3d.z * this.ap); - this.ar *= this.ap; if (d2 > 0.0D) { Vec3 vec3d1 = getDeltaMovement(); setDeltaMovement(vec3d1.x, vec3d1.y + d2 * 0.0615D, vec3d1.z); } } move(MoverType.SELF, getDeltaMovement()); - if (isVehicle()) { - setYRot((float) (getYRot() + this.ar)); - } + checkInsideBlocks(); } else { super.tick(); } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/nonliving/BoatController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/nonliving/BoatController.java index d1324a3c3..55059ac60 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/nonliving/BoatController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/nonliving/BoatController.java @@ -51,12 +51,10 @@ public class BoatController extends MobEntityController { public static class EntityBoatNPC extends Boat implements NPCHolder { private double aC; - private float aD; private Status aE; private Status aF; private double ap; - private double ar; private final CitizensNPC npc; public EntityBoatNPC(EntityType types, Level level) { @@ -183,7 +181,18 @@ public class BoatController extends MobEntityController { @Override public void tick() { if (npc != null) { + baseTick(); + if (getControllingPassenger() instanceof NPCHolder + && ((NPCHolder) getControllingPassenger()).getNPC().getNavigator().isNavigating()) { + setDeltaMovement(getControllingPassenger().getDeltaMovement().multiply(20, 1, 20)); + } npc.update(); + if (getHurtTime() > 0) { + setHurtTime(getHurtTime() - 1); + } + if (getDamage() > 0.0F) { + setDamage(getDamage() - 1.0F); + } this.aF = this.aE; aE = getStatus(); double d1 = isNoGravity() ? 0.0D : -0.04D; @@ -214,16 +223,13 @@ public class BoatController extends MobEntityController { } Vec3 vec3d = getDeltaMovement(); setDeltaMovement(vec3d.x * this.ap, vec3d.y + d1, vec3d.z * this.ap); - this.ar *= this.ap; if (d2 > 0.0D) { Vec3 vec3d1 = getDeltaMovement(); setDeltaMovement(vec3d1.x, vec3d1.y + d2 * 0.0615D, vec3d1.z); } } move(MoverType.SELF, getDeltaMovement()); - if (isVehicle()) { - setYRot((float) (getYRot() + this.ar)); - } + checkInsideBlocks(); } else { super.tick(); } diff --git a/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/entity/nonliving/BoatController.java b/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/entity/nonliving/BoatController.java index 8a315a8c2..60df8bf24 100644 --- a/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/entity/nonliving/BoatController.java +++ b/v1_20_R4/src/main/java/net/citizensnpcs/nms/v1_20_R4/entity/nonliving/BoatController.java @@ -49,12 +49,10 @@ public class BoatController extends MobEntityController { public static class EntityBoatNPC extends Boat implements NPCHolder { private double aC; - private float aD; private Status aE; private Status aF; private double ap; - private double ar; private final CitizensNPC npc; public EntityBoatNPC(EntityType types, Level level) { @@ -173,7 +171,18 @@ public class BoatController extends MobEntityController { @Override public void tick() { if (npc != null) { + baseTick(); + if (getControllingPassenger() instanceof NPCHolder + && ((NPCHolder) getControllingPassenger()).getNPC().getNavigator().isNavigating()) { + setDeltaMovement(getControllingPassenger().getDeltaMovement().multiply(20, 1, 20)); + } npc.update(); + if (getHurtTime() > 0) { + setHurtTime(getHurtTime() - 1); + } + if (getDamage() > 0.0F) { + setDamage(getDamage() - 1.0F); + } this.aF = this.aE; aE = getStatus(); double d1 = isNoGravity() ? 0.0D : -0.04D; @@ -204,16 +213,13 @@ public class BoatController extends MobEntityController { } Vec3 vec3d = getDeltaMovement(); setDeltaMovement(vec3d.x * this.ap, vec3d.y + d1, vec3d.z * this.ap); - this.ar *= this.ap; if (d2 > 0.0D) { Vec3 vec3d1 = getDeltaMovement(); setDeltaMovement(vec3d1.x, vec3d1.y + d2 * 0.0615D, vec3d1.z); } } move(MoverType.SELF, getDeltaMovement()); - if (isVehicle()) { - setYRot((float) (getYRot() + this.ar)); - } + checkInsideBlocks(); } else { super.tick(); } diff --git a/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/entity/nonliving/BoatController.java b/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/entity/nonliving/BoatController.java index 7a9c49666..4ade1fd73 100644 --- a/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/entity/nonliving/BoatController.java +++ b/v1_21_R1/src/main/java/net/citizensnpcs/nms/v1_21_R1/entity/nonliving/BoatController.java @@ -4,6 +4,7 @@ import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_21_R1.CraftServer; import org.bukkit.craftbukkit.v1_21_R1.entity.CraftBoat; import org.bukkit.craftbukkit.v1_21_R1.entity.CraftEntity; +import org.bukkit.entity.Player; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_21_R1.entity.MobEntityController; @@ -15,7 +16,6 @@ import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.Util; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.FluidTags; import net.minecraft.tags.TagKey; import net.minecraft.util.Mth; @@ -48,14 +48,12 @@ public class BoatController extends MobEntityController { } public static class EntityBoatNPC extends Boat implements NPCHolder { - private double aC; - - private float aD; - private Status aE; - private Status aF; - private double ap; - private double ar; + private float invFriction; + private float landFriction; + private Status lastStatus; private final CitizensNPC npc; + private Status status; + private double waterLevel; public EntityBoatNPC(EntityType types, Level level) { this(types, level, null); @@ -73,6 +71,76 @@ public class BoatController extends MobEntityController { return NMSImpl.teleportAcrossWorld(this, transition); } + private boolean checkInWater() { + AABB axisalignedbb = this.getBoundingBox(); + int i = Mth.floor(axisalignedbb.minX); + int j = Mth.ceil(axisalignedbb.maxX); + int k = Mth.floor(axisalignedbb.minY); + int l = Mth.ceil(axisalignedbb.minY + 0.001); + int i1 = Mth.floor(axisalignedbb.minZ); + int j1 = Mth.ceil(axisalignedbb.maxZ); + boolean flag = false; + this.waterLevel = -1.7976931348623157E308; + BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); + + for (int k1 = i; k1 < j; ++k1) { + for (int l1 = k; l1 < l; ++l1) { + for (int i2 = i1; i2 < j1; ++i2) { + blockposition_mutableblockposition.set(k1, l1, i2); + FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); + if (fluid.is(FluidTags.WATER)) { + float f = l1 + fluid.getHeight(this.level(), blockposition_mutableblockposition); + this.waterLevel = Math.max(f, this.waterLevel); + flag |= axisalignedbb.minY < f; + } + } + } + } + return flag; + } + + private void floatBoat() { + double d0 = -this.getGravity(); + double d1 = 0.0; + this.invFriction = 0.05F; + if (this.lastStatus == net.minecraft.world.entity.vehicle.Boat.Status.IN_AIR + && this.status != net.minecraft.world.entity.vehicle.Boat.Status.IN_AIR + && this.status != net.minecraft.world.entity.vehicle.Boat.Status.ON_LAND) { + this.waterLevel = this.getY(1.0); + double d2 = this.getWaterLevelAbove() - this.getBbHeight() + 0.101; + if (this.level().noCollision(this, this.getBoundingBox().move(0.0, d2 - this.getY(), 0.0))) { + this.move(MoverType.SELF, new Vec3(0.0, d2 - this.getY(), 0.0)); + this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, 0.0, 1.0)); + } + this.status = net.minecraft.world.entity.vehicle.Boat.Status.IN_WATER; + } else { + if (this.status == net.minecraft.world.entity.vehicle.Boat.Status.IN_WATER) { + d1 = (this.waterLevel - this.getY()) / this.getBbHeight(); + this.invFriction = 0.9F; + } else if (this.status == net.minecraft.world.entity.vehicle.Boat.Status.UNDER_FLOWING_WATER) { + d0 = -7.0E-4; + this.invFriction = 0.9F; + } else if (this.status == net.minecraft.world.entity.vehicle.Boat.Status.UNDER_WATER) { + d1 = 0.009999999776482582; + this.invFriction = 0.45F; + } else if (this.status == net.minecraft.world.entity.vehicle.Boat.Status.IN_AIR) { + this.invFriction = 0.9F; + } else if (this.status == net.minecraft.world.entity.vehicle.Boat.Status.ON_LAND) { + this.invFriction = this.landFriction; + if (this.getControllingPassenger() instanceof Player) { + this.landFriction /= 2.0F; + } + } + Vec3 vec3d = this.getDeltaMovement(); + this.setDeltaMovement(vec3d.x * this.invFriction, vec3d.y + d0, vec3d.z * this.invFriction); + if (d1 > 0.0) { + Vec3 vec3d1 = this.getDeltaMovement(); + this.setDeltaMovement(vec3d1.x, (vec3d1.y + d1 * (this.getDefaultGravity() / 0.65)) * 0.75, + vec3d1.z); + } + } + } + @Override public CraftEntity getBukkitEntity() { if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) { @@ -92,16 +160,16 @@ public class BoatController extends MobEntityController { } private Status getStatus() { - Status entityboat_Status = u(); + Status entityboat_Status = isUnderwater(); if (entityboat_Status != null) { - this.aC = getBoundingBox().maxY; + this.waterLevel = getBoundingBox().maxY; return entityboat_Status; } - if (t()) + if (checkInWater()) return Status.IN_WATER; float f = getGroundFriction(); if (f > 0.0F) { - this.aD = f; + this.landFriction = f; return Status.ON_LAND; } return Status.IN_AIR; @@ -113,6 +181,36 @@ public class BoatController extends MobEntityController { : npc.data(). get(NPC.Metadata.COLLIDABLE, !npc.isProtected()); } + private Status isUnderwater() { + AABB axisalignedbb = this.getBoundingBox(); + double d0 = axisalignedbb.maxY + 0.001; + int i = Mth.floor(axisalignedbb.minX); + int j = Mth.ceil(axisalignedbb.maxX); + int k = Mth.floor(axisalignedbb.maxY); + int l = Mth.ceil(d0); + int i1 = Mth.floor(axisalignedbb.minZ); + int j1 = Mth.ceil(axisalignedbb.maxZ); + boolean flag = false; + BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); + + for (int k1 = i; k1 < j; ++k1) { + for (int l1 = k; l1 < l; ++l1) { + for (int i2 = i1; i2 < j1; ++i2) { + blockposition_mutableblockposition.set(k1, l1, i2); + FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); + if (fluid.is(FluidTags.WATER) && d0 < blockposition_mutableblockposition.getY() + + fluid.getHeight(this.level(), blockposition_mutableblockposition)) { + if (!fluid.isSource()) { + return net.minecraft.world.entity.vehicle.Boat.Status.UNDER_FLOWING_WATER; + } + flag = true; + } + } + } + } + return flag ? Status.UNDER_WATER : null; + } + @Override protected AABB makeBoundingBox() { return NMSBoundingBox.makeBB(npc, super.makeBoundingBox()); @@ -142,111 +240,31 @@ public class BoatController extends MobEntityController { return npc == null ? super.save(save) : false; } - private boolean t() { - boolean m = false; - AABB axisalignedbb = getBoundingBox(); - int i = Mth.floor(axisalignedbb.minX); - int j = Mth.ceil(axisalignedbb.maxX); - int k = Mth.floor(axisalignedbb.minY); - int l = Mth.ceil(axisalignedbb.minY + 0.001D); - int i1 = Mth.floor(axisalignedbb.minZ); - int j1 = Mth.ceil(axisalignedbb.maxZ); - boolean flag = false; - this.aC = Double.MIN_VALUE; - BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); - for (int k1 = i; k1 < j; k1++) { - for (int l1 = k; l1 < l; l1++) { - for (int i2 = i1; i2 < j1; i2++) { - blockposition_mutableblockposition.set(k1, l1, i2); - FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); - if (fluid.is(FluidTags.WATER)) { - float f = l1 + fluid.getHeight(this.level(), blockposition_mutableblockposition); - this.aC = Math.max(f, this.aC); - m = flag | (axisalignedbb.minY < f ? true : false); - } - } - } - } - return m; - } - @Override public void tick() { if (npc != null) { + baseTick(); + if (getControllingPassenger() instanceof NPCHolder + && ((NPCHolder) getControllingPassenger()).getNPC().getNavigator().isNavigating()) { + setDeltaMovement(getControllingPassenger().getDeltaMovement().multiply(20, 1, 20)); + } npc.update(); - this.aF = this.aE; - aE = getStatus(); - double d1 = isNoGravity() ? 0.0D : -0.04D; - double d2 = 0.0D; - this.ap = 0.05F; - if (this.aF == Status.IN_AIR && this.aE != Status.IN_AIR && this.aE != Status.ON_LAND) { - this.aC = getY(1.0D); - setPos(getX(), getWaterLevelAbove() - getBbHeight() + 0.101D, getZ()); - setDeltaMovement(getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); - this.aE = Status.IN_WATER; - } else { - if (this.aE == Status.IN_WATER) { - d2 = (this.aC - getY()) / getBbHeight(); - this.ap = 0.9F; - } else if (this.aE == Status.UNDER_FLOWING_WATER) { - d1 = -7.0E-4D; - this.ap = 0.9F; - } else if (this.aE == Status.UNDER_WATER) { - d2 = 0.01D; - this.ap = 0.45F; - } else if (this.aE == Status.IN_AIR) { - this.ap = 0.9F; - } else if (this.aE == Status.ON_LAND) { - this.ap = this.aD; - if (getControllingPassenger() instanceof ServerPlayer) { - this.aD /= 2.0F; - } - } - Vec3 vec3d = getDeltaMovement(); - setDeltaMovement(vec3d.x * this.ap, vec3d.y + d1, vec3d.z * this.ap); - this.ar *= this.ap; - if (d2 > 0.0D) { - Vec3 vec3d1 = getDeltaMovement(); - setDeltaMovement(vec3d1.x, vec3d1.y + d2 * 0.0615D, vec3d1.z); - } + if (getHurtTime() > 0) { + setHurtTime(getHurtTime() - 1); } + if (getDamage() > 0.0F) { + setDamage(getDamage() - 1.0F); + } + lastStatus = status; + status = getStatus(); + floatBoat(); move(MoverType.SELF, getDeltaMovement()); - if (isVehicle()) { - setYRot((float) (getYRot() + this.ar)); - } + checkInsideBlocks(); } else { super.tick(); } } - private Status u() { - AABB axisalignedbb = getBoundingBox(); - double d0 = axisalignedbb.maxY + 0.001D; - int i = Mth.floor(axisalignedbb.minX); - int j = Mth.ceil(axisalignedbb.maxX); - int k = Mth.floor(axisalignedbb.maxY); - int l = Mth.ceil(d0); - int i1 = Mth.floor(axisalignedbb.minZ); - int j1 = Mth.ceil(axisalignedbb.maxZ); - boolean flag = false; - BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); - for (int k1 = i; k1 < j; k1++) { - for (int l1 = k; l1 < l; l1++) { - for (int i2 = i1; i2 < j1; i2++) { - blockposition_mutableblockposition.set(k1, l1, i2); - FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); - if (fluid.is(FluidTags.WATER) && d0 < blockposition_mutableblockposition.getY() - + fluid.getHeight(this.level(), blockposition_mutableblockposition)) { - if (!fluid.isSource()) - return Status.UNDER_FLOWING_WATER; - flag = true; - } - } - } - } - return flag ? Status.UNDER_WATER : null; - } - @Override public boolean updateFluidHeightAndDoFluidPushing(TagKey tagkey, double d0) { if (npc == null)