diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java index 58a2fe008..81d0ef287 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java @@ -198,7 +198,7 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity releaseDecoy(); lowHealthWarning(); - this.terrainCompat(2.7f, 2.7f); + this.terrainCompact(2.7f, 2.7f); this.refreshDimensions(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java index 0e415fc78..42162d55e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java @@ -54,6 +54,7 @@ import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; +import org.joml.Math; import org.joml.Matrix4f; import org.joml.Vector4f; import software.bernie.geckolib.animatable.GeoEntity; @@ -62,7 +63,10 @@ import software.bernie.geckolib.animation.*; import software.bernie.geckolib.util.GeckoLibUtil; import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.List; import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle; @@ -232,7 +236,7 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit } turretAngle(25, 25); - this.terrainCompat(4f, 5f); + this.terrainCompact(4f, 5f); inertiaRotate(1); releaseSmokeDecoy(); @@ -241,6 +245,42 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit this.refreshDimensions(); } + @Override + public void terrainCompact(float w, float l) { + if (onGround()) { + float x1 = terrainCompactTrackValue(w, l)[0]; + float x2 = terrainCompactTrackValue(w, l - 1)[0]; + float x3 = terrainCompactTrackValue(w, l - 2)[0]; + float x4 = terrainCompactTrackValue(w, l - 3)[0]; + float x5 = terrainCompactTrackValue(w, l - 4)[0]; + float x6 = terrainCompactTrackValue(w, l - 5)[0]; + + List numbersX = Arrays.asList(x1, x2, x3, x4, x5, x6); + float maxX = Collections.max(numbersX); + float minX = Collections.min(numbersX); + + float z1 = terrainCompactTrackValue(w, l)[1]; + float z2 = terrainCompactTrackValue(w, l - 1)[1]; + float z3 = terrainCompactTrackValue(w, l - 2)[1]; + float z4 = terrainCompactTrackValue(w, l - 3)[1]; + float z5 = terrainCompactTrackValue(w, l - 4)[1]; + float z6 = terrainCompactTrackValue(w, l - 5)[1]; + + List numbersZ = Arrays.asList(z1, z2, z3, z4, z5, z6); + float maxZ = Collections.max(numbersZ); + float minZ = Collections.min(numbersZ); + + float diffX = Math.clamp(-15f, 15f, (minX + maxX) / 2); + setXRot(Mth.clamp(getXRot() + 0.15f * diffX, -45f, 45f)); + + float diffZ = Math.clamp(-15f, 15f, minZ + maxZ); + setZRot(Mth.clamp(getRoll() + 0.15f * diffZ, -45f, 45f)); + } else if (isInWater()) { + setXRot(getXRot() * 0.9f); + setZRot(getRoll() * 0.9f); + } + } + @Override public boolean canCollideHardBlock() { return getDeltaMovement().horizontalDistance() > 0.07 || Mth.abs(this.entityData.get(POWER)) > 0.12; @@ -452,8 +492,8 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit setLeftTrack((float) ((getLeftTrack() - 1.9 * Math.PI * s0) + Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f))); setRightTrack((float) ((getRightTrack() - 1.9 * Math.PI * s0) - Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f))); + this.setYRot((float) (this.getYRot() - (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT))); if (this.isInWater() || onGround()) { - this.setYRot((float) (this.getYRot() - (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT))); this.setDeltaMovement(this.getDeltaMovement().add(getViewVector(1).scale((!isInWater() && !onGround() ? 0.13f : (isInWater() && !onGround() ? 2 : 2.4f)) * this.entityData.get(POWER)))); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java index e745bda31..ffb2c278f 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java @@ -188,7 +188,7 @@ public class Lav150Entity extends ContainerMobileVehicleEntity implements GeoEnt turretAngle(15, 12.5f); lowHealthWarning(); - this.terrainCompat(2.7f, 3.61f); + this.terrainCompact(2.7f, 3.61f); inertiaRotate(1.25f); releaseSmokeDecoy(); @@ -376,8 +376,8 @@ public class Lav150Entity extends ContainerMobileVehicleEntity implements GeoEnt this.setRudderRot(Mth.clamp(this.getRudderRot() - this.entityData.get(DELTA_ROT), -0.8f, 0.8f) * 0.75f); + this.setYRot((float) (this.getYRot() - Math.max((isInWater() && !onGround() ? 5 : 10) * this.getDeltaMovement().horizontalDistance(), 0) * this.getRudderRot() * (this.entityData.get(POWER) > 0 ? 1 : -1))); if (this.isInWater() || onGround()) { - this.setYRot((float) (this.getYRot() - Math.max((isInWater() && !onGround() ? 5 : 10) * this.getDeltaMovement().horizontalDistance(), 0) * this.getRudderRot() * (this.entityData.get(POWER) > 0 ? 1 : -1))); this.setDeltaMovement(this.getDeltaMovement().add(getViewVector(1).scale((!isInWater() && !onGround() ? 0.05f : (isInWater() && !onGround() ? 0.3f : 1)) * this.entityData.get(POWER)))); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/PrismTankEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/PrismTankEntity.java index 168407890..f38aca017 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/PrismTankEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/PrismTankEntity.java @@ -63,6 +63,8 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.AnimatableManager; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.stream.StreamSupport; @@ -216,7 +218,7 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo } turretAngle(15, 10); - this.terrainCompat(4.6375f, 5.171875f); + this.terrainCompact(4.6375f, 5.171875f); inertiaRotate(1); releaseSmokeDecoy(); @@ -225,6 +227,42 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo this.refreshDimensions(); } + @Override + public void terrainCompact(float w, float l) { + if (onGround()) { + float x1 = terrainCompactTrackValue(w, l)[0]; + float x2 = terrainCompactTrackValue(w, l - 1)[0]; + float x3 = terrainCompactTrackValue(w, l - 2)[0]; + float x4 = terrainCompactTrackValue(w, l - 3)[0]; + float x5 = terrainCompactTrackValue(w, l - 4)[0]; + float x6 = terrainCompactTrackValue(w, l - 5)[0]; + + List numbersX = Arrays.asList(x1, x2, x3, x4, x5, x6); + float maxX = Collections.max(numbersX); + float minX = Collections.min(numbersX); + + float z1 = terrainCompactTrackValue(w, l)[1]; + float z2 = terrainCompactTrackValue(w, l - 1)[1]; + float z3 = terrainCompactTrackValue(w, l - 2)[1]; + float z4 = terrainCompactTrackValue(w, l - 3)[1]; + float z5 = terrainCompactTrackValue(w, l - 4)[1]; + float z6 = terrainCompactTrackValue(w, l - 5)[1]; + + List numbersZ = Arrays.asList(z1, z2, z3, z4, z5, z6); + float maxZ = Collections.max(numbersZ); + float minZ = Collections.min(numbersZ); + + float diffX = Math.clamp(-15f, 15f, (minX + maxX) / 2); + setXRot(Mth.clamp(getXRot() + 0.15f * diffX, -45f, 45f)); + + float diffZ = Math.clamp(-15f, 15f, minZ + maxZ); + setZRot(Mth.clamp(getRoll() + 0.15f * diffZ, -45f, 45f)); + } else if (isInWater()) { + setXRot(getXRot() * 0.9f); + setZRot(getRoll() * 0.9f); + } + } + @Override public boolean canCollideHardBlock() { return getDeltaMovement().horizontalDistance() > 0.07 || Mth.abs(this.entityData.get(POWER)) > 0.12; @@ -499,8 +537,8 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo setLeftTrack((float) ((getLeftTrack() - 1.9 * Math.PI * s0) + Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f))); setRightTrack((float) ((getRightTrack() - 1.9 * Math.PI * s0) - Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f))); + this.setYRot((float) (this.getYRot() - (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT))); if (this.isInWater() || onGround()) { - this.setYRot((float) (this.getYRot() - (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT))); this.setDeltaMovement(this.getDeltaMovement().add(getViewVector(1).scale((!isInWater() && !onGround() ? 0.13f : (isInWater() && !onGround() ? 2 : 2.4f)) * this.entityData.get(POWER)))); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java index acb4172ba..c9a17b9c2 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java @@ -164,7 +164,7 @@ public class SpeedboatEntity extends ContainerMobileVehicleEntity implements Geo turretAngle(40, 40); lowHealthWarning(); inertiaRotate(2); - this.terrainCompat(2f, 3f); + this.terrainCompact(2f, 3f); this.refreshDimensions(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java index d2bee1d09..5ee4f6008 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java @@ -129,7 +129,7 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity { } } - this.terrainCompat(1f, 1.2f); + this.terrainCompact(1f, 1.2f); this.setDeltaMovement(this.getDeltaMovement().add(0.0, 0.01, 0.0)); this.refreshDimensions(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java index c633a26dd..94c15da60 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java @@ -85,7 +85,7 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity { } @Override - protected void playStepSound(BlockPos pPos, BlockState pState) { + protected void playStepSound(@NotNull BlockPos pPos, @NotNull BlockState pState) { this.playSound(ModSounds.WHEEL_STEP.get(), (float) (getDeltaMovement().length() * 0.5), random.nextFloat() * 0.15f + 1); } @@ -113,7 +113,7 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity { } this.setSprinting(this.getDeltaMovement().horizontalDistance() > 0.15); attractEntity(); - this.terrainCompat(0.9f, 1.2f); + this.terrainCompact(0.9f, 1.2f); inertiaRotate(10f); this.refreshDimensions(); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java index c1dfd0705..a2a81b2d3 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java @@ -66,7 +66,10 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.*; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.List; import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit; import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle; @@ -329,7 +332,9 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti turretAngle(5, 5); gunnerAngle(15, 15); lowHealthWarning(); - this.terrainCompat(4.375f, 6.3125f); + + terrainCompact(4.375f, 6.3125f); + inertiaRotate(1.2f); releaseSmokeDecoy(); @@ -337,6 +342,44 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti this.refreshDimensions(); } + @Override + public void terrainCompact(float w, float l) { + if (onGround()) { + float x1 = terrainCompactTrackValue(w, l)[0]; + float x2 = terrainCompactTrackValue(w, l - 1)[0]; + float x3 = terrainCompactTrackValue(w, l - 2)[0]; + float x4 = terrainCompactTrackValue(w, l - 3)[0]; + float x5 = terrainCompactTrackValue(w, l - 4)[0]; + float x6 = terrainCompactTrackValue(w, l - 5)[0]; + float x7 = terrainCompactTrackValue(w, l - 6)[0]; + + List numbersX = Arrays.asList(x1, x2, x3, x4, x5, x6, x7); + float maxX = Collections.max(numbersX); + float minX = Collections.min(numbersX); + + float z1 = terrainCompactTrackValue(w, l)[1]; + float z2 = terrainCompactTrackValue(w, l - 1)[1]; + float z3 = terrainCompactTrackValue(w, l - 2)[1]; + float z4 = terrainCompactTrackValue(w, l - 3)[1]; + float z5 = terrainCompactTrackValue(w, l - 4)[1]; + float z6 = terrainCompactTrackValue(w, l - 5)[1]; + float z7 = terrainCompactTrackValue(w, l - 6)[1]; + + List numbersZ = Arrays.asList(z1, z2, z3, z4, z5, z6, z7); + float maxZ = Collections.max(numbersZ); + float minZ = Collections.min(numbersZ); + + float diffX = Math.clamp(-15f, 15f, (minX + maxX) / 2); + setXRot(Mth.clamp(getXRot() + 0.15f * diffX, -45f, 45f)); + + float diffZ = Math.clamp(-15f, 15f, minZ + maxZ); + setZRot(Mth.clamp(getRoll() + 0.15f * diffZ, -45f, 45f)); + } else if (isInWater()) { + setXRot(getXRot() * 0.9f); + setZRot(getRoll() * 0.9f); + } + } + @Override public boolean canCollideHardBlock() { return getDeltaMovement().horizontalDistance() > 0.05 || Mth.abs(this.entityData.get(POWER)) > 0.1; @@ -728,8 +771,8 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti setLeftTrack((float) ((getLeftTrack() - 1.5 * Math.PI * s0) + Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f))); setRightTrack((float) ((getRightTrack() - 1.5 * Math.PI * s0) - Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f))); + this.setYRot((float) (this.getYRot() - (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT))); if (this.isInWater() || onGround()) { - this.setYRot((float) (this.getYRot() - (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT))); this.setDeltaMovement(this.getDeltaMovement().add(getViewVector(1).scale((!isInWater() && !onGround() ? 0.13f : (isInWater() && !onGround() ? 2 : 2.4f)) * this.entityData.get(POWER)))); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/MobileVehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/MobileVehicleEntity.java index 7c7c49f96..4ad85092c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/MobileVehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/MobileVehicleEntity.java @@ -328,7 +328,7 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements } // 地形适应测试 - public void terrainCompat(float w, float l) { + public void terrainCompact(float w, float l) { if (onGround()) { Matrix4f transform = this.getWheelsTransform(1); @@ -402,6 +402,53 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements } } + //用于履带的地形适应 + + public float[] terrainCompactTrackValue(float w, float l) { + Matrix4f transform = this.getWheelsTransform(1); + + // 左前 + Vector4f positionLF = transformPosition(transform, w / 2, 0, l / 2); + // 右前 + Vector4f positionRF = transformPosition(transform, -w / 2, 0, l / 2); + // 左后 + Vector4f positionLB = transformPosition(transform, w / 2, 0, -l / 2); + // 右后 + Vector4f positionRB = transformPosition(transform, -w / 2, 0, -l / 2); + + Vec3 p1 = new Vec3(positionLF.x, positionLF.y, positionLF.z); + Vec3 p2 = new Vec3(positionRF.x, positionRF.y, positionRF.z); + Vec3 p3 = new Vec3(positionLB.x, positionLB.y, positionLB.z); + Vec3 p4 = new Vec3(positionRB.x, positionRB.y, positionRB.z); + + // 确定点位是否在墙里来调整点位高度 + float p1y = (float) this.traceBlockY(p1, 3); + float p2y = (float) this.traceBlockY(p2, 3); + float p3y = (float) this.traceBlockY(p3, 3); + float p4y = (float) this.traceBlockY(p4, 3); + + p1 = new Vec3(positionLF.x, p1y, positionLF.z); + p2 = new Vec3(positionRF.x, p2y, positionRF.z); + p3 = new Vec3(positionLB.x, p3y, positionLB.z); + p4 = new Vec3(positionRB.x, p4y, positionRB.z); + + Vec3 v0 = p3.vectorTo(p1); + Vec3 v1 = p4.vectorTo(p2); + Vec3 v2 = p1.vectorTo(p2); + Vec3 v3 = p3.vectorTo(p4); + + double x1 = getXRotFromVector(v0); + double x2 = getXRotFromVector(v1); + + double z1 = getXRotFromVector(v2); + double z2 = getXRotFromVector(v3); + + float x = Math.clamp(-15f, 15f, Mth.wrapDegrees((float) (-(x1 + x2)) - getXRot())); + float z = Math.clamp(-15f, 15f, Mth.wrapDegrees((float) (-(z1 + z2)) - getRoll())); + + return new float[]{x, z}; + } + public Matrix4f getWheelsTransform(float ticks) { Matrix4f transform = new Matrix4f(); transform.translate((float) Mth.lerp(ticks, xo, getX()), (float) Mth.lerp(ticks, yo, getY()), (float) Mth.lerp(ticks, zo, getZ()));