优化履带车辆地形适应

This commit is contained in:
Atsuishio 2025-04-22 13:03:28 +08:00 committed by Light_Quanta
parent c218ae5157
commit 2551f6ffca
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
9 changed files with 182 additions and 14 deletions

View file

@ -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();
}

View file

@ -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<Float> 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<Float> 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))));
}
}

View file

@ -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))));
}
}

View file

@ -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<Float> 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<Float> 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))));
}
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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();

View file

@ -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<Float> 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<Float> 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))));
}
}

View file

@ -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()));