优化火炮自瞄,添加各种瞄准失败提示信息

This commit is contained in:
Atsuishio 2025-07-15 23:54:54 +08:00 committed by Light_Quanta
parent 101ae62310
commit 9ad273d750
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
11 changed files with 205 additions and 119 deletions

View file

@ -41,7 +41,7 @@ public class MortarInfoOverlay implements LayeredDraw.Layer {
.append(Component.literal(FormatTool.format1D(mortar.getYRot(), "°"))), .append(Component.literal(FormatTool.format1D(mortar.getYRot(), "°"))),
w / 2 - 90, h / 2 - 16, -1, false); w / 2 - 90, h / 2 - 16, -1, false);
guiGraphics.drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.range") guiGraphics.drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.range")
.append(Component.literal(FormatTool.format1D((int) RangeTool.getRange(-mortar.getXRot(), 13, 0.11), "m"))), .append(Component.literal(FormatTool.format1D((int) RangeTool.getRange(-mortar.getXRot(), mortar.shootVelocity(), -mortar.projectileGravity()), "m"))),
w / 2 - 90, h / 2 - 6, -1, false); w / 2 - 90, h / 2 - 6, -1, false);
} }
} }

View file

@ -107,6 +107,11 @@ public class Type63InfoOverlay implements LayeredDraw.Layer {
} }
ItemStack stack = player.getOffhandItem(); ItemStack stack = player.getOffhandItem();
if (player.getMainHandItem().getItem() instanceof FiringParameters) {
stack = player.getMainHandItem();
}
if (stack.getItem() instanceof FiringParameters) { if (stack.getItem() instanceof FiringParameters) {
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
if (parameters == null) { if (parameters == null) {
@ -148,6 +153,10 @@ public class Type63InfoOverlay implements LayeredDraw.Layer {
if (angle < -5 || angle > 60) { if (angle < -5 || angle > 60) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.warn", lookingEntity.getDisplayName()).withStyle(ChatFormatting.RED), guiGraphics.drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.warn", lookingEntity.getDisplayName()).withStyle(ChatFormatting.RED),
screenWidth / 2 + 90, screenHeight / 2 + 4, -1, false); screenWidth / 2 + 90, screenHeight / 2 + 4, -1, false);
if (angle > 60 && !isDepressed) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.ballistics.warn").withStyle(ChatFormatting.RED),
screenWidth / 2 + 90, screenHeight / 2 + 14, -1, false);
}
} }
} }
} }

View file

