添加载具第三人称防穿模功能,添加调整相机距离的功能

This commit is contained in:
Atsuishio 2025-06-05 14:21:53 +08:00 committed by Light_Quanta
parent 343869a55b
commit f6df1b9529
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 82 additions and 16 deletions

View file

@ -11,6 +11,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
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.entity.vehicle.base.WeaponVehicleEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.event.ClientMouseHandler;
import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.network.message.send.*; import com.atsuishio.superbwarfare.network.message.send.*;
@ -151,6 +152,13 @@ public class ClickHandler {
double scroll = event.getScrollDeltaY(); double scroll = event.getScrollDeltaY();
// 按下自由视角键时为具有自由视角功能的载具调整相机距离
if (player.getVehicle() instanceof VehicleEntity vehicle && vehicle.allowFreeCam() && player == vehicle.getFirstPassenger() && ModKeyMappings.FREE_CAMERA.isDown()) {
ClientMouseHandler.custom3pDistance = Mth.clamp(ClientMouseHandler.custom3pDistance - event.getScrollDeltaY(), -3, 8);
event.setCanceled(true);
return;
}
// 未按下shift时为有武器的载具切换武器 // 未按下shift时为有武器的载具切换武器
if (!Screen.hasShiftDown() if (!Screen.hasShiftDown()
&& player.getVehicle() instanceof VehicleEntity vehicle && player.getVehicle() instanceof VehicleEntity vehicle

View file

@ -6,6 +6,7 @@ import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.vehicle.base.*; import com.atsuishio.superbwarfare.entity.vehicle.base.*;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.*; import com.atsuishio.superbwarfare.entity.vehicle.weapon.*;
import com.atsuishio.superbwarfare.event.ClientMouseHandler;
import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModParticleTypes; import com.atsuishio.superbwarfare.init.ModParticleTypes;
@ -1061,13 +1062,13 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
if (this.getSeatIndex(player) == 0) { if (this.getSeatIndex(player) == 0) {
Matrix4f transform = getClientVehicleTransform(partialTicks); Matrix4f transform = getClientVehicleTransform(partialTicks);
Vector4f maxCameraPosition = transformPosition(transform, 0, 4, -14 - (float) ClientMouseHandler.custom3pDistanceLerp);
Vector4f worldPosition = transformPosition(transform, 0f, 4, -14); Vec3 finalPos = CameraTool.getMaxZoom(transform, maxCameraPosition);
if (isFirstPerson) { 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())); 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 { } else {
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z); return finalPos;
} }
} }
return super.getCameraPosition(partialTicks, player, false, false); return super.getCameraPosition(partialTicks, player, false, false);

View file

