diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/EntityMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/EntityMixin.java index bc2ce449a..cd6e292c1 100644 --- a/src/main/java/com/atsuishio/superbwarfare/mixins/EntityMixin.java +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/EntityMixin.java @@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.entity.OBBEntity; import com.atsuishio.superbwarfare.entity.mixin.OBBHitter; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.tools.OBB; +import net.minecraft.network.chat.Component; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; @@ -34,12 +35,6 @@ public abstract class EntityMixin implements OBBHitter { @Shadow public abstract AABB getBoundingBox(); - @Shadow - public abstract Vec3 position(); - - @Shadow - public abstract Vec3 getEyePosition(); - @Inject(method = "collide", at = @At("HEAD")) private void sbw$spoofGroundStart(Vec3 movement, CallbackInfoReturnable cir) { if (MobileVehicleEntity.IGNORE_ENTITY_GROUND_CHECK_STEPPING) { @@ -74,19 +69,23 @@ public abstract class EntityMixin implements OBBHitter { private void onHitOBB(Vec3 movement, CallbackInfoReturnable cir) { AABB boundingBox = this.getBoundingBox(); Entity self = (Entity) (Object) this; - if (self instanceof Player player) { - boundingBox = player.getLocalBoundsForPose(player.getPose()); - } - var list = this.level().getEntities(self, boundingBox.expandTowards(movement)); - var entity = list.stream().filter(e -> e instanceof OBBEntity).findFirst().orElse(null); + var list = this.level().getEntities(self, boundingBox.expandTowards(movement).inflate(1), e -> true); + var entity = list.stream().filter(e -> e instanceof OBBEntity).min((e1, e2) -> (int) (e1.position().distanceTo(self.position()) - e2.position().distanceTo(self.position()))).orElse(null); if (entity == null || entity == self) return; + OBBEntity obbEntity = (OBBEntity) entity; - Vec3 feetPos = this.position().subtract(this.getEyePosition()); + Vec3 position = self.position(); // 第一版实现 - var faceInfo = OBB.findClosestFace(obbEntity.getOBBs(), feetPos); + var faceInfo = OBB.findClosestFace(obbEntity.getOBBs(), position); if (faceInfo == null) return; double dot = movement.dot(new Vec3(faceInfo.faceNormal())); var vec = new Vec3(faceInfo.faceNormal()).multiply(dot, dot, dot); + + if (self instanceof Player player) { + player.displayClientMessage(Component.literal("Vec: [" + vec.x + ", " + vec.y + ", " + vec.z + "]," + + " Face: [" + faceInfo.faceNormal().x + ", " + faceInfo.faceNormal().y + ", " + faceInfo.faceNormal().z + "]"), true); + } + cir.setReturnValue(movement.subtract(vec)); } diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/LevelMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/LevelMixin.java index 64aa751f7..78747b788 100644 --- a/src/main/java/com/atsuishio/superbwarfare/mixins/LevelMixin.java +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/LevelMixin.java @@ -29,11 +29,13 @@ public abstract class LevelMixin { // TODO 研究OBB碰撞的时候把这个删了 if (!(pEntity instanceof Projectile)) return; - StreamSupport.stream(this.getEntities().getAll().spliterator(), false).filter(e -> e instanceof OBBEntity && pPredicate.test(e)) + StreamSupport.stream(this.getEntities().getAll().spliterator(), false).filter(e -> pPredicate.test(e) && e != pEntity) .forEach(entity -> { - for (OBB obb : ((OBBEntity) entity).getOBBs()) { - if (OBB.isColliding(obb, pBoundingBox) && !cir.getReturnValue().contains(entity)) { - cir.getReturnValue().add(entity); + if (entity instanceof OBBEntity obbEntity) { + for (OBB obb : obbEntity.getOBBs()) { + if (OBB.isColliding(obb, pBoundingBox) && !cir.getReturnValue().contains(entity)) { + cir.getReturnValue().add(entity); + } } } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/OBB.java b/src/main/java/com/atsuishio/superbwarfare/tools/OBB.java index a3bf6362a..b8c716478 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/OBB.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/OBB.java @@ -397,7 +397,7 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part return null; } - Vector3f pos = new Vector3f((float) playerPos.x, (float) playerPos.y, (float) playerPos.z); + Vector3f pos = playerPos.toVector3f(); OBB closestOBB = null; int closestFaceIndex = -1; float minDistance = Float.MAX_VALUE; @@ -410,7 +410,7 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part float distToCenter = pos.distance(obb.center()); // 如果距离大于包围球半径,不可能比当前最小值更近 - if (distToCenter - obb.getBoundingSphereRadius() > minDistance) { + if (distToCenter > obb.getBoundingSphereRadius()) { continue; }