@ -70,8 +70,6 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, CannonEntity
public static final EntityDataAccessor<Vector3f> TARGET_POS = SynchedEntityData.defineId(Mk42Entity.class, EntityDataSerializers.VECTOR3); public static final EntityDataAccessor<Vector3f> TARGET_POS = SynchedEntityData.defineId(Mk42Entity.class, EntityDataSerializers.VECTOR3);
public static final EntityDataAccessor<Integer> RADIUS = SynchedEntityData.defineId(Mk42Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> RADIUS = SynchedEntityData.defineId(Mk42Entity.class, EntityDataSerializers.INT);
private final float shellGravity = 0.1f;
public Mk42Entity(EntityType<Mk42Entity> type, Level world) { public Mk42Entity(EntityType<Mk42Entity> type, Level world) {
super(type, world); super(type, world);
} }
@ -97,7 +95,7 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, CannonEntity
.explosionDamage(VehicleConfig.MK42_AP_EXPLOSION_DAMAGE.get()) .explosionDamage(VehicleConfig.MK42_AP_EXPLOSION_DAMAGE.get())
.explosionRadius(VehicleConfig.MK42_AP_EXPLOSION_RADIUS.get().floatValue()) .explosionRadius(VehicleConfig.MK42_AP_EXPLOSION_RADIUS.get().floatValue())
.durability(60) .durability(60)
.gravity(shellGravity) .gravity(projectileGravity())
.sound(ModSounds.CANNON_RELOAD.get()) .sound(ModSounds.CANNON_RELOAD.get())
.icon(Mod.loc("textures/screens/vehicle_weapon/ap_shell.png")), .icon(Mod.loc("textures/screens/vehicle_weapon/ap_shell.png")),
new CannonShellWeapon() new CannonShellWeapon()
@ -107,7 +105,7 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, CannonEntity
.durability(1) .durability(1)
.fireProbability(0.18F) .fireProbability(0.18F)
.fireTime(2) .fireTime(2)
.gravity(shellGravity) .gravity(projectileGravity())
.sound(ModSounds.CANNON_RELOAD.get()) .sound(ModSounds.CANNON_RELOAD.get())
.icon(Mod.loc("textures/screens/vehicle_weapon/he_shell.png")), .icon(Mod.loc("textures/screens/vehicle_weapon/he_shell.png")),
} }
@ -182,69 +180,65 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, CannonEntity
} }
if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) { if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) {
if (setTarget(player.getMainHandItem())) { setTarget(player.getMainHandItem(), player);
player.swing(InteractionHand.MAIN_HAND);
return InteractionResult.SUCCESS;
} else {
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName()).withStyle(ChatFormatting.RED), true);
return InteractionResult.FAIL;
}
} }
if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) { if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) {
if (setTarget(player.getOffhandItem())) { setTarget(player.getMainHandItem(), player);
player.swing(InteractionHand.OFF_HAND);
return InteractionResult.SUCCESS;
} else {
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName()).withStyle(ChatFormatting.RED), true);
return InteractionResult.FAIL;
}
} }
return super.interact(player, hand); return super.interact(player, hand);
} }
@Override @Override
public boolean setTarget(ItemStack stack) { public void setTarget(ItemStack stack, Entity entity) {
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
if (parameters == null) return false; if (parameters == null) return;
var pos = parameters.pos(); var pos = parameters.pos();
int targetX = pos.getX(); int targetX = pos.getX();
int targetY = pos.getY(); int targetY = pos.getY();
int targetZ = pos.getZ(); int targetZ = pos.getZ();
var isDepressed = parameters.isDepressed(); var isDepressed = parameters.isDepressed();
var radius = parameters.radius();
Matrix4f transform = getVehicleFlatTransform(1); boolean canAim = true;
Vector4f worldPosition = transformPosition(transform, 0f, 2.16f, 0.5175f);
Vec3 shootPos = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
double adjust = -1 + 0.004 * new Vec3(targetX, targetY, targetZ).distanceTo(shootPos);
entityData.set(TARGET_POS, new Vector3f((float) targetX, (float) (targetY - adjust), (float) targetZ)); entityData.set(TARGET_POS, new Vector3f((float) targetX, (float) targetY, (float) targetZ));
entityData.set(DEPRESSED, isDepressed); entityData.set(DEPRESSED, isDepressed);
entityData.set(RADIUS, parameters.radius()); entityData.set(RADIUS, radius);
Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS)); Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS));
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, shootVelocity(), projectileGravity(), entityData.get(DEPRESSED));
try { Component component = Component.literal("");
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 15, -shellGravity, entityData.get(DEPRESSED)); Component location = Component.translatable("tips.superbwarfare.mortar.position", this.getDisplayName())
this.look(randomPos); .append(Component.literal(" X:" + FormatTool.format0D(getX()) + " Y:" + FormatTool.format0D(getY()) + " Z:" + FormatTool.format0D(getZ()) + " "));
float angle = getXRot();
if (launchVector == null) { if (launchVector == null) {
return false; canAim = false;
component = Component.translatable("tips.superbwarfare.mortar.out_of_range");
} else {
angle = (float) -getXRotFromVector(launchVector);
if (angle < -maxPitch() || angle > -minPitch()) {
canAim = false;
component = Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName());
if (angle < -maxPitch()) {
component = Component.translatable("tips.superbwarfare.ballistics.warn");
}
} }
float angle = (float) -getXRotFromVector(launchVector);
if (angle < -85 || angle > 14.9) {
return false;
}
entityData.set(PITCH, angle);
} catch (Exception e) {
return false;
} }
return true;
if (canAim) {
this.look(randomPos);
entityData.set(PITCH, angle);
} else if (entity instanceof Player player) {
player.displayClientMessage(location.copy().append(component).withStyle(ChatFormatting.RED), false);
}
} }
@Override @Override
public void resetTarget() { public void resetTarget() {
Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS)); Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS));
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 15, -shellGravity, entityData.get(DEPRESSED)); Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 15, projectileGravity(), entityData.get(DEPRESSED));
this.look(randomPos); this.look(randomPos);
if (launchVector == null) { if (launchVector == null) {
@ -256,6 +250,26 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, CannonEntity
} }
} }
@Override
public double minPitch() {
return -14.9;
}
@Override
public double maxPitch() {
return 85;
}
@Override
public double shootVelocity() {
return 15;
}
@Override
public float projectileGravity() {
return -0.1f;
}
@Override @Override
public void look(Vec3 pTarget) { public void look(Vec3 pTarget) {
Matrix4f transform = getVehicleFlatTransform(1); Matrix4f transform = getVehicleFlatTransform(1);

View file

@ -73,8 +73,6 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, CannonEnt
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private final float shellGravity = 0.1f;
public Mle1934Entity(EntityType<Mle1934Entity> type, Level world) { public Mle1934Entity(EntityType<Mle1934Entity> type, Level world) {
super(type, world); super(type, world);
} }
@ -88,7 +86,7 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, CannonEnt
.explosionDamage(VehicleConfig.MLE1934_AP_EXPLOSION_DAMAGE.get()) .explosionDamage(VehicleConfig.MLE1934_AP_EXPLOSION_DAMAGE.get())
.explosionRadius(VehicleConfig.MLE1934_AP_EXPLOSION_RADIUS.get().floatValue()) .explosionRadius(VehicleConfig.MLE1934_AP_EXPLOSION_RADIUS.get().floatValue())
.durability(70) .durability(70)
.gravity(shellGravity) .gravity(projectileGravity())
.sound(ModSounds.CANNON_RELOAD.get()) .sound(ModSounds.CANNON_RELOAD.get())
.icon(Mod.loc("textures/screens/vehicle_weapon/ap_shell.png")), .icon(Mod.loc("textures/screens/vehicle_weapon/ap_shell.png")),
new CannonShellWeapon() new CannonShellWeapon()
@ -98,7 +96,7 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, CannonEnt
.durability(1) .durability(1)
.fireProbability(0.24F) .fireProbability(0.24F)
.fireTime(5) .fireTime(5)
.gravity(shellGravity) .gravity(projectileGravity())
.sound(ModSounds.CANNON_RELOAD.get()) .sound(ModSounds.CANNON_RELOAD.get())
.icon(Mod.loc("textures/screens/vehicle_weapon/he_shell.png")), .icon(Mod.loc("textures/screens/vehicle_weapon/he_shell.png")),
} }
@ -200,70 +198,63 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, CannonEnt
} }
if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) { if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) {
if (setTarget(player.getMainHandItem())) { setTarget(player.getMainHandItem(), player);
player.swing(InteractionHand.MAIN_HAND);
return InteractionResult.SUCCESS;
} else {
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName()).withStyle(ChatFormatting.RED), true);
return InteractionResult.FAIL;
}
} }
if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) { if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) {
if (setTarget(player.getOffhandItem())) { setTarget(player.getMainHandItem(), player);
player.swing(InteractionHand.OFF_HAND);
return InteractionResult.SUCCESS;
} else {
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName()).withStyle(ChatFormatting.RED), true);
return InteractionResult.FAIL;
}
} }
return super.interact(player, hand); return super.interact(player, hand);
} }
//这个炮仰角太低只能用低伸弹道 //这个炮仰角太低只能用低伸弹道
@Override @Override
public boolean setTarget(ItemStack stack) { public void setTarget(ItemStack stack, Entity entity) {
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
if (parameters == null) return false; if (parameters == null) return;
var pos = parameters.pos(); var pos = parameters.pos();
int targetX = pos.getX(); int targetX = pos.getX();
int targetY = pos.getY(); int targetY = pos.getY();
int targetZ = pos.getZ(); int targetZ = pos.getZ();
// var isDepressed = parameters.isDepressed(); boolean canAim = true;
Matrix4f transform = getVehicleFlatTransform(1); entityData.set(TARGET_POS, new Vector3f((float) targetX, (float) targetY, (float) targetZ));
Vector4f worldPosition = transformPosition(transform, 0, 1.4992625f, 1.52065f);
Vec3 shootPos = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
double adjust = -1 + 0.004 * new Vec3(targetX, targetY, targetZ).distanceTo(shootPos);
entityData.set(TARGET_POS, new Vector3f((float) targetX, (float) (targetY - adjust), (float) targetZ));
entityData.set(DEPRESSED, true); entityData.set(DEPRESSED, true);
entityData.set(RADIUS, parameters.radius()); entityData.set(RADIUS, parameters.radius());
Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS)); Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS));
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, shootVelocity(), projectileGravity(), entityData.get(DEPRESSED));
try { Component component = Component.literal("");
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 15, -shellGravity, entityData.get(DEPRESSED)); Component location = Component.translatable("tips.superbwarfare.mortar.position", this.getDisplayName())
this.look(randomPos); .append(Component.literal(" X:" + FormatTool.format0D(getX()) + " Y:" + FormatTool.format0D(getY()) + " Z:" + FormatTool.format0D(getZ()) + " "));
float angle = getXRot();
if (launchVector == null) { if (launchVector == null) {
return false; canAim = false;
component = Component.translatable("tips.superbwarfare.mortar.out_of_range");
} else {
angle = (float) -getXRotFromVector(launchVector);
if (angle < -maxPitch() || angle > -minPitch()) {
canAim = false;
component = Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName());
if (angle < -maxPitch()) {
component = Component.translatable("tips.superbwarfare.ballistics.warn");
}
} }
float angle = (float) -getXRotFromVector(launchVector);
if (angle < -30 || angle > 2.7) {
return false;
}
entityData.set(PITCH, angle);
} catch (Exception e) {
return false;
} }
return true;
if (canAim) {
this.look(randomPos);
entityData.set(PITCH, angle);
} else if (entity instanceof Player player) {
player.displayClientMessage(location.copy().append(component).withStyle(ChatFormatting.RED), false);
}
} }
@Override @Override
public void resetTarget() { public void resetTarget() {
Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS)); Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS));
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 15, -shellGravity, entityData.get(DEPRESSED)); Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 15, projectileGravity(), entityData.get(DEPRESSED));
this.look(randomPos); this.look(randomPos);
if (launchVector == null) { if (launchVector == null) {
@ -275,6 +266,26 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, CannonEnt
} }
} }
@Override
public double minPitch() {
return -2.7;
}
@Override
public double maxPitch() {
return 30;
}
@Override
public double shootVelocity() {
return 15;
}
@Override
public float projectileGravity() {
return -0.1f;
}
@Override @Override
public void look(Vec3 pTarget) { public void look(Vec3 pTarget) {
Matrix4f transform = getVehicleFlatTransform(1); Matrix4f transform = getVehicleFlatTransform(1);

View file

@ -12,6 +12,7 @@ import com.atsuishio.superbwarfare.item.ArtilleryIndicator;
import com.atsuishio.superbwarfare.item.Monitor; import com.atsuishio.superbwarfare.item.Monitor;
import com.atsuishio.superbwarfare.item.common.ammo.MortarShell; import com.atsuishio.superbwarfare.item.common.ammo.MortarShell;
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage; import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
import com.atsuishio.superbwarfare.tools.FormatTool;
import com.atsuishio.superbwarfare.tools.VectorTool; import com.atsuishio.superbwarfare.tools.VectorTool;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.commands.arguments.EntityAnchorArgument;
@ -28,6 +29,7 @@ import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.MoverType;
@ -160,6 +162,26 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, RemoteCont
this.fire(player); this.fire(player);
} }
@Override
public double minPitch() {
return 20;
}
@Override
public double maxPitch() {
return 89;
}
@Override
public double shootVelocity() {
return 10;
}
@Override
public float projectileGravity() {
return -0.13f;
}
@Override @Override
public @NotNull InteractionResult interact(Player player, @NotNull InteractionHand hand) { public @NotNull InteractionResult interact(Player player, @NotNull InteractionHand hand) {
ItemStack mainHandItem = player.getMainHandItem(); ItemStack mainHandItem = player.getMainHandItem();
@ -194,22 +216,10 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, RemoteCont
} }
if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) { if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) {
if (setTarget(player.getMainHandItem())) { setTarget(player.getMainHandItem(), player);
player.swing(InteractionHand.MAIN_HAND);
return InteractionResult.SUCCESS;
} else {
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName()).withStyle(ChatFormatting.RED), true);
return InteractionResult.FAIL;
}
} }
if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) { if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get()) {
if (setTarget(player.getOffhandItem())) { setTarget(player.getMainHandItem(), player);
player.swing(InteractionHand.OFF_HAND);
return InteractionResult.SUCCESS;
} else {
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName()).withStyle(ChatFormatting.RED), true);
return InteractionResult.FAIL;
}
} }
if (player.isShiftKeyDown()) { if (player.isShiftKeyDown()) {
@ -228,9 +238,9 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, RemoteCont
} }
@Override @Override
public boolean setTarget(ItemStack stack) { public void setTarget(ItemStack stack, Entity entity) {
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
if (parameters == null) return false; if (parameters == null) return;
var pos = parameters.pos(); var pos = parameters.pos();
double targetX = pos.getX(); double targetX = pos.getX();
@ -238,33 +248,57 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, RemoteCont
double targetZ = pos.getZ(); double targetZ = pos.getZ();
var isDepressed = parameters.isDepressed(); var isDepressed = parameters.isDepressed();
boolean canAim = true;
entityData.set(TARGET_POS, new Vector3f((float) targetX, (float) targetY, (float) targetZ)); entityData.set(TARGET_POS, new Vector3f((float) targetX, (float) targetY, (float) targetZ));
entityData.set(DEPRESSED, isDepressed); entityData.set(DEPRESSED, isDepressed);
entityData.set(RADIUS, parameters.radius()); entityData.set(RADIUS, parameters.radius());
Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS)); Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS));
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, shootVelocity(), projectileGravity(), entityData.get(DEPRESSED));
Vec3 launchVector2 = calculateLaunchVector(getEyePosition(), randomPos, shootVelocity(), projectileGravity(), !entityData.get(DEPRESSED));
try { Component component = Component.literal("");
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 13, -0.11, entityData.get(DEPRESSED)); Component location = Component.translatable("tips.superbwarfare.mortar.position", this.getDisplayName())
this.look(randomPos); .append(Component.literal(" X:" + FormatTool.format0D(getX()) + " Y:" + FormatTool.format0D(getY()) + " Z:" + FormatTool.format0D(getZ()) + " "));
float angle = getXRot();
if (launchVector == null) { if (launchVector == null || launchVector2 == null) {
return false; canAim = false;
component = Component.translatable("tips.superbwarfare.mortar.out_of_range");
} else {
angle = (float) -getXRotFromVector(launchVector);
float angle2 = (float) -getXRotFromVector(launchVector2);
if (angle < -maxPitch() || angle > -minPitch()) {
if (angle2 > -maxPitch() && angle2 < -minPitch()) {
component = Component.translatable("tips.superbwarfare.ballistics.warn2");
canAim = false;
} else {
component = Component.translatable("tips.superbwarfare.mortar.warn", this.getDisplayName());
if (entity instanceof Player player) {
player.displayClientMessage(location.copy().append(component).withStyle(ChatFormatting.RED), false);
}
return;
}
} }
float angle = (float) -getXRotFromVector(launchVector);
if (angle < -89 || angle > -20) { if (angle < -maxPitch()) {
return false; component = Component.translatable("tips.superbwarfare.ballistics.warn");
canAim = false;
} }
entityData.set(PITCH, angle);
} catch (Exception e) {
return false;
} }
return true;
if (canAim) {
this.look(randomPos);
entityData.set(PITCH, angle);
} else if (entity instanceof Player player) {
player.displayClientMessage(location.copy().append(component).withStyle(ChatFormatting.RED), false);
}
} }
@Override @Override
public void resetTarget() { public void resetTarget() {
Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS)); Vec3 randomPos = VectorTool.randomPos(new Vec3(entityData.get(TARGET_POS)), entityData.get(RADIUS));
Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, 13, -0.11, entityData.get(DEPRESSED)); Vec3 launchVector = calculateLaunchVector(getEyePosition(), randomPos, shootVelocity(), projectileGravity(), entityData.get(DEPRESSED));
this.look(randomPos); this.look(randomPos);
if (launchVector == null) { if (launchVector == null) {
@ -302,7 +336,7 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, RemoteCont
if (level instanceof ServerLevel server) { if (level instanceof ServerLevel server) {
MortarShellEntity entityToSpawn = MortarShell.createShell(shooter, level, this.items.getFirst()); MortarShellEntity entityToSpawn = MortarShell.createShell(shooter, level, this.items.getFirst());
entityToSpawn.setPos(this.getX(), this.getEyeY(), this.getZ()); entityToSpawn.setPos(this.getX(), this.getEyeY(), this.getZ());
entityToSpawn.shoot(this.getLookAngle().x, this.getLookAngle().y, this.getLookAngle().z, 13f, (float) 0.1); entityToSpawn.shoot(this.getLookAngle().x, this.getLookAngle().y, this.getLookAngle().z, (float) shootVelocity(), (float) 0.1);
level.addFreshEntity(entityToSpawn); level.addFreshEntity(entityToSpawn);
server.sendParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, (this.getX() + 3 * this.getLookAngle().x), (this.getY() + 0.1 + 3 * this.getLookAngle().y), (this.getZ() + 3 * this.getLookAngle().z), 8, 0.4, 0.4, 0.4, server.sendParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, (this.getX() + 3 * this.getLookAngle().x), (this.getY() + 0.1 + 3 * this.getLookAngle().y), (this.getZ() + 3 * this.getLookAngle().z), 8, 0.4, 0.4, 0.4,
0.007); 0.007);

View file

@ -561,4 +561,9 @@ public class Type63Entity extends ContainerMobileVehicleEntity implements GeoEnt
} }
this.entityData.set(LOADED_AMMO, list); this.entityData.set(LOADED_AMMO, list);
} }
@Override
public boolean hasEnergyStorage() {
return false;
}
} }

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.entity.vehicle.base; package com.atsuishio.superbwarfare.entity.vehicle.base;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@ -8,7 +9,7 @@ import javax.annotation.Nullable;
public interface RemoteControllableTurret { public interface RemoteControllableTurret {
boolean setTarget(ItemStack stack); void setTarget(ItemStack stack, Entity entity);
void resetTarget(); void resetTarget();
@ -17,4 +18,13 @@ public interface RemoteControllableTurret {
boolean canRemoteFire(); boolean canRemoteFire();
void remoteFire(@Nullable Player player); void remoteFire(@Nullable Player player);
double minPitch();
double maxPitch();
double shootVelocity();
float projectileGravity();
} }

View file

@ -150,11 +150,7 @@ public class ArtilleryIndicator extends Item implements ItemScreenProvider {
if (entity instanceof RemoteControllableTurret lockTargetEntity) { if (entity instanceof RemoteControllableTurret lockTargetEntity) {
list.add(tag); list.add(tag);
lockTargetEntity.setTarget(stack, player);
if (!lockTargetEntity.setTarget(stack)) {
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.warn", entity.getDisplayName())
.withStyle(ChatFormatting.RED), true);
}
} }
} }

