优化防御塔目标选择,防御塔不会再试图瞄准射角之外的目标

This commit is contained in:
Atsuishio 2025-04-29 00:46:09 +08:00 committed by Light_Quanta
parent 614504b947
commit d2aeaa6a0a
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
4 changed files with 48 additions and 21 deletions

View file

@ -3,6 +3,7 @@ package com.atsuishio.superbwarfare.client.overlay;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.RenderHelper; import com.atsuishio.superbwarfare.client.RenderHelper;
import com.atsuishio.superbwarfare.config.client.DisplayConfig; import com.atsuishio.superbwarfare.config.client.DisplayConfig;
import com.atsuishio.superbwarfare.entity.vehicle.Hpj11Entity;
import com.atsuishio.superbwarfare.entity.vehicle.SpeedboatEntity; import com.atsuishio.superbwarfare.entity.vehicle.SpeedboatEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.*; import com.atsuishio.superbwarfare.entity.vehicle.base.*;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon;
@ -103,7 +104,7 @@ public class VehicleHudOverlay implements LayeredDraw.Layer {
int compatHeight = getArmorPlateCompatHeight(player); int compatHeight = getArmorPlateCompatHeight(player);
if (vehicle instanceof EnergyVehicleEntity energyVehicleEntity) { if (vehicle instanceof EnergyVehicleEntity energyVehicleEntity && !(vehicle instanceof Hpj11Entity)) {
float energy = energyVehicleEntity.getEnergy(); float energy = energyVehicleEntity.getEnergy();
float maxEnergy = energyVehicleEntity.getMaxEnergy(); float maxEnergy = energyVehicleEntity.getMaxEnergy();
preciseBlit(guiGraphics, ENERGY, 10, h - 22 - compatHeight, 100, 0, 0, 8, 8, 8, 8); preciseBlit(guiGraphics, ENERGY, 10, h - 22 - compatHeight, 100, 0, 0, 8, 8, 8, 8);

View file

@ -212,6 +212,10 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
this.entityData.set(ANIM_TIME, this.entityData.get(ANIM_TIME) - 1); this.entityData.set(ANIM_TIME, this.entityData.get(ANIM_TIME) - 1);
} }
if (this.level() instanceof ServerLevel) {
this.handleAmmo();
}
this.move(MoverType.SELF, this.getDeltaMovement()); this.move(MoverType.SELF, this.getDeltaMovement());
if (this.onGround()) { if (this.onGround()) {
this.setDeltaMovement(Vec3.ZERO); this.setDeltaMovement(Vec3.ZERO);
@ -227,13 +231,25 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
lowHealthWarning(); lowHealthWarning();
} }
private void handleAmmo() {
if (hasItem(ModItems.CREATIVE_AMMO_BOX.get())) {
entityData.set(AMMO, 9999);
} else {
entityData.set(AMMO, countItem(ModItems.SMALL_SHELL.get()));
}
}
public void autoAim() { public void autoAim() {
if (this.getFirstPassenger() != null || !entityData.get(ACTIVE)) { if (this.getFirstPassenger() != null || !entityData.get(ACTIVE)) {
return; return;
} }
Matrix4f transform = getBarrelTransform(1);
Vector4f worldPosition = transformPosition(transform, 0f, 0.4f, 0);
Vec3 barrelRootPos = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
if (entityData.get(TARGET_UUID).equals("none") && tickCount % 10 == 0) { if (entityData.get(TARGET_UUID).equals("none") && tickCount % 10 == 0) {
Entity naerestEntity = seekNearLivingEntity(128); Entity naerestEntity = seekNearLivingEntity(barrelRootPos,-32.5,90,3,128);
if (naerestEntity != null) { if (naerestEntity != null) {
entityData.set(TARGET_UUID, naerestEntity.getStringUUID()); entityData.set(TARGET_UUID, naerestEntity.getStringUUID());
} }
@ -251,10 +267,6 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
return; return;
} }
Matrix4f transform = getBarrelTransform(1);
Vector4f worldPosition = transformPosition(transform, 0f, 0.4f, 2.6875f);
Vec3 barrelRootPos = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
Vec3 targetPos = new Vec3(target.getX(), target.getY() + target.getBbHeight() / 2, target.getZ()); Vec3 targetPos = new Vec3(target.getX(), target.getY() + target.getBbHeight() / 2, target.getZ());
Vec3 targetVec = barrelRootPos.vectorTo(targetPos).normalize(); Vec3 targetVec = barrelRootPos.vectorTo(targetPos).normalize();
@ -273,7 +285,7 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
this.setRot(this.getYRot(), this.getXRot()); this.setRot(this.getYRot(), this.getXRot());
if (VectorTool.calculateAngle(getViewVector(1), targetVec) < 1) { if (VectorTool.calculateAngle(getViewVector(1), targetVec) < 1) {
if (checkNoClip(target)) { if (checkNoClip(target) && entityData.get(AMMO) > 0) {
vehicleShoot(player, 0); vehicleShoot(player, 0);
} else { } else {
changeTargetTimer++; changeTargetTimer++;
@ -294,18 +306,24 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
} }
} }
public Entity seekNearLivingEntity(double seekRange) { public Entity seekNearLivingEntity(Vec3 pos, double minAngle, double maxAngle, double minRange, double seekRange) {
return StreamSupport.stream(EntityFindUtil.getEntities(level()).getAll().spliterator(), false) return StreamSupport.stream(EntityFindUtil.getEntities(level()).getAll().spliterator(), false)
.filter(e -> { .filter(e -> {
// TODO 自定义目标列表 // TODO 自定义目标列表
if (e.distanceTo(this) <= seekRange && ((e instanceof LivingEntity living && living instanceof Enemy && living.getHealth() > 0) if (e.distanceTo(this) > minRange
)) { && e.distanceTo(this) <= seekRange
&& canAim(pos, e, minAngle, maxAngle)
&& e instanceof LivingEntity living
&& living instanceof Enemy
&& living.getHealth() > 0) {
return checkNoClip(e); return checkNoClip(e);
} }
return false; return false;
}).min(Comparator.comparingDouble(e -> e.distanceTo(this))).orElse(null); }).min(Comparator.comparingDouble(e -> e.distanceTo(this))).orElse(null);
} }
public boolean checkNoClip(Entity target) { public boolean checkNoClip(Entity target) {
return level().clip(new ClipContext(this.getEyePosition(), target.getEyePosition(), return level().clip(new ClipContext(this.getEyePosition(), target.getEyePosition(),
ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() != HitResult.Type.BLOCK; ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() != HitResult.Type.BLOCK;
@ -479,16 +497,12 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
@Override @Override
public boolean canShoot(Player player) { public boolean canShoot(Player player) {
return (countItem(ModItems.SMALL_SHELL.get()) > 0 || InventoryTool.hasCreativeAmmoBox(player) || hasItem(ModItems.CREATIVE_AMMO_BOX.get())) && !cannotFire; return (this.entityData.get(AMMO) > 0 || InventoryTool.hasCreativeAmmoBox(player)) && !cannotFire;
} }
@Override @Override
public int getAmmoCount(Player player) { public int getAmmoCount(Player player) {
if (hasItem(ModItems.CREATIVE_AMMO_BOX.get())) { return this.entityData.get(AMMO);
return 9999;
} else {
return countItem(ModItems.SMALL_SHELL.get());
}
} }
@Override @Override

View file

@ -241,8 +241,10 @@ public class LaserTowerEntity extends EnergyVehicleEntity implements GeoEntity,
return; return;
} }
Vec3 barrelRootPos = new Vec3(this.getX(), this.getY() + 1.390625f, this.getZ());
if (entityData.get(TARGET_UUID).equals("none") && tickCount % 10 == 0) { if (entityData.get(TARGET_UUID).equals("none") && tickCount % 10 == 0) {
Entity naerestEntity = seekNearLivingEntity(72); Entity naerestEntity = seekNearLivingEntity(barrelRootPos,-40, 90,1,72);
if (naerestEntity != null) { if (naerestEntity != null) {
entityData.set(TARGET_UUID, naerestEntity.getStringUUID()); entityData.set(TARGET_UUID, naerestEntity.getStringUUID());
} }
@ -260,7 +262,6 @@ public class LaserTowerEntity extends EnergyVehicleEntity implements GeoEntity,
return; return;
} }
Vec3 barrelRootPos = new Vec3(this.getX(), this.getY() + 1.390625f, this.getZ());
Vec3 targetVec = barrelRootPos.vectorTo(target.getEyePosition()).normalize(); Vec3 targetVec = barrelRootPos.vectorTo(target.getEyePosition()).normalize();
double d0 = targetVec.x; double d0 = targetVec.x;
@ -312,12 +313,16 @@ public class LaserTowerEntity extends EnergyVehicleEntity implements GeoEntity,
} }
} }
public Entity seekNearLivingEntity(double seekRange) { public Entity seekNearLivingEntity(Vec3 pos, double minAngle, double maxAngle, double minRange, double seekRange) {
return StreamSupport.stream(EntityFindUtil.getEntities(level()).getAll().spliterator(), false) return StreamSupport.stream(EntityFindUtil.getEntities(level()).getAll().spliterator(), false)
.filter(e -> { .filter(e -> {
// TODO 自定义目标列表 // TODO 自定义目标列表
if (e.distanceTo(this) <= seekRange && ((e instanceof LivingEntity living && living instanceof Enemy && living.getHealth() > 0) if (e.distanceTo(this) > minRange
)) { && e.distanceTo(this) <= seekRange
&& canAim(pos, e, minAngle, maxAngle)
&& e instanceof LivingEntity living
&& living instanceof Enemy
&& living.getHealth() > 0) {
return checkNoClip(e); return checkNoClip(e);
} }
return false; return false;

View file

@ -969,6 +969,13 @@ public abstract class VehicleEntity extends Entity {
return getEyePosition(); return getEyePosition();
} }
public static boolean canAim (Vec3 pos, Entity target, double minAngle, double maxAngle) {
Vec3 targetPos = new Vec3(target.getX(), target.getY() + target.getBbHeight() / 2, target.getZ());
Vec3 toVec = pos.vectorTo(targetPos).normalize();
double targetAngle = VehicleEntity.getXRotFromVector(toVec);
return minAngle < targetAngle && targetAngle < maxAngle;
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderFirstPersonOverlay(GuiGraphics guiGraphics, Font font, Player player, int screenWidth, int screenHeight, float scale) { public void renderFirstPersonOverlay(GuiGraphics guiGraphics, Font font, Player player, int screenWidth, int screenHeight, float scale) {
if (!(this instanceof WeaponVehicleEntity weaponVehicle)) return; if (!(this instanceof WeaponVehicleEntity weaponVehicle)) return;