优化无人机标点(为什么实体服务端视角向量和客户端视角向量有微妙偏差(恼))

This commit is contained in:
Atsuishio 2025-07-10 20:30:04 +08:00 committed by Light_Quanta
parent 95c78585a8
commit bfaad88cd0
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 55 additions and 58 deletions

View file

@ -5,6 +5,7 @@ import com.atsuishio.superbwarfare.compat.clothconfig.ClothConfigHelper;
import com.atsuishio.superbwarfare.config.client.ReloadConfig;
import com.atsuishio.superbwarfare.data.gun.FireMode;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
import com.atsuishio.superbwarfare.entity.vehicle.MortarEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
@ -16,6 +17,7 @@ import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.item.ItemScreenProvider;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.network.message.send.*;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.NBTTool;
import com.atsuishio.superbwarfare.tools.SeekTool;
import com.atsuishio.superbwarfare.tools.TraceTool;
@ -32,7 +34,9 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
@ -136,7 +140,7 @@ public class ClickHandler {
event.setCanceled(true);
}
if (stack.is(ModItems.MONITOR.get()) && player.getOffhandItem().is(ModItems.ARTILLERY_INDICATOR.get())) {
PacketDistributor.sendToServer(DroneFireMessage.INSTANCE);
droneLeftClick(stack, player);
event.setCanceled(true);
}
}
@ -395,7 +399,7 @@ public class ClickHandler {
if (player.getOffhandItem().is(ModItems.ARTILLERY_INDICATOR.get())) {
ClientEventHandler.holdFire = true;
} else {
PacketDistributor.sendToServer(DroneFireMessage.INSTANCE);
droneLeftClick(stack, player);
}
}
@ -537,4 +541,30 @@ public class ClickHandler {
}
PacketDistributor.sendToServer(PlayerStopRidingMessage.INSTANCE);
}
public static void droneLeftClick(ItemStack stack, Player player) {
var tag = NBTTool.getTag(stack);
if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) {
DroneEntity drone = EntityFindUtil.findDrone(player.level(), tag.getString("LinkedDrone"));
if (drone != null) {
boolean lookAtEntity = false;
Entity lookingEntity = SeekTool.seekLivingEntity(drone, drone.level(), 512, 2 / droneFovLerp);
BlockHitResult result = player.level().clip(new ClipContext(drone.getEyePosition(), drone.getEyePosition().add(drone.getLookAngle().scale(512)),
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, drone));
Vec3 pos = result.getLocation();
if (lookingEntity != null) {
lookAtEntity = true;
}
if (lookAtEntity) {
pos = lookingEntity.position();
}
PacketDistributor.sendToServer(new DroneFireMessage(pos.toVector3f()));
}
}
}
}

View file

@ -1022,7 +1022,7 @@ public class ClientEventHandler {
DroneEntity drone = EntityFindUtil.findDrone(entity.level(), tag.getString("LinkedDrone"));
if (drone != null) {
event.setRoll(drone.getRoll((float) event.getPartialTick()) * (1 - (drone.getPitch((float) event.getPartialTick()) / 90)));
cameraRoll = drone.getRoll((float) event.getPartialTick()) * (1 - (drone.getPitch((float) event.getPartialTick()) / 90));
}
}

View file

@ -53,7 +53,7 @@ public class NetworkRegistry {
playToServer(FireModeMessage.TYPE, FireModeMessage.STREAM_CODEC, (message1, context1) -> FireModeMessage.handler(context1));
playToServer(PlayerStopRidingMessage.TYPE, PlayerStopRidingMessage.STREAM_CODEC, (message1, context1) -> PlayerStopRidingMessage.handler(context1));
playToServer(ZoomMessage.TYPE, ZoomMessage.STREAM_CODEC, ZoomMessage::handler);
playToServer(DroneFireMessage.TYPE, DroneFireMessage.STREAM_CODEC, (message1, context1) -> DroneFireMessage.handler(context1));
playToServer(DroneFireMessage.TYPE, DroneFireMessage.STREAM_CODEC, DroneFireMessage::handler);
playToServer(SetFiringParametersMessage.TYPE, SetFiringParametersMessage.STREAM_CODEC, (message, context) -> SetFiringParametersMessage.handler(context));
playToServer(ArtilleryIndicatorFireMessage.TYPE, ArtilleryIndicatorFireMessage.STREAM_CODEC, (message, context) -> ArtilleryIndicatorFireMessage.handler(context));
playToServer(SensitivityMessage.TYPE, SensitivityMessage.STREAM_CODEC, SensitivityMessage::handler);

View file

@ -11,7 +11,6 @@ import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.item.FiringParameters;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.NBTTool;
import com.atsuishio.superbwarfare.tools.SeekTool;
import com.atsuishio.superbwarfare.tools.SoundTool;
import io.netty.buffer.ByteBuf;
import net.minecraft.ChatFormatting;
@ -19,27 +18,29 @@ import net.minecraft.core.BlockPos;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import org.jetbrains.annotations.NotNull;
import org.joml.Vector3f;
import static com.atsuishio.superbwarfare.item.ArtilleryIndicator.TAG_CANNON;
public enum DroneFireMessage implements CustomPacketPayload {
INSTANCE;
public record DroneFireMessage(Vector3f pos) implements CustomPacketPayload {
public static final Type<DroneFireMessage> TYPE = new Type<>(Mod.loc("drone_fire"));
public static final StreamCodec<ByteBuf, DroneFireMessage> STREAM_CODEC = StreamCodec.unit(INSTANCE);
public static final StreamCodec<ByteBuf, DroneFireMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VECTOR3F,
DroneFireMessage::pos,
DroneFireMessage::new
);
public static void handler(final IPayloadContext context) {
public static void handler(DroneFireMessage message, final IPayloadContext context) {
Player player = context.player();
ItemStack stack = player.getMainHandItem();
var mainTag = NBTTool.getTag(stack);
@ -48,42 +49,25 @@ public enum DroneFireMessage implements CustomPacketPayload {
DroneEntity drone = EntityFindUtil.findDrone(player.level(), mainTag.getString("LinkedDrone"));
if (drone != null) {
if (player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get()) || player.getOffhandItem().is(ModItems.ARTILLERY_INDICATOR.get())) {
boolean lookAtEntity = false;
Entity lookingEntity = SeekTool.seekLivingEntity(drone, drone.level(), 512, 2);
BlockHitResult result = player.level().clip(new ClipContext(drone.getEyePosition(), drone.getEyePosition().add(drone.getLookAngle().scale(512)),
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, drone));
Vec3 hitPos = result.getLocation();
if (lookingEntity != null) {
lookAtEntity = true;
}
ItemStack offStack = player.getOffhandItem();
var parameters = offStack.get(ModDataComponents.FIRING_PARAMETERS);
var isDepressed = parameters != null && parameters.isDepressed();
BlockPos pos;
if (lookAtEntity) {
pos = lookingEntity.blockPosition();
} else {
pos = new BlockPos((int) hitPos.x, (int) hitPos.y, (int) hitPos.z);
var isDepressed = false;
if (parameters != null) {
isDepressed = parameters.isDepressed();
}
offStack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(pos, isDepressed));
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos")
.withStyle(ChatFormatting.GRAY)
.append(Component.literal("["
+ pos.getX()
+ "," + pos.getY()
+ "," + pos.getZ()
+ "]")), true);
offStack.set(ModDataComponents.FIRING_PARAMETERS, new FiringParameters.Parameters(new BlockPos((int) message.pos.x, (int) message.pos.y, (int) message.pos.z), isDepressed));
player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos").withStyle(ChatFormatting.GRAY)
.append(Component.literal("[" + message.pos.x()
+ "," + message.pos.y()
+ "," + message.pos.z() + "]")), true);
SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_IN.get(), 2, 1);
if (offStack.is(ModItems.ARTILLERY_INDICATOR.get())) {
var offTag = NBTTool.getTag(offStack);
ListTag tags = offTag.getList(TAG_CANNON, Tag.TAG_COMPOUND);
ListTag tags = NBTTool.getTag(offStack).getList(TAG_CANNON, Tag.TAG_COMPOUND);
for (int i = 0; i < tags.size(); i++) {
var tag = tags.getCompound(i);
Entity entity = EntityFindUtil.findEntity(player.level(), tag.getString("UUID"));

View file

@ -1,21 +1,17 @@
package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.LandArmorEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModMobEffects;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.EventPriority;
@ -96,19 +92,6 @@ public class VectorUtil {
roll = -r * vehicle.getRoll((float) event.getPartialTick()) + r2 * vehicle.getViewXRot((float) event.getPartialTick());
}
Minecraft mc = Minecraft.getInstance();
LocalPlayer player = mc.player;
if (player != null) {
ItemStack stack = player.getMainHandItem();
var tag = NBTTool.getTag(stack);
if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) {
DroneEntity drone = EntityFindUtil.findDrone(player.level(), tag.getString("LinkedDrone"));
if (drone != null) {
roll = event.getRoll();
}
}
}
PoseStack poseStack = new PoseStack();
poseStack.mulPose(Axis.ZP.rotationDegrees(roll));
poseStack.mulPose(Axis.XP.rotationDegrees(event.getPitch()));