@ -12,13 +12,11 @@ import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.SmallCannonShellWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.SmallCannonShellWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon;
import com.atsuishio.superbwarfare.event.ClientMouseHandler;
import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModDamageTypes;
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.tools.Ammo; 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.mojang.math.Axis; import com.mojang.math.Axis;
import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.Pair;
import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.ParticleTypes;
@ -676,6 +674,21 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
return seatIndex == 0 ? 0 : original; return seatIndex == 0 ? 0 : original;
} }
@Override
public double getMouseSensitivity() {
return 0.15;
}
@Override
public double getMouseSpeedX() {
return 0.35;
}
@Override
public double getMouseSpeedY() {
return 0.2;
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@Nullable @Nullable
public Pair<Quaternionf, Quaternionf> getPassengerRotation(Entity entity, float tickDelta) { public Pair<Quaternionf, Quaternionf> getPassengerRotation(Entity entity, float tickDelta) {
@ -711,14 +724,13 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
public Vec3 getCameraPosition(float partialTicks, Player player, boolean zoom, boolean isFirstPerson) { public Vec3 getCameraPosition(float partialTicks, Player player, boolean zoom, boolean isFirstPerson) {
if (this.getSeatIndex(player) == 0) { if (this.getSeatIndex(player) == 0) {
Matrix4f transform = getClientVehicleTransform(partialTicks); Matrix4f transform = getClientVehicleTransform(partialTicks);
Vector4f maxCameraPosition = transformPosition(transform, -2.1f, 1, -10 - (float) ClientMouseHandler.custom3pDistanceLerp);
Vec3 finalPos = CameraTool.getMaxZoom(transform, maxCameraPosition);
Vector4f worldPosition = transformPosition(transform, -2.1f, 1, -10);
if (isFirstPerson) { 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())); 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 { } else {
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z); return finalPos;
} }
} }
return super.getCameraPosition(partialTicks, player, false, false); return super.getCameraPosition(partialTicks, player, false, false);

View file

@ -43,6 +43,9 @@ public class ClientMouseHandler {
public static double freeCameraPitch = 0; public static double freeCameraPitch = 0;
public static double freeCameraYaw = 0; public static double freeCameraYaw = 0;
public static double custom3pDistance = 0;
public static double custom3pDistanceLerp = 0;
private static boolean notInGame() { private static boolean notInGame() {
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
if (mc.player == null) return true; if (mc.player == null) return true;
@ -78,8 +81,15 @@ public class ClientMouseHandler {
} }
if (!notInGame() && player.getVehicle() instanceof VehicleEntity vehicle && player == vehicle.getFirstPassenger()) { if (!notInGame() && player.getVehicle() instanceof VehicleEntity vehicle && player == vehicle.getFirstPassenger()) {
int y = 1;
if (vehicle instanceof AirEntity && VehicleControlConfig.INVERT_AIRCRAFT_CONTROL.get()) {
y = -1;
}
speedX = vehicle.getMouseSensitivity() * (posN.x - posO.x); speedX = vehicle.getMouseSensitivity() * (posN.x - posO.x);
speedY = vehicle.getMouseSensitivity() * (posN.y - posO.y); speedY = y * vehicle.getMouseSensitivity() * (posN.y - posO.y);
lerpSpeedX = Mth.lerp(vehicle.getMouseSpeedX(), lerpSpeedX, speedX); lerpSpeedX = Mth.lerp(vehicle.getMouseSpeedX(), lerpSpeedX, speedX);
lerpSpeedY = Mth.lerp(vehicle.getMouseSpeedY(), lerpSpeedY, speedY); lerpSpeedY = Mth.lerp(vehicle.getMouseSpeedY(), lerpSpeedY, speedY);
@ -120,10 +130,10 @@ public class ClientMouseHandler {
if (isFreeCam(player)) { if (isFreeCam(player)) {
freeCameraYaw -= 0.4f * times * lerpSpeedX; freeCameraYaw -= 0.4f * times * lerpSpeedX;
freeCameraPitch += 0.2f * times * lerpSpeedY; freeCameraPitch += 0.3f * times * lerpSpeedY;
} else { } else {
freeCameraYaw = Mth.lerp(0.075 * event.getPartialTick(), freeCameraYaw, 0); freeCameraYaw = Mth.lerp(0.2 * times, freeCameraYaw, 0);
freeCameraPitch = Mth.lerp(0.075 * event.getPartialTick(), freeCameraPitch, 0); freeCameraPitch = Mth.lerp(0.2 * times, freeCameraPitch, 0);
} }
while (freeCameraYaw > 180F) { while (freeCameraYaw > 180F) {
@ -139,10 +149,12 @@ public class ClientMouseHandler {
freeCameraPitch += 360; freeCameraPitch += 360;
} }
if (player.getVehicle() instanceof AirEntity) { if (player.getVehicle() instanceof VehicleEntity vehicle && player == vehicle.getFirstPassenger() && vehicle instanceof AirEntity) {
player.setYRot(player.getVehicle().getYRot()); player.setYRot(player.getVehicle().getYRot());
player.setYHeadRot(player.getYRot()); player.setYHeadRot(player.getYRot());
} }
custom3pDistanceLerp = Mth.lerp(times, custom3pDistanceLerp, custom3pDistance);
} }
@SubscribeEvent @SubscribeEvent

View file

@ -0,0 +1,33 @@
package com.atsuishio.superbwarfare.tools;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import org.joml.Matrix4f;
import org.joml.Vector4f;
public class CameraTool {
public static Vec3 getMaxZoom(Matrix4f transform, Vector4f maxCameraPos) {
Minecraft mc = Minecraft.getInstance();
Player player = mc.player;
Vector4f vehiclePos = transformPosition(transform, 0, 0, 0);
Vec3 maxCameraPosVec3 = new Vec3(maxCameraPos.x, maxCameraPos.y, maxCameraPos.z);
Vec3 vehiclePosVec3 = new Vec3(vehiclePos.x, vehiclePos.y, vehiclePos.z);
Vec3 toVec = vehiclePosVec3.vectorTo(maxCameraPosVec3);
if (player != null) {
HitResult hitresult = player.level().clip(new ClipContext(vehiclePosVec3, vehiclePosVec3.add(toVec), ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, player));
if (hitresult.getType() == HitResult.Type.BLOCK) {
return hitresult.getLocation().add(toVec.normalize().scale(-0.25));
}
}
return maxCameraPosVec3;
}
public static Vector4f transformPosition(Matrix4f transform, float x, float y, float z) {
return transform.transform(new Vector4f(x, y, z, 1));
}
}