添加炮塔受损

This commit is contained in:
Atsuishio 2025-06-21 14:06:23 +08:00 committed by Light_Quanta
parent bd8327336b
commit fae9ddcb1c
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
17 changed files with 115 additions and 27 deletions

View file

@ -48,6 +48,7 @@ import java.util.concurrent.atomic.AtomicReference;
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
import static com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay.*;
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.DECOY_COUNT;
import static com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity.TURRET_DAMAGED_TIME;
@OnlyIn(Dist.CLIENT)
public class VehicleHudOverlay implements LayeredDraw.Layer {
@ -187,7 +188,6 @@ public class VehicleHudOverlay implements LayeredDraw.Layer {
int addH = (w / h) * 27;
preciseBlit(guiGraphics, FRAME, (float) -addW / 2, (float) -addH / 2, 10, 0, 0.0F, w + addW, h + addH, w + addW, h + addH);
preciseBlit(guiGraphics, Mod.loc("textures/screens/land/line.png"), w / 2f - 64, h - 56, 0, 0.0F, 128, 1, 128, 1);
preciseBlit(guiGraphics, Mod.loc("textures/screens/land/line.png"), w / 2f + 112, h - 71, 0, 0.0F, 1, 16, 1, 16);
// 指南针
preciseBlit(guiGraphics, Mod.loc("textures/screens/compass.png"), (float) w / 2 - 128, (float) 10, 128 + ((float) 64 / 45 * player.getYRot()), 0, 256, 16, 512, 16);
@ -195,10 +195,45 @@ public class VehicleHudOverlay implements LayeredDraw.Layer {
// 炮塔方向
poseStack.pushPose();
//车身
ResourceLocation body;
if (mobileVehicle.getHealth() > 0.4 * mobileVehicle.getMaxHealth()) {
body = Mod.loc("textures/screens/land/body.png");
} else if (mobileVehicle.getHealth() > 0.1 * mobileVehicle.getMaxHealth()) {
body = Mod.loc("textures/screens/land/body_warning.png");
} else {
body = Mod.loc("textures/screens/land/body_damaged.png");
}
//左轮
ResourceLocation left_wheel;
left_wheel = Mod.loc("textures/screens/land/left_wheel.png");
//右轮
ResourceLocation right_wheel;
right_wheel = Mod.loc("textures/screens/land/right_wheel.png");
//引擎
ResourceLocation engine;
engine = Mod.loc("textures/screens/land/engine.png");
poseStack.rotateAround(Axis.ZP.rotationDegrees(Mth.lerp(partialTick, iLand.turretYRotO(), iLand.turretYRot())), w / 2f + 112, h - 56, 0);
preciseBlit(guiGraphics, Mod.loc("textures/screens/land/body.png"), w / 2f + 96, h - 72, 0, 0.0F, 32, 32, 32, 32);
preciseBlit(guiGraphics, body, w / 2f + 96, h - 72, 0, 0.0F, 32, 32, 32, 32);
preciseBlit(guiGraphics, left_wheel, w / 2f + 96, h - 72, 0, 0.0F, 32, 32, 32, 32);
preciseBlit(guiGraphics, right_wheel, w / 2f + 96, h - 72, 0, 0.0F, 32, 32, 32, 32);
preciseBlit(guiGraphics, engine, w / 2f + 96, h - 72, 0, 0.0F, 32, 32, 32, 32);
poseStack.popPose();
// 炮塔损伤
ResourceLocation barrel;
if (mobileVehicle.getEntityData().get(TURRET_DAMAGED_TIME) > 0) {
barrel = Mod.loc("textures/screens/land/line_damaged.png");
} else {
barrel = Mod.loc("textures/screens/land/line.png");
}
preciseBlit(guiGraphics, barrel, w / 2f + 112, h - 71, 0, 0.0F, 1, 16, 1, 16);
// 时速
guiGraphics.drawString(mc.font, Component.literal(FormatTool.format0D(mobileVehicle.getDeltaMovement().dot(mobileVehicle.getViewVector(partialTick)) * 72, " km/h")),
w / 2 + 160, h / 2 - 48, 0x66FF00, false);

View file

@ -16,7 +16,6 @@ import com.atsuishio.superbwarfare.entity.vehicle.weapon.WgMissileWeapon;
import com.atsuishio.superbwarfare.event.ClientMouseHandler;
import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModParticleTypes;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
import com.atsuishio.superbwarfare.tools.*;
@ -33,7 +32,6 @@ import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@ -70,7 +68,6 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
public static final EntityDataAccessor<Integer> LOADED_MISSILE = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> MISSILE_COUNT = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Boolean> TURRET_DAMAGED = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.BOOLEAN);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public int reloadCoolDown;
@ -135,8 +132,7 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
super.defineSynchedData(builder);
builder.define(CANNON_FIRE_TIME, 0)
.define(LOADED_MISSILE, 0)
.define(MISSILE_COUNT, 0)
.define(TURRET_DAMAGED, false);
.define(MISSILE_COUNT, 0);
}
@Override
@ -217,22 +213,7 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
sendParticle(serverLevel, ParticleTypes.BUBBLE_COLUMN_UP, this.getX() + 0.5 * this.getDeltaMovement().x, this.getY() + getSubmergedHeight(this) - 0.2, this.getZ() + 0.5 * this.getDeltaMovement().z, (int) (2 + 10 * this.getDeltaMovement().length()), 0.65, 0, 0.65, 0, true);
}
if (entityData.get(TURRET_DAMAGED)) {
List<Entity> entities = getPlayer(level());
for (var e : entities) {
if (e instanceof ServerPlayer player) {
if (player.level() instanceof ServerLevel serverLevel) {
Matrix4f transformT = getTurretTransform(1);
Vector4f worldPositionT = transformPosition(transformT, 0, 0.56875f, 0f);
sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), worldPositionT.x, worldPositionT.y, worldPositionT.z, 5, 0.25, 0.25, 0.25, 0.2, true);
}
}
}
turretAngle(1, 1.25f);
} else {
turretAngle(10, 12.5f);
}
turretAngle(10, 12.5f);
this.terrainCompact(4f, 5f);
inertiaRotate(1);
@ -575,6 +556,7 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
return new Vec3(rootPosition.x, rootPosition.y, rootPosition.z).vectorTo(new Vec3(targetPosition.x, targetPosition.y, targetPosition.z));
}
@Override
public Matrix4f getTurretTransform(float ticks) {
Matrix4f transformV = getVehicleTransform(ticks);

View file

@ -76,7 +76,7 @@ public class Lav150Entity extends ContainerMobileVehicleEntity implements GeoEnt
this.obb5 = new OBB(this.position().toVector3f(), new Vector3f(1.3125f, 0.90625f, 2.4375f), new Quaternionf(), OBB.Part.BODY);
this.obb6 = new OBB(this.position().toVector3f(), new Vector3f(1.3125f, 0.53125f, 0.34375f), new Quaternionf(), OBB.Part.BODY);
this.obb7 = new OBB(this.position().toVector3f(), new Vector3f(1.3125f, 0.625f, 0.53125f), new Quaternionf(), OBB.Part.BODY);
this.obbTurret = new OBB(this.position().toVector3f(), new Vector3f(0.875f, 0.3625f, 1.25f), new Quaternionf(), OBB.Part.BODY);
this.obbTurret = new OBB(this.position().toVector3f(), new Vector3f(0.875f, 0.3625f, 1.25f), new Quaternionf(), OBB.Part.TURRET);
}
@Override
@ -424,6 +424,7 @@ public class Lav150Entity extends ContainerMobileVehicleEntity implements GeoEnt
return new Vec3(rootPosition.x, rootPosition.y, rootPosition.z).vectorTo(new Vec3(targetPosition.x, targetPosition.y, targetPosition.z));
}
@Override
public Matrix4f getTurretTransform(float ticks) {
Matrix4f transformV = getVehicleTransform(ticks);

View file

@ -94,7 +94,7 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo
this.obb3 = new OBB(this.position().toVector3f(), new Vector3f(0.46875f, 0.78125f, 3.3125f), new Quaternionf(), OBB.Part.BODY);
this.obb4 = new OBB(this.position().toVector3f(), new Vector3f(0.46875f, 0.78125f, 3.3125f), new Quaternionf(), OBB.Part.BODY);
this.obb5 = new OBB(this.position().toVector3f(), new Vector3f(1.375f, 0.28125f, 1.375f), new Quaternionf(), OBB.Part.BODY);
this.obbTurret = new OBB(this.position().toVector3f(), new Vector3f(0.4375f, 0.90625f, 1.21875f), new Quaternionf(), OBB.Part.BODY);
this.obbTurret = new OBB(this.position().toVector3f(), new Vector3f(0.4375f, 0.90625f, 1.21875f), new Quaternionf(), OBB.Part.TURRET);
}
@Override
@ -622,6 +622,7 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo
return new Vec3(rootPosition.x, rootPosition.y, rootPosition.z).vectorTo(new Vec3(targetPosition.x, targetPosition.y, targetPosition.z));
}
@Override
public Matrix4f getTurretTransform(float ticks) {
Matrix4f transformV = getVehicleTransform(ticks);

View file

@ -421,6 +421,7 @@ public class SpeedboatEntity extends ContainerMobileVehicleEntity implements Geo
return transformT;
}
@Override
public Matrix4f getTurretTransform(float ticks) {
Matrix4f transformV = getVehicleTransform(ticks);

View file

@ -98,8 +98,8 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
this.obb2 = new OBB(this.position().toVector3f(), new Vector3f(2.375f, 0.59375f, 0.65625f), new Quaternionf(), OBB.Part.BODY);
this.obb3 = new OBB(this.position().toVector3f(), new Vector3f(0.625f, 0.84375f, 3.875f), new Quaternionf(), OBB.Part.BODY);
this.obb4 = new OBB(this.position().toVector3f(), new Vector3f(0.625f, 0.84375f, 3.875f), new Quaternionf(), OBB.Part.BODY);
this.obbTurret = new OBB(this.position().toVector3f(), new Vector3f(2.375f, 0.5625f, 2.1875f), new Quaternionf(), OBB.Part.BODY);
this.obbTurret2 = new OBB(this.position().toVector3f(), new Vector3f(1.625f, 0.40625f, 0.59375f), new Quaternionf(), OBB.Part.BODY);
this.obbTurret = new OBB(this.position().toVector3f(), new Vector3f(2.375f, 0.5625f, 2.1875f), new Quaternionf(), OBB.Part.TURRET);
this.obbTurret2 = new OBB(this.position().toVector3f(), new Vector3f(1.625f, 0.40625f, 0.59375f), new Quaternionf(), OBB.Part.TURRET);
}
@Override
@ -833,6 +833,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
return transformT;
}
@Override
public Matrix4f getTurretTransform(float ticks) {
Matrix4f transformV = getVehicleTransform(ticks);
@ -1284,6 +1285,16 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
return Mod.loc("textures/gui/vehicle/type/land.png");
}
@Override
public float turretDamagedMin() {
return 75;
}
@Override
public float turretDamagedMultiply() {
return 2;
}
@Override
public List<OBB> getOBBs() {
return List.of(this.obb, this.obb2, this.obb3, this.obb4, this.obbTurret, this.obbTurret2);

View file

@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.entity.vehicle.base;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.data.vehicle.VehicleData;
import com.atsuishio.superbwarfare.entity.OBBEntity;
import com.atsuishio.superbwarfare.entity.mixin.OBBHitter;
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
@ -10,6 +11,7 @@ import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.item.ContainerBlockItem;
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.OBB;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.VectorTool;
import com.google.common.collect.ImmutableList;
@ -74,6 +76,8 @@ import java.util.Objects;
import java.util.function.Function;
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.getPlayer;
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
public abstract class VehicleEntity extends Entity {
@ -85,6 +89,9 @@ public abstract class VehicleEntity extends Entity {
public static final EntityDataAccessor<Float> MOUSE_SPEED_Y = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<List<Integer>> SELECTED_WEAPON = SynchedEntityData.defineId(VehicleEntity.class, ModSerializers.INT_LIST_SERIALIZER.get());
public static final EntityDataAccessor<Integer> HEAT = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> TURRET_DAMAGED_TIME = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> L_WHEEL_DAMAGED_TIME = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> R_WHEEL_DAMAGED_TIME = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.INT);
public VehicleWeapon[][] availableWeapons;
@ -296,6 +303,9 @@ public abstract class VehicleEntity extends Entity {
.define(MOUSE_SPEED_X, 0f)
.define(MOUSE_SPEED_Y, 0f)
.define(HEAT, 0)
.define(TURRET_DAMAGED_TIME, 0)
.define(L_WHEEL_DAMAGED_TIME, 0)
.define(R_WHEEL_DAMAGED_TIME, 0)
.define(SELECTED_WEAPON, IntList.of(new int[this.getMaxPassengers()]));
// 怎么还不给玩动态注册了
}
@ -317,6 +327,9 @@ public abstract class VehicleEntity extends Entity {
this.entityData.set(LAST_ATTACKER_UUID, compound.getString("LastAttacker"));
this.entityData.set(LAST_DRIVER_UUID, compound.getString("LastDriver"));
this.entityData.set(HEALTH, compound.getFloat("Health"));
this.entityData.set(TURRET_DAMAGED_TIME, compound.getInt("TurretDamagedTime"));
this.entityData.set(L_WHEEL_DAMAGED_TIME, compound.getInt("LWheelDamagedTime"));
this.entityData.set(R_WHEEL_DAMAGED_TIME, compound.getInt("RWheelDamagedTime"));
if (this instanceof WeaponVehicleEntity weaponVehicle && weaponVehicle.getAllWeapons().length > 0) {
var selected = compound.getIntArray("SelectedWeapon");
@ -335,6 +348,9 @@ public abstract class VehicleEntity extends Entity {
compound.putFloat("Health", this.entityData.get(HEALTH));
compound.putString("LastAttacker", this.entityData.get(LAST_ATTACKER_UUID));
compound.putString("LastDriver", this.entityData.get(LAST_DRIVER_UUID));
compound.putInt("TurretDamagedTime", this.entityData.get(TURRET_DAMAGED_TIME));
compound.putInt("LWheelDamagedTime", this.entityData.get(L_WHEEL_DAMAGED_TIME));
compound.putInt("RWheelDamagedTime", this.entityData.get(R_WHEEL_DAMAGED_TIME));
if (this instanceof WeaponVehicleEntity weaponVehicle && weaponVehicle.getAllWeapons().length > 0) {
compound.putIntArray("SelectedWeapon", this.entityData.get(SELECTED_WEAPON));
@ -433,6 +449,10 @@ public abstract class VehicleEntity extends Entity {
// TODO 这里可以获取击中的部位给需要的载具加一个部位受伤方法
if (source.getDirectEntity() instanceof Projectile projectile) {
OBBHitter accessor = OBBHitter.getInstance(projectile);
//炮塔损伤
if (this instanceof OBBEntity obbEntity && accessor.sbw$getCurrentHitPart() == OBB.Part.TURRET && computedAmount > turretDamagedMin()) {
entityData.set(TURRET_DAMAGED_TIME, (int) (entityData.get(TURRET_DAMAGED_TIME) + computedAmount * turretDamagedMultiply()));
}
// System.out.println(accessor.sbw$getCurrentHitPart());
}
@ -634,9 +654,29 @@ public abstract class VehicleEntity extends Entity {
}
clearArrow();
partDamaged();
this.refreshDimensions();
}
public void partDamaged() {
// 炮塔损毁特效
if (entityData.get(TURRET_DAMAGED_TIME) > 0) {
List<Entity> entities = getPlayer(level());
for (var e : entities) {
if (e instanceof ServerPlayer player) {
if (player.level() instanceof ServerLevel serverLevel) {
Matrix4f transformT = getTurretTransform(1);
Vector4f worldPositionT = transformPosition(transformT, 0, 0.5f, 0f);
sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), worldPositionT.x, worldPositionT.y, worldPositionT.z, 5, 0.25, 0.25, 0.25, 0.25, true);
sendParticle(serverLevel, ParticleTypes.LARGE_SMOKE, worldPositionT.x, worldPositionT.y, worldPositionT.z, 1, 1, 0.5, 1, 0.01, true);
}
}
}
entityData.set(TURRET_DAMAGED_TIME, entityData.get(TURRET_DAMAGED_TIME) - 1);
}
}
public void clearArrow() {
List<Entity> list = this.level().getEntities(this, this.getBoundingBox().inflate(0F, 0.5F, 0F));
if (!list.isEmpty()) {
@ -698,6 +738,11 @@ public abstract class VehicleEntity extends Entity {
this.turretTurnSound(diffX, diffY, 0.95f);
if (entityData.get(TURRET_DAMAGED_TIME) > 0) {
ySpeed *= 0.2f;
xSpeed *= 0.2f;
}
float min = -ySpeed + (float) (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT);
float max = ySpeed + (float) (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT);
@ -800,6 +845,10 @@ public abstract class VehicleEntity extends Entity {
return transform;
}
public Matrix4f getTurretTransform(float ticks) {
return getVehicleTransform(ticks);
}
public Vector4f transformPosition(Matrix4f transform, float x, float y, float z) {
return transform.transform(new Vector4f(x, y, z, 1));
}
@ -1034,6 +1083,14 @@ public abstract class VehicleEntity extends Entity {
super.addDeltaMovement(pAddend);
}
public float turretDamagedMin() {
return 30;
}
public float turretDamagedMultiply() {
return 4;
}
/**
* 玩家在载具上的灵敏度调整
*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B