重写炮弹运动,优化瞄准算法
This commit is contained in:
parent
a79327161c
commit
87f0c307bf
15 changed files with 219 additions and 211 deletions
|
@ -1,149 +1,66 @@
|
||||||
package com.atsuishio.superbwarfare.client.gui;
|
package com.atsuishio.superbwarfare.client.gui;
|
||||||
|
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class RangeHelper {
|
public class RangeHelper {
|
||||||
|
|
||||||
public static final int MAX_RANGE = 1145;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算迫击炮理论水平射程
|
* 计算迫击炮理论水平射程
|
||||||
*
|
*
|
||||||
* @param thetaDegrees 发射角度(以度为单位),需要根据实际情况修改
|
* @param thetaDegrees 发射角度(以度为单位),需要根据实际情况修改
|
||||||
|
* @param v 初始速度
|
||||||
|
* @param g 重力加速度
|
||||||
*/
|
*/
|
||||||
public static double getRange(double thetaDegrees) {
|
public static double getRange(double thetaDegrees, double v, double g) {
|
||||||
double initialVelocity = 11.4; // 初始速度 11.4 m/s
|
double t = v * Math.sin(thetaDegrees * Mth.DEG_TO_RAD) / g * 2;
|
||||||
double thetaRadians = Math.toRadians(thetaDegrees); // 将角度转换为弧度
|
return t * v * Math.cos(thetaDegrees * Mth.DEG_TO_RAD);
|
||||||
double gravity = 0.146; // 重力加速度
|
|
||||||
double velocityDecay = 0.99; // 速度衰减系数
|
|
||||||
|
|
||||||
// 计算射程
|
|
||||||
return calculateRange(initialVelocity, thetaRadians, gravity, velocityDecay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double calculateRange(double initialVelocity, double theta, double gravity, double velocityDecay) {
|
// 谢谢DeepSeek
|
||||||
double vx = initialVelocity * Math.cos(theta); // 水平速度
|
|
||||||
double vy = initialVelocity * Math.sin(theta); // 垂直速度
|
|
||||||
|
|
||||||
double x = 0.0; // 水平位置
|
/**
|
||||||
double y = 1.0; // 垂直位置
|
* 判断按指定参数发射是否可以击中目标
|
||||||
|
*
|
||||||
|
* @param v 初始速度
|
||||||
|
* @param g 重力加速度
|
||||||
|
* @param startPos 起始位置
|
||||||
|
* @param endPos 目标位置
|
||||||
|
* @param minAngle 最小仰角
|
||||||
|
* @param maxAngle 最大仰角
|
||||||
|
* @param isDepressedTrajectory 是否使用低伸弹道
|
||||||
|
*/
|
||||||
|
public static boolean canReach(double v, double g, Vec3 startPos, Vec3 endPos, double minAngle, double maxAngle, boolean isDepressedTrajectory) {
|
||||||
|
if (getD(v, g, startPos, endPos) < 0) return false;
|
||||||
|
|
||||||
// 当炮弹还未触地时,继续计算飞行轨迹
|
var targetAngle = calculateAngle(v, g, startPos, endPos, isDepressedTrajectory);
|
||||||
while (y >= 0) {
|
return targetAngle >= minAngle && targetAngle <= maxAngle;
|
||||||
// 更新位置
|
|
||||||
x += vx;
|
|
||||||
y += vy;
|
|
||||||
|
|
||||||
// 更新速度
|
|
||||||
vx *= velocityDecay;
|
|
||||||
vy = vy * velocityDecay - gravity;
|
|
||||||
|
|
||||||
// 如果炮弹触地,则跳出循环
|
|
||||||
if (y < 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回最终水平距离
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double calculateRangeWithDeltaY(double initialVelocity, double theta, double gravity, double velocityDecay, double deltaY) {
|
/**
|
||||||
double vx = initialVelocity * Math.cos(theta); // 水平速度
|
* 计算按指定参数发射所需的仰角
|
||||||
double vy = initialVelocity * Math.sin(theta); // 垂直速度
|
*
|
||||||
|
* @param v 初始速度
|
||||||
double range = 0.0; // 水平距离
|
* @param g 重力加速度
|
||||||
double y = 1.0; // 垂直位置
|
* @param startPos 起始位置
|
||||||
|
* @param endPos 目标位置
|
||||||
double commonRange = calculateRange(initialVelocity, theta, gravity, velocityDecay);
|
* @param isDepressedTrajectory 是否使用低伸弹道
|
||||||
|
*/
|
||||||
// 当炮弹还未触地时,继续计算飞行轨迹
|
public static double calculateAngle(double v, double g, Vec3 startPos, Vec3 endPos, boolean isDepressedTrajectory) {
|
||||||
while (range < commonRange / 2 || (range >= commonRange / 2 && y >= deltaY)) {
|
var xDiff = startPos.x - endPos.x;
|
||||||
// 更新位置
|
var zDiff = startPos.z - endPos.z;
|
||||||
range += vx;
|
var x = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(zDiff, 2));
|
||||||
y += vy;
|
double d = getD(v, g, startPos, endPos);
|
||||||
|
return Math.atan((v * v + (isDepressedTrajectory ? -d : d)) / (g * x)) * Mth.RAD_TO_DEG;
|
||||||
// 更新速度
|
|
||||||
vx *= velocityDecay;
|
|
||||||
vy = vy * velocityDecay - gravity;
|
|
||||||
|
|
||||||
if (range >= commonRange / 2 && y < deltaY) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回最终水平距离
|
|
||||||
return range;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canReachTarget(double initialVelocity, double gravity, double velocityDecay, Vec3 startPos, Vec3 targetPos, double[] angles) {
|
private static double getD(double v, double g, Vec3 startPos, Vec3 endPos) {
|
||||||
if (startPos.equals(targetPos)) {
|
var xDiff = startPos.x - endPos.x;
|
||||||
return false;
|
var zDiff = startPos.z - endPos.z;
|
||||||
}
|
var x = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(zDiff, 2));
|
||||||
|
var y = startPos.y - endPos.y;
|
||||||
|
|
||||||
double startX = startPos.x;
|
return Math.sqrt(Math.pow(v, 4) - g * g * x * x - 2 * g * y * v * v);
|
||||||
double startY = startPos.y;
|
|
||||||
double startZ = startPos.z;
|
|
||||||
|
|
||||||
double targetX = targetPos.x;
|
|
||||||
double targetY = targetPos.y;
|
|
||||||
double targetZ = targetPos.z;
|
|
||||||
|
|
||||||
double distanceXZ = Math.sqrt(Math.pow(targetX - startX, 2) + Math.pow(targetZ - startZ, 2));
|
|
||||||
if (distanceXZ > MAX_RANGE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
double theta = calculateLaunchAngle(initialVelocity, gravity, velocityDecay, distanceXZ, targetY - startY);
|
|
||||||
|
|
||||||
if (theta < 20 || theta > 90) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
angles[0] = Math.atan2(targetZ, targetX); // 水平角度
|
|
||||||
angles[1] = theta; // 炮口抬升角度
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double calculateLaunchAngle(double initialVelocity, double gravity, double velocityDecay, double distanceXZ, double targetY) {
|
|
||||||
double left = 20; // 最小角度
|
|
||||||
double right = 30; // 最大角度
|
|
||||||
double tolerance = 0.5; // 允许的误差范围
|
|
||||||
|
|
||||||
// 在 20 到 30 之间搜索
|
|
||||||
while (right - left > tolerance) {
|
|
||||||
double mid = (left + right) / 2;
|
|
||||||
double radian = Math.toRadians(mid);
|
|
||||||
double range = calculateRangeWithDeltaY(initialVelocity, radian, gravity, velocityDecay, targetY);
|
|
||||||
|
|
||||||
if (Math.abs(range - distanceXZ) < tolerance * 8) {
|
|
||||||
return mid;
|
|
||||||
} else if (range < distanceXZ) {
|
|
||||||
left = mid;
|
|
||||||
} else {
|
|
||||||
right = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果在 20 到 30 之间没有找到合适的角度,则在 30 到 90 之间搜索
|
|
||||||
left = 30;
|
|
||||||
right = 90;
|
|
||||||
|
|
||||||
while (right - left > tolerance) {
|
|
||||||
double mid = (left + right) / 2;
|
|
||||||
double radian = Math.toRadians(mid);
|
|
||||||
double range = calculateRangeWithDeltaY(initialVelocity, radian, gravity, velocityDecay, targetY);
|
|
||||||
|
|
||||||
if (Math.abs(range - distanceXZ) < tolerance * 8) {
|
|
||||||
return mid;
|
|
||||||
} else if (range < distanceXZ) {
|
|
||||||
right = mid;
|
|
||||||
} else {
|
|
||||||
left = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果仍然没有找到合适的角度,则返回 -1
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class MortarInfoOverlay {
|
||||||
.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);
|
||||||
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.range")
|
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.mortar.range")
|
||||||
.append(Component.literal(FormatTool.format1D((int) RangeHelper.getRange(-mortar.getXRot()), "m"))),
|
.append(Component.literal(FormatTool.format1D((int) RangeHelper.getRange(-mortar.getXRot(), 11.4, 0.146), "m"))),
|
||||||
w / 2 - 90, h / 2 - 6, -1, false);
|
w / 2 - 90, h / 2 - 6, -1, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.atsuishio.superbwarfare.component;
|
package com.atsuishio.superbwarfare.component;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
|
import com.atsuishio.superbwarfare.item.FiringParameters;
|
||||||
import com.atsuishio.superbwarfare.item.common.ammo.box.AmmoBoxInfo;
|
import com.atsuishio.superbwarfare.item.common.ammo.box.AmmoBoxInfo;
|
||||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.component.DataComponentType;
|
import net.minecraft.core.component.DataComponentType;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
|
@ -19,9 +21,14 @@ public class ModDataComponents {
|
||||||
public static final DeferredRegister<DataComponentType<?>> DATA_COMPONENT_TYPES =
|
public static final DeferredRegister<DataComponentType<?>> DATA_COMPONENT_TYPES =
|
||||||
DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, Mod.MODID);
|
DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, Mod.MODID);
|
||||||
|
|
||||||
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockPos>> BLOCK_POS = register(
|
public static final DeferredHolder<DataComponentType<?>, DataComponentType<FiringParameters.Parameters>> FIRING_PARAMETERS = register(
|
||||||
"coordinates",
|
"firing_parameters",
|
||||||
builder -> builder.persistent(BlockPos.CODEC)
|
builder -> builder.persistent(RecordCodecBuilder.create(instance ->
|
||||||
|
instance.group(
|
||||||
|
BlockPos.CODEC.fieldOf("pos").forGetter(FiringParameters.Parameters::pos),
|
||||||
|
Codec.BOOL.fieldOf("is_depressed").forGetter(FiringParameters.Parameters::isDepressed)
|
||||||
|
).apply(instance, FiringParameters.Parameters::new)
|
||||||
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Integer>> ENERGY = register(
|
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Integer>> ENERGY = register(
|
||||||
|
|
|
@ -2,13 +2,13 @@ package com.atsuishio.superbwarfare.entity;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
import com.atsuishio.superbwarfare.client.gui.RangeHelper;
|
import com.atsuishio.superbwarfare.client.gui.RangeHelper;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity;
|
import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||||
import com.atsuishio.superbwarfare.init.ModEntities;
|
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||||
import com.atsuishio.superbwarfare.init.ModItems;
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||||
import com.atsuishio.superbwarfare.item.common.ammo.MortarShell;
|
import com.atsuishio.superbwarfare.item.common.ammo.MortarShell;
|
||||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
|
@ -168,24 +168,29 @@ public class MortarEntity extends VehicleEntity implements GeoEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setTarget(ItemStack stack) {
|
public boolean setTarget(ItemStack stack) {
|
||||||
var tag = NBTTool.getTag(stack);
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
double targetX = tag.getDouble("TargetX");
|
if (parameters == null) return false;
|
||||||
double targetY = tag.getDouble("TargetY");
|
|
||||||
double targetZ = tag.getDouble("TargetZ");
|
var pos = parameters.pos();
|
||||||
|
double targetX = pos.getX();
|
||||||
|
double targetY = pos.getY();
|
||||||
|
double targetZ = pos.getZ();
|
||||||
|
var isDepressed = parameters.isDepressed();
|
||||||
|
|
||||||
|
if (!RangeHelper.canReach(11.4, 0.146, this.getEyePosition(), new Vec3(targetX, targetY, targetZ), 20, 89, isDepressed)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
this.look(new Vec3(targetX, targetY, targetZ));
|
this.look(new Vec3(targetX, targetY, targetZ));
|
||||||
|
|
||||||
double[] angles = new double[2];
|
entityData.set(PITCH, (float) -RangeHelper.calculateAngle(
|
||||||
boolean flag = RangeHelper.canReachTarget(11.4, 0.146, 0.99,
|
11.4, 0.146,
|
||||||
new Vec3(this.getX(), this.getEyeY(), this.getZ()),
|
this.getEyePosition(),
|
||||||
new Vec3(targetX, targetY, targetZ),
|
new Vec3(targetX, targetY, targetZ),
|
||||||
angles);
|
parameters.isDepressed()
|
||||||
|
));
|
||||||
|
|
||||||
if (flag) {
|
return true;
|
||||||
entityData.set(PITCH, (float) -angles[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void look(Vec3 pTarget) {
|
private void look(Vec3 pTarget) {
|
||||||
|
|
|
@ -358,7 +358,7 @@ public class CannonShellEntity extends FastThrowableProjectile implements GeoEnt
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double getDefaultGravity() {
|
protected double getDefaultGravity() {
|
||||||
return 0.05F;
|
return 0.2F;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,6 +6,7 @@ import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
|
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
|
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
|
||||||
import net.neoforged.neoforge.network.PacketDistributor;
|
import net.neoforged.neoforge.network.PacketDistributor;
|
||||||
|
|
||||||
|
@ -32,6 +33,25 @@ public abstract class FastThrowableProjectile extends ThrowableItemProjectile im
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
|
Vec3 vec3 = this.getDeltaMovement();
|
||||||
|
float friction;
|
||||||
|
if (this.isInWater()) {
|
||||||
|
friction = 0.8F;
|
||||||
|
} else {
|
||||||
|
friction = 0.99F;
|
||||||
|
}
|
||||||
|
// 撤销重力影响
|
||||||
|
vec3 = vec3.add(0, this.getGravity(), 0);
|
||||||
|
// 重新计算动量
|
||||||
|
this.setDeltaMovement(vec3.scale(1 / friction));
|
||||||
|
// 重新应用重力
|
||||||
|
this.applyGravity();
|
||||||
|
|
||||||
|
//
|
||||||
|
System.out.println(this.getDeltaMovement());
|
||||||
|
|
||||||
|
// 同步动量
|
||||||
this.syncMotion();
|
this.syncMotion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.atsuishio.superbwarfare.entity.vehicle;
|
package com.atsuishio.superbwarfare.entity.vehicle;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
||||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.projectile.C4Entity;
|
import com.atsuishio.superbwarfare.entity.projectile.C4Entity;
|
||||||
|
@ -147,10 +148,14 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTarget(ItemStack stack) {
|
public void setTarget(ItemStack stack) {
|
||||||
var tag = NBTTool.getTag(stack);
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
int targetX = tag.getInt("TargetX");
|
if (parameters == null) return;
|
||||||
int targetY = tag.getInt("TargetY");
|
|
||||||
int targetZ = tag.getInt("TargetZ");
|
var pos = parameters.pos();
|
||||||
|
int targetX = pos.getX();
|
||||||
|
int targetY = pos.getY();
|
||||||
|
int targetZ = pos.getZ();
|
||||||
|
|
||||||
this.look(new Vec3(targetX, targetY, targetZ));
|
this.look(new Vec3(targetX, targetY, targetZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.atsuishio.superbwarfare.entity.vehicle;
|
package com.atsuishio.superbwarfare.entity.vehicle;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
|
import com.atsuishio.superbwarfare.client.gui.RangeHelper;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
||||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
|
||||||
|
@ -15,16 +17,16 @@ import com.atsuishio.superbwarfare.init.ModSounds;
|
||||||
import com.atsuishio.superbwarfare.init.ModTags;
|
import com.atsuishio.superbwarfare.init.ModTags;
|
||||||
import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem;
|
import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem;
|
||||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||||
import com.atsuishio.superbwarfare.tools.*;
|
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||||
|
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||||
|
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||||
|
import com.atsuishio.superbwarfare.tools.SoundTool;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.protocol.Packet;
|
|
||||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
|
||||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerEntity;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
@ -144,36 +146,28 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, CannonEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTarget(ItemStack stack) {
|
public void setTarget(ItemStack stack) {
|
||||||
var tag = NBTTool.getTag(stack);
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
int targetX = tag.getInt("TargetX");
|
if (parameters == null) return;
|
||||||
int targetY = tag.getInt("TargetY");
|
|
||||||
int targetZ = tag.getInt("TargetZ");
|
var pos = parameters.pos();
|
||||||
|
int targetX = pos.getX();
|
||||||
|
int targetY = pos.getY();
|
||||||
|
int targetZ = pos.getZ();
|
||||||
|
|
||||||
|
if (!RangeHelper.canReach(15, 0.2F, this.getEyePosition(), new Vec3(targetX, targetY, targetZ), -14.9, 85, parameters.isDepressed()))
|
||||||
|
return;
|
||||||
|
|
||||||
this.look(new Vec3(targetX, targetY, targetZ));
|
this.look(new Vec3(targetX, targetY, targetZ));
|
||||||
|
entityData.set(PITCH, (float) -RangeHelper.calculateAngle(15, 0.2F, this.getEyePosition(), new Vec3(targetX, targetY, targetZ), parameters.isDepressed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void look(Vec3 pTarget) {
|
private void look(Vec3 pTarget) {
|
||||||
Vec3 vec3 = this.getEyePosition();
|
Vec3 vec3 = this.getEyePosition();
|
||||||
double d0 = pTarget.x - vec3.x;
|
double d0 = pTarget.x - vec3.x;
|
||||||
double d1 = pTarget.y - vec3.y;
|
|
||||||
double d2 = pTarget.z - vec3.z;
|
double d2 = pTarget.z - vec3.z;
|
||||||
double d3 = Math.sqrt(d0 * d0 + d2 * d2);
|
|
||||||
double distance = pTarget.distanceTo(vec3);
|
|
||||||
entityData.set(YAW, Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F));
|
entityData.set(YAW, Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F));
|
||||||
entityData.set(PITCH, Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875))) - (float) (distance * 0.008f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO addEntityPacket
|
|
||||||
@Override
|
|
||||||
public @NotNull Packet<ClientGamePacketListener> getAddEntityPacket(@NotNull ServerEntity entity) {
|
|
||||||
return super.getAddEntityPacket(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public Packet<ClientGamePacketListener> getAddEntityPacket() {
|
|
||||||
// return NetworkHooks.getEntitySpawningPacket(this);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void positionRider(@NotNull Entity passenger, @NotNull MoveFunction callback) {
|
public void positionRider(@NotNull Entity passenger, @NotNull MoveFunction callback) {
|
||||||
if (!this.hasPassenger(passenger)) {
|
if (!this.hasPassenger(passenger)) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.atsuishio.superbwarfare.entity.vehicle;
|
package com.atsuishio.superbwarfare.entity.vehicle;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
|
import com.atsuishio.superbwarfare.client.gui.RangeHelper;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
|
||||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
|
||||||
|
@ -15,7 +17,10 @@ import com.atsuishio.superbwarfare.init.ModSounds;
|
||||||
import com.atsuishio.superbwarfare.init.ModTags;
|
import com.atsuishio.superbwarfare.init.ModTags;
|
||||||
import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem;
|
import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem;
|
||||||
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
|
||||||
import com.atsuishio.superbwarfare.tools.*;
|
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||||
|
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||||
|
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||||
|
import com.atsuishio.superbwarfare.tools.SoundTool;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
|
@ -147,22 +152,26 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, CannonEnt
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTarget(ItemStack stack) {
|
public void setTarget(ItemStack stack) {
|
||||||
var tag = NBTTool.getTag(stack);
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
int targetX = tag.getInt("TargetX");
|
if (parameters == null) return;
|
||||||
int targetY = tag.getInt("TargetY");
|
|
||||||
int targetZ = tag.getInt("TargetZ");
|
var pos = parameters.pos();
|
||||||
|
int targetX = pos.getX();
|
||||||
|
int targetY = pos.getY();
|
||||||
|
int targetZ = pos.getZ();
|
||||||
|
|
||||||
|
if (!RangeHelper.canReach(15, 0.2F, this.getEyePosition(), new Vec3(targetX, targetY, targetZ), -2.7, 30, parameters.isDepressed()))
|
||||||
|
return;
|
||||||
|
|
||||||
this.look(new Vec3(targetX, targetY, targetZ));
|
this.look(new Vec3(targetX, targetY, targetZ));
|
||||||
|
entityData.set(PITCH, (float) -RangeHelper.calculateAngle(15, 0.2F, this.getEyePosition(), new Vec3(targetX, targetY, targetZ), parameters.isDepressed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void look(Vec3 pTarget) {
|
private void look(Vec3 pTarget) {
|
||||||
Vec3 vec3 = this.getEyePosition();
|
Vec3 vec3 = this.getEyePosition();
|
||||||
double d0 = pTarget.x - vec3.x;
|
double d0 = pTarget.x - vec3.x;
|
||||||
double d1 = pTarget.y - vec3.y;
|
|
||||||
double d2 = pTarget.z - vec3.z;
|
double d2 = pTarget.z - vec3.z;
|
||||||
double d3 = Math.sqrt(d0 * d0 + d2 * d2);
|
|
||||||
double distance = pTarget.distanceTo(vec3);
|
|
||||||
entityData.set(YAW, Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F));
|
entityData.set(YAW, Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F));
|
||||||
entityData.set(PITCH, Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875))) - (float) (distance * 0.008f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,18 +4,25 @@ import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.InteractionResultHolder;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.TooltipFlag;
|
import net.minecraft.world.item.TooltipFlag;
|
||||||
import net.minecraft.world.item.context.UseOnContext;
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FiringParameters extends Item {
|
public class FiringParameters extends Item {
|
||||||
|
|
||||||
|
public record Parameters(BlockPos pos, boolean isDepressed) {
|
||||||
|
}
|
||||||
|
|
||||||
public FiringParameters() {
|
public FiringParameters() {
|
||||||
super(new Properties().stacksTo(1));
|
super(new Properties().stacksTo(1));
|
||||||
}
|
}
|
||||||
|
@ -29,15 +36,39 @@ public class FiringParameters extends Item {
|
||||||
BlockPos pos = pContext.getClickedPos();
|
BlockPos pos = pContext.getClickedPos();
|
||||||
pos = pos.relative(pContext.getClickedFace());
|
pos = pos.relative(pContext.getClickedFace());
|
||||||
|
|
||||||
stack.set(ModDataComponents.BLOCK_POS, pos);
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
|
var isDepressed = parameters != null && parameters.isDepressed();
|
||||||
|
|
||||||
|
stack.set(ModDataComponents.FIRING_PARAMETERS, new Parameters(pos, isDepressed));
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendHoverText(ItemStack stack, @NotNull TooltipContext context, @NotNull List<Component> tooltipComponents, @NotNull TooltipFlag tooltipFlag) {
|
@ParametersAreNonnullByDefault
|
||||||
var pos = stack.get(ModDataComponents.BLOCK_POS);
|
public @NotNull InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) {
|
||||||
if (pos == null) return;
|
if (!player.isCrouching()) return InteractionResultHolder.pass(player.getItemInHand(usedHand));
|
||||||
|
|
||||||
|
var stack = player.getItemInHand(usedHand);
|
||||||
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
|
if (parameters == null) return InteractionResultHolder.fail(stack);
|
||||||
|
|
||||||
|
var isDepressed = !parameters.isDepressed();
|
||||||
|
stack.set(ModDataComponents.FIRING_PARAMETERS, new Parameters(parameters.pos(), isDepressed));
|
||||||
|
player.displayClientMessage(Component.translatable(
|
||||||
|
isDepressed
|
||||||
|
? "tips.superbwarfare.mortar.target_pos.depressed_trajectory"
|
||||||
|
: "tips.superbwarfare.mortar.target_pos.lofted_trajectory"
|
||||||
|
).withStyle(ChatFormatting.GREEN), true);
|
||||||
|
|
||||||
|
return InteractionResultHolder.success(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendHoverText(ItemStack stack, @NotNull TooltipContext context, @NotNull List<Component> tooltipComponents, @NotNull TooltipFlag tooltipFlag) {
|
||||||
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
|
if (parameters == null) return;
|
||||||
|
|
||||||
|
var pos = parameters.pos();
|
||||||
tooltipComponents.add(Component.translatable("tips.superbwarfare.mortar.target_pos")
|
tooltipComponents.add(Component.translatable("tips.superbwarfare.mortar.target_pos")
|
||||||
.withStyle(ChatFormatting.GRAY)
|
.withStyle(ChatFormatting.GRAY)
|
||||||
.append(Component.literal("["
|
.append(Component.literal("["
|
||||||
|
@ -46,5 +77,11 @@ public class FiringParameters extends Item {
|
||||||
+ pos.getZ() + "]")
|
+ pos.getZ() + "]")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
tooltipComponents.add(Component.translatable(
|
||||||
|
parameters.isDepressed
|
||||||
|
? "tips.superbwarfare.mortar.target_pos.depressed_trajectory"
|
||||||
|
: "tips.superbwarfare.mortar.target_pos.lofted_trajectory"
|
||||||
|
).withStyle(ChatFormatting.GRAY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.init.ModBlocks;
|
import com.atsuishio.superbwarfare.init.ModBlocks;
|
||||||
import com.atsuishio.superbwarfare.init.ModItems;
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
import com.atsuishio.superbwarfare.init.ModMenuTypes;
|
import com.atsuishio.superbwarfare.init.ModMenuTypes;
|
||||||
|
import com.atsuishio.superbwarfare.item.FiringParameters;
|
||||||
import com.atsuishio.superbwarfare.network.dataslot.ContainerEnergyData;
|
import com.atsuishio.superbwarfare.network.dataslot.ContainerEnergyData;
|
||||||
import com.atsuishio.superbwarfare.network.dataslot.SimpleEnergyData;
|
import com.atsuishio.superbwarfare.network.dataslot.SimpleEnergyData;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -80,7 +81,10 @@ public class FuMO25Menu extends EnergyMenu {
|
||||||
ItemStack stack = this.container.getItem(0);
|
ItemStack stack = this.container.getItem(0);
|
||||||
if (stack.isEmpty()) return;
|
if (stack.isEmpty()) return;
|
||||||
|
|
||||||
stack.set(ModDataComponents.BLOCK_POS, new BlockPos(this.posX, this.posY, this.posZ));
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
|
var isDepressed = parameters != null && parameters.isDepressed();
|
||||||
|
|
||||||
|
stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos(this.posX, this.posY, this.posZ), isDepressed));
|
||||||
|
|
||||||
this.resetPos();
|
this.resetPos();
|
||||||
this.container.setChanged();
|
this.container.setChanged();
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package com.atsuishio.superbwarfare.network.message.send;
|
package com.atsuishio.superbwarfare.network.message.send;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
||||||
import com.atsuishio.superbwarfare.init.ModItems;
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
|
import com.atsuishio.superbwarfare.item.FiringParameters;
|
||||||
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
|
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
|
||||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||||
import com.atsuishio.superbwarfare.tools.SeekTool;
|
import com.atsuishio.superbwarfare.tools.SeekTool;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.codec.ByteBufCodecs;
|
import net.minecraft.network.codec.ByteBufCodecs;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
@ -21,6 +24,8 @@ import net.minecraft.world.phys.Vec3;
|
||||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public record DroneFireMessage(int msgType) implements CustomPacketPayload {
|
public record DroneFireMessage(int msgType) implements CustomPacketPayload {
|
||||||
public static final Type<DroneFireMessage> TYPE = new Type<>(Mod.loc("drone_fire"));
|
public static final Type<DroneFireMessage> TYPE = new Type<>(Mod.loc("drone_fire"));
|
||||||
|
|
||||||
|
@ -55,24 +60,23 @@ public record DroneFireMessage(int msgType) implements CustomPacketPayload {
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack offStack = player.getOffhandItem();
|
ItemStack offStack = player.getOffhandItem();
|
||||||
var offTag = NBTTool.getTag(offStack);
|
var parameters = offStack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
|
var isDepressed = parameters != null && parameters.isDepressed();
|
||||||
|
|
||||||
if (lookAtEntity) {
|
if (lookAtEntity) {
|
||||||
offTag.putDouble("TargetX", lookingEntity.getX());
|
offStack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(lookingEntity.blockPosition(), isDepressed));
|
||||||
offTag.putDouble("TargetY", lookingEntity.getY());
|
|
||||||
offTag.putDouble("TargetZ", lookingEntity.getZ());
|
|
||||||
} else {
|
} else {
|
||||||
offTag.putDouble("TargetX", hitPos.x());
|
offStack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z), isDepressed));
|
||||||
offTag.putDouble("TargetY", hitPos.y());
|
|
||||||
offTag.putDouble("TargetZ", hitPos.z());
|
|
||||||
}
|
}
|
||||||
NBTTool.saveTag(offStack, offTag);
|
|
||||||
|
var pos = Objects.requireNonNull(offStack.get(ModDataComponents.FIRING_PARAMETERS)).pos();
|
||||||
|
|
||||||
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos")
|
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos")
|
||||||
.withStyle(ChatFormatting.GRAY)
|
.withStyle(ChatFormatting.GRAY)
|
||||||
.append(Component.literal("["
|
.append(Component.literal("["
|
||||||
+ offTag.getInt("TargetX")
|
+ pos.getX()
|
||||||
+ "," + offTag.getInt("TargetY")
|
+ "," + pos.getY()
|
||||||
+ "," + offTag.getInt("TargetZ")
|
+ "," + pos.getZ()
|
||||||
+ "]")), true);
|
+ "]")), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.atsuishio.superbwarfare.network.message.send;
|
package com.atsuishio.superbwarfare.network.message.send;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
|
import com.atsuishio.superbwarfare.item.FiringParameters;
|
||||||
import com.atsuishio.superbwarfare.tools.TraceTool;
|
import com.atsuishio.superbwarfare.tools.TraceTool;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.codec.ByteBufCodecs;
|
import net.minecraft.network.codec.ByteBufCodecs;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
@ -18,6 +20,8 @@ import net.minecraft.world.phys.Vec3;
|
||||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public record SetFiringParametersMessage(int msgType) implements CustomPacketPayload {
|
public record SetFiringParametersMessage(int msgType) implements CustomPacketPayload {
|
||||||
public static final Type<SetFiringParametersMessage> TYPE = new Type<>(Mod.loc("set_firing_parameters"));
|
public static final Type<SetFiringParametersMessage> TYPE = new Type<>(Mod.loc("set_firing_parameters"));
|
||||||
|
|
||||||
|
@ -41,25 +45,23 @@ public record SetFiringParametersMessage(int msgType) implements CustomPacketPay
|
||||||
lookAtEntity = true;
|
lookAtEntity = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tag = NBTTool.getTag(stack);
|
var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS);
|
||||||
|
var isDepressed = parameters != null && parameters.isDepressed();
|
||||||
|
|
||||||
if (lookAtEntity) {
|
if (lookAtEntity) {
|
||||||
tag.putDouble("TargetX", lookingEntity.getX());
|
stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(lookingEntity.blockPosition(), isDepressed));
|
||||||
tag.putDouble("TargetY", lookingEntity.getY());
|
|
||||||
tag.putDouble("TargetZ", lookingEntity.getZ());
|
|
||||||
} else {
|
} else {
|
||||||
tag.putDouble("TargetX", hitPos.x());
|
stack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z), isDepressed));
|
||||||
tag.putDouble("TargetY", hitPos.y());
|
|
||||||
tag.putDouble("TargetZ", hitPos.z());
|
|
||||||
}
|
}
|
||||||
NBTTool.saveTag(stack, tag);
|
|
||||||
|
var pos = Objects.requireNonNull(stack.get(ModDataComponents.FIRING_PARAMETERS)).pos();
|
||||||
|
|
||||||
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos")
|
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos")
|
||||||
.withStyle(ChatFormatting.GRAY)
|
.withStyle(ChatFormatting.GRAY)
|
||||||
.append(Component.literal("[" + tag.getInt("TargetX")
|
.append(Component.literal("[" + pos.getX()
|
||||||
+ "," + tag.getInt("TargetY")
|
+ "," + pos.getY()
|
||||||
+ "," + tag.getInt("TargetZ")
|
+ "," + pos.getZ()
|
||||||
+ "]")), true);
|
+ "]")), true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -502,6 +502,8 @@
|
||||||
"tips.superbwarfare.mortar.yaw": "Yaw: ",
|
"tips.superbwarfare.mortar.yaw": "Yaw: ",
|
||||||
"tips.superbwarfare.mortar.pitch": "Pitch: ",
|
"tips.superbwarfare.mortar.pitch": "Pitch: ",
|
||||||
"tips.superbwarfare.mortar.target_pos": "Target Position: ",
|
"tips.superbwarfare.mortar.target_pos": "Target Position: ",
|
||||||
|
"tips.superbwarfare.mortar.target_pos.depressed_trajectory": "Depressed Trajectory",
|
||||||
|
"tips.superbwarfare.mortar.target_pos.lofted_trajectory": "Lofted Trajectory",
|
||||||
"tips.superbwarfare.mortar.warn": "The mortar cannot aim at this position",
|
"tips.superbwarfare.mortar.warn": "The mortar cannot aim at this position",
|
||||||
|
|
||||||
"container.superbwarfare.reforging_table": "Gun Reforge Table",
|
"container.superbwarfare.reforging_table": "Gun Reforge Table",
|
||||||
|
|
|
@ -500,6 +500,8 @@
|
||||||
"tips.superbwarfare.mortar.yaw": "水平朝向:",
|
"tips.superbwarfare.mortar.yaw": "水平朝向:",
|
||||||
"tips.superbwarfare.mortar.pitch": "俯仰角度:",
|
"tips.superbwarfare.mortar.pitch": "俯仰角度:",
|
||||||
"tips.superbwarfare.mortar.target_pos": "目标坐标:",
|
"tips.superbwarfare.mortar.target_pos": "目标坐标:",
|
||||||
|
"tips.superbwarfare.mortar.target_pos.depressed_trajectory": "低伸弹道",
|
||||||
|
"tips.superbwarfare.mortar.target_pos.lofted_trajectory": "传统弹道",
|
||||||
"tips.superbwarfare.mortar.warn": "迫击炮无法瞄准该位置",
|
"tips.superbwarfare.mortar.warn": "迫击炮无法瞄准该位置",
|
||||||
|
|
||||||
"container.superbwarfare.reforging_table": "枪械重铸台",
|
"container.superbwarfare.reforging_table": "枪械重铸台",
|
||||||
|
|
Loading…
Add table
Reference in a new issue