优化鼠标操控

This commit is contained in:
Atsuishio 2025-06-15 11:39:17 +08:00 committed by Light_Quanta
parent d130cd11c2
commit b6ddd1557f
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
3 changed files with 73 additions and 11 deletions

View file

@ -321,10 +321,10 @@ public class VehicleConfig {
AH_6_CANNON_DAMAGE = builder.defineInRange("ah_6_cannon_damage", 25, 1, 10000000); AH_6_CANNON_DAMAGE = builder.defineInRange("ah_6_cannon_damage", 25, 1, 10000000);
builder.comment("The cannon explosion damage of AH-6"); builder.comment("The cannon explosion damage of AH-6");
AH_6_CANNON_EXPLOSION_DAMAGE = builder.defineInRange("ah_6_cannon_explosion_damage", 13, 1, 10000000); AH_6_CANNON_EXPLOSION_DAMAGE = builder.defineInRange("ah_6_cannon_explosion_damage", 20, 1, 10000000);
builder.comment("The cannon explosion damage of AH-6"); builder.comment("The cannon explosion damage of AH-6");
AH_6_CANNON_EXPLOSION_RADIUS = builder.defineInRange("ah_6_cannon_explosion_damage", 4d, 1, 10000000); AH_6_CANNON_EXPLOSION_RADIUS = builder.defineInRange("ah_6_cannon_explosion_damage", 8d, 1, 10000000);
builder.comment("The rocket damage of AH-6"); builder.comment("The rocket damage of AH-6");
AH_6_ROCKET_DAMAGE = builder.defineInRange("ah_6_rocket_damage", 80, 1, 10000000); AH_6_ROCKET_DAMAGE = builder.defineInRange("ah_6_rocket_damage", 80, 1, 10000000);

View file

@ -6,8 +6,10 @@ import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity; import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition; import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition;
import com.atsuishio.superbwarfare.event.ClientMouseHandler;
import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.tools.CameraTool;
import com.atsuishio.superbwarfare.tools.CustomExplosion; import com.atsuishio.superbwarfare.tools.CustomExplosion;
import com.atsuishio.superbwarfare.tools.ParticleTool; import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.mojang.math.Axis; import com.mojang.math.Axis;
@ -32,6 +34,8 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.event.EventHooks;
@ -48,11 +52,18 @@ import software.bernie.geckolib.util.GeckoLibUtil;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import static com.atsuishio.superbwarfare.event.ClientEventHandler.isFreeCam;
import static com.atsuishio.superbwarfare.event.ClientMouseHandler.freeCameraPitch;
import static com.atsuishio.superbwarfare.event.ClientMouseHandler.freeCameraYaw;
public class Tom6Entity extends MobileVehicleEntity implements GeoEntity { public class Tom6Entity extends MobileVehicleEntity implements GeoEntity {
public static final EntityDataAccessor<Boolean> MELON = SynchedEntityData.defineId(Tom6Entity.class, EntityDataSerializers.BOOLEAN); public static final EntityDataAccessor<Boolean> MELON = SynchedEntityData.defineId(Tom6Entity.class, EntityDataSerializers.BOOLEAN);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private float yRotSync; private float yRotSync;
public float delta_xo;
public float delta_yo;
public float delta_x; public float delta_x;
public float delta_y; public float delta_y;
@ -107,6 +118,8 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity {
@Override @Override
public void baseTick() { public void baseTick() {
delta_xo = delta_x;
delta_yo = delta_y;
super.baseTick(); super.baseTick();
delta_x = entityData.get(MOUSE_SPEED_Y); delta_x = entityData.get(MOUSE_SPEED_Y);
@ -371,4 +384,41 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity {
public @Nullable ResourceLocation getVehicleItemIcon() { public @Nullable ResourceLocation getVehicleItemIcon() {
return Mod.loc("textures/gui/vehicle/type/aircraft.png"); return Mod.loc("textures/gui/vehicle/type/aircraft.png");
} }
public Matrix4f getClientVehicleTransform(float ticks) {
Matrix4f transform = new Matrix4f();
transform.translate((float) Mth.lerp(ticks, xo, getX()), (float) Mth.lerp(ticks, yo + 0.5f, getY() + 0.5f), (float) Mth.lerp(ticks, zo, getZ()));
transform.rotate(Axis.YP.rotationDegrees((float) (-Mth.lerp(ticks, yRotO, getYRot()) + freeCameraYaw)));
transform.rotate(Axis.XP.rotationDegrees((float) (Mth.lerp(ticks, xRotO, getXRot()) + freeCameraPitch)));
transform.rotate(Axis.ZP.rotationDegrees(Mth.lerp(ticks, prevRoll, getRoll())));
return transform;
}
@OnlyIn(Dist.CLIENT)
@Override
public @Nullable Vec2 getCameraRotation(float partialTicks, Player player, boolean zoom, boolean isFirstPerson) {
if (isFreeCam(player) && this.getSeatIndex(player) == 0 && Mth.abs((float) (freeCameraYaw * freeCameraPitch)) > 0.01) {
return new Vec2((float) (getYaw(partialTicks) - 0.5f * Mth.lerp(partialTicks, delta_yo, delta_y) - freeCameraYaw), (float) (getPitch(partialTicks) - 0.5f * Mth.lerp(partialTicks, delta_xo, delta_x) + freeCameraPitch));
}
return super.getCameraRotation(partialTicks, player, false, false);
}
@OnlyIn(Dist.CLIENT)
@Override
public Vec3 getCameraPosition(float partialTicks, Player player, boolean zoom, boolean isFirstPerson) {
if (isFreeCam(player) && this.getSeatIndex(player) == 0 && Mth.abs((float) (freeCameraYaw * freeCameraPitch)) > 0.01) {
Matrix4f transform = getClientVehicleTransform(partialTicks);
Vector4f maxCameraPosition = transformPosition(transform, 0, 2.5f, -6 - (float) ClientMouseHandler.custom3pDistanceLerp);
Vec3 finalPos = CameraTool.getMaxZoom(transform, maxCameraPosition);
if (isFirstPerson) {
return new Vec3(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ()));
} else {
return finalPos;
}
}
return super.getCameraPosition(partialTicks, player, false, false);
}
} }

View file

@ -6,6 +6,7 @@ import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity; import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.AirEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.AirEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity;
import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModMobEffects; import com.atsuishio.superbwarfare.init.ModMobEffects;
import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.GunItem;
@ -61,8 +62,10 @@ public class ClientMouseHandler {
if (player == null) return; if (player == null) return;
if (notInGame()) { if (notInGame()) {
PacketDistributor.sendToServer(new MouseMoveMessage(0, 0)); speedX = 0;
return; speedY = 0;
lerpSpeedX = 0;
lerpSpeedY = 0;
} }
posO = posN; posO = posN;
@ -90,7 +93,6 @@ public class ClientMouseHandler {
} }
if (player.getVehicle() instanceof VehicleEntity vehicle && player == vehicle.getFirstPassenger()) { if (player.getVehicle() instanceof VehicleEntity vehicle && player == vehicle.getFirstPassenger()) {
if (notInGame()) { if (notInGame()) {
PacketDistributor.sendToServer(new MouseMoveMessage(0, 0)); PacketDistributor.sendToServer(new MouseMoveMessage(0, 0));
return; return;
@ -140,6 +142,12 @@ public class ClientMouseHandler {
LocalPlayer player = Minecraft.getInstance().player; LocalPlayer player = Minecraft.getInstance().player;
if (player == null) return; if (player == null) return;
if (notInGame()) {
freeCameraYaw = 0;
freeCameraPitch = 0;
return;
}
float times = 0.6f * (float) Math.min(Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(), 0.8); float times = 0.6f * (float) Math.min(Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(), 0.8);
freeCameraYaw -= 0.4f * times * lerpSpeedX; freeCameraYaw -= 0.4f * times * lerpSpeedX;
@ -162,11 +170,6 @@ public class ClientMouseHandler {
freeCameraPitch += 360; freeCameraPitch += 360;
} }
if (player.getVehicle() instanceof VehicleEntity vehicle && player == vehicle.getFirstPassenger() && vehicle instanceof AirEntity) {
player.setYRot(player.getVehicle().getYRot());
player.setYHeadRot(player.getYRot());
}
custom3pDistanceLerp = Mth.lerp(times, custom3pDistanceLerp, custom3pDistance); custom3pDistanceLerp = Mth.lerp(times, custom3pDistanceLerp, custom3pDistance);
} }
@ -219,10 +222,19 @@ public class ClientMouseHandler {
return 0; return 0;
} }
if (player.getVehicle() instanceof VehicleEntity vehicle) { if (player.getVehicle() instanceof VehicleEntity vehicle && vehicle instanceof WeaponVehicleEntity weaponVehicle && weaponVehicle.banHand(player)) {
return vehicle.getSensitivity(original, ClientEventHandler.zoomVehicle, vehicle.getSeatIndex(player), vehicle.onGround()); return vehicle.getSensitivity(original, ClientEventHandler.zoomVehicle, vehicle.getSeatIndex(player), vehicle.onGround());
} }
if (stack.getItem() instanceof GunItem) {
var data = GunData.from(stack);
float customSens = data.sensitivity.get();
if (!player.getMainHandItem().isEmpty() && mc.options.getCameraType() == CameraType.FIRST_PERSON) {
return original / Math.max((1 + (0.2 * (data.zoom() - (0.3 * customSens)) * ClientEventHandler.zoomTime)), 0.1);
}
}
return original; return original;
} }
} }