View file

@ -598,6 +598,10 @@
"tips.superbwarfare.mortar.target_pos.depressed_trajectory": "Depressed Trajectory", "tips.superbwarfare.mortar.target_pos.depressed_trajectory": "Depressed Trajectory",
"tips.superbwarfare.mortar.target_pos.lofted_trajectory": "Lofted Trajectory", "tips.superbwarfare.mortar.target_pos.lofted_trajectory": "Lofted Trajectory",
"tips.superbwarfare.mortar.warn": "%1$s cannot aim at this position", "tips.superbwarfare.mortar.warn": "%1$s cannot aim at this position",
"tips.superbwarfare.mortar.position": "%1$s located in",
"tips.superbwarfare.ballistics.warn": "Use Depressed Trajectory Please",
"tips.superbwarfare.ballistics.warn2": "Use Lofted Trajectory Please",
"tips.superbwarfare.target.yaw": "Target Yaw: ", "tips.superbwarfare.target.yaw": "Target Yaw: ",
"tips.superbwarfare.target.pitch": "Target Pitch: ", "tips.superbwarfare.target.pitch": "Target Pitch: ",
"tips.superbwarfare.barrel_empty": "EMPTY", "tips.superbwarfare.barrel_empty": "EMPTY",

View file

@ -598,6 +598,10 @@
"tips.superbwarfare.mortar.target_pos.depressed_trajectory": "低伸弹道", "tips.superbwarfare.mortar.target_pos.depressed_trajectory": "低伸弹道",
"tips.superbwarfare.mortar.target_pos.lofted_trajectory": "传统弹道", "tips.superbwarfare.mortar.target_pos.lofted_trajectory": "传统弹道",
"tips.superbwarfare.mortar.warn": "%1$s无法瞄准该位置", "tips.superbwarfare.mortar.warn": "%1$s无法瞄准该位置",
"tips.superbwarfare.mortar.position": "%1$s位于",
"tips.superbwarfare.ballistics.warn": "请使用低伸弹道",
"tips.superbwarfare.ballistics.warn2": "请使用传统弹道",
"tips.superbwarfare.target.yaw": "目标偏航角: ", "tips.superbwarfare.target.yaw": "目标偏航角: ",
"tips.superbwarfare.target.pitch": "目标俯仰角: ", "tips.superbwarfare.target.pitch": "目标俯仰角: ",
"tips.superbwarfare.barrel_empty": "空", "tips.superbwarfare.barrel_empty": "空",

View file

@ -1,7 +1,6 @@
{ {
"ID": "superbwarfare:type_63", "ID": "superbwarfare:type_63",
"MaxHealth": 100, "MaxHealth": 100,
"MaxEnergy": 24000,
"Mass": 0.45, "Mass": 0.45,
"DamageModifiers": [ "DamageModifiers": [
{ {