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

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.client.RenderHelper;
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.base.*;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon;
@ -103,7 +104,7 @@ public class VehicleHudOverlay implements LayeredDraw.Layer {
int compatHeight = getArmorPlateCompatHeight(player);
if (vehicle instanceof EnergyVehicleEntity energyVehicleEntity) {
if (vehicle instanceof EnergyVehicleEntity energyVehicleEntity && !(vehicle instanceof Hpj11Entity)) {
float energy = energyVehicleEntity.getEnergy();
float maxEnergy = energyVehicleEntity.getMaxEnergy();
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);
}
if (this.level() instanceof ServerLevel) {
this.handleAmmo();
}
this.move(MoverType.SELF, this.getDeltaMovement());
if (this.onGround()) {
this.setDeltaMovement(Vec3.ZERO);
@ -227,13 +231,25 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
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() {
if (this.getFirstPassenger() != null || !entityData.get(ACTIVE)) {
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) {
Entity naerestEntity = seekNearLivingEntity(128);
Entity naerestEntity = seekNearLivingEntity(barrelRootPos,-32.5,90,3,128);
if (naerestEntity != null) {
entityData.set(TARGET_UUID, naerestEntity.getStringUUID());
}
@ -251,10 +267,6 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
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 targetVec = barrelRootPos.vectorTo(targetPos).normalize();
@ -273,7 +285,7 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
this.setRot(this.getYRot(), this.getXRot());
if (VectorTool.calculateAngle(getViewVector(1), targetVec) < 1) {
if (checkNoClip(target)) {
if (checkNoClip(target) && entityData.get(AMMO) > 0) {
vehicleShoot(player, 0);
} else {
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)
.filter(e -> {
// 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 false;
}).min(Comparator.comparingDouble(e -> e.distanceTo(this))).orElse(null);
}
public boolean checkNoClip(Entity target) {
return level().clip(new ClipContext(this.getEyePosition(), target.getEyePosition(),
ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() != HitResult.Type.BLOCK;
@ -479,16 +497,12 @@ public class Hpj11Entity extends ContainerMobileVehicleEntity implements GeoEnti
@Override
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
public int getAmmoCount(Player player) {
if (hasItem(ModItems.CREATIVE_AMMO_BOX.get())) {
return 9999;
} else {
return countItem(ModItems.SMALL_SHELL.get());
}
return this.entityData.get(AMMO);
}
@Override

View file

@ -241,8 +241,10 @@ public class LaserTowerEntity extends EnergyVehicleEntity implements GeoEntity,
return;
}
Vec3 barrelRootPos = new Vec3(this.getX(), this.getY() + 1.390625f, this.getZ());
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) {
entityData.set(TARGET_UUID, naerestEntity.getStringUUID());
}
@ -260,7 +262,6 @@ public class LaserTowerEntity extends EnergyVehicleEntity implements GeoEntity,
return;
}
Vec3 barrelRootPos = new Vec3(this.getX(), this.getY() + 1.390625f, this.getZ());
Vec3 targetVec = barrelRootPos.vectorTo(target.getEyePosition()).normalize();
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)
.filter(e -> {
// 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 false;

View file

@ -969,6 +969,13 @@ public abstract class VehicleEntity extends Entity {
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)
public void renderFirstPersonOverlay(GuiGraphics guiGraphics, Font font, Player player, int screenWidth, int screenHeight, float scale) {
if (!(this instanceof WeaponVehicleEntity weaponVehicle)) return;