添加直升机的机炮

This commit is contained in:
Atsuihsio 2025-01-03 21:23:05 +08:00
parent 38faab6b19
commit 8b1f04537c
13 changed files with 191 additions and 21 deletions

View file

@ -120,7 +120,7 @@ public class ClickHandler {
|| stack.is(ModItems.MONITOR.get())
|| stack.is(ModItems.LUNGE_MINE.get())
|| (player.getVehicle() instanceof ICannonEntity)
|| (player.getVehicle() instanceof IArmedVehicleEntity iVehicle && iVehicle.isDriver(player) && stack.is(ItemStack.EMPTY.getItem()))
|| (player.getVehicle() instanceof IArmedVehicleEntity iVehicle && iVehicle.isDriver(player))
|| (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get()))) {
if (button == ModKeyMappings.FIRE.getKey().getValue()) {
handleWeaponFirePress(player, stack);
@ -256,7 +256,7 @@ public class ClickHandler {
if ((stack.is(ModTags.Items.GUN) && !(player.getVehicle() instanceof ICannonEntity))
|| stack.is(ModItems.MONITOR.get())
|| (player.getVehicle() instanceof ICannonEntity)
|| (player.getVehicle() instanceof IArmedVehicleEntity iVehicle && iVehicle.isDriver(player) && stack.is(ItemStack.EMPTY.getItem()))
|| (player.getVehicle() instanceof IArmedVehicleEntity iVehicle && iVehicle.isDriver(player))
|| (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get()))) {
if (key == ModKeyMappings.FIRE.getKey().getValue()) {
handleWeaponFirePress(player, stack);

View file

@ -1,9 +1,13 @@
package com.atsuishio.superbwarfare.client.overlay;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.client.RenderHelper;
import com.atsuishio.superbwarfare.entity.IHelicopterEntity;
import com.atsuishio.superbwarfare.entity.MobileVehicleEntity;
import com.atsuishio.superbwarfare.entity.VehicleEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.network.ModVariables;
import com.atsuishio.superbwarfare.tools.HudUtil;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
@ -15,12 +19,15 @@ import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderGuiEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import java.text.DecimalFormat;
@ -77,22 +84,81 @@ public class HelicopterHudOverlay {
event.getGuiGraphics().blit(ModUtils.loc("textures/screens/helicopter/heli_power_ruler.png"), w / 2 + 100, h / 2 - 64, 0, 0, 64, 128, 64, 128);
double height = mobileVehicle.position().distanceTo((Vec3.atLowerCornerOf(mobileVehicle.level().clip(new ClipContext(mobileVehicle.position(), mobileVehicle.position().add(new Vec3(0, -1, 0).scale(100)),
ClipContext.Block.OUTLINE, ClipContext.Fluid.ANY, mobileVehicle)).getBlockPos())));
double blockInWay = mobileVehicle.position().distanceTo((Vec3.atLowerCornerOf(mobileVehicle.level().clip(new ClipContext(mobileVehicle.position(), mobileVehicle.position().add(new Vec3(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y + 0.06, mobileVehicle.getDeltaMovement().z).normalize().scale(100)),
ClipContext.Block.OUTLINE, ClipContext.Fluid.ANY, mobileVehicle)).getBlockPos())));
float power = iHelicopterEntity.getPower();
lerpPower = Mth.lerp(0.001f * event.getPartialTick(), lerpPower, power);
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/helicopter/heli_power.png"), (float) w / 2 + 130f, ((float) h / 2 - 64 + 124 - power * 980), 0, 0, 4, power * 980, 4, power * 980);
lerpVy = (float) Mth.lerp(0.021f * event.getPartialTick(), lerpVy, mobileVehicle.getDeltaMovement().y() + 0.06f);
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/helicopter/heli_vy_move.png"), (float) w / 2 + 100, ((float) h / 2 - 64 - Math.max(lerpVy, 0) * 100f), 0, 0, 64, 128, 64, 128);
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/helicopter/heli_vy_move.png"), (float) w / 2 + 138, ((float) h / 2 - 3 - Math.max(lerpVy * 20, -24) * 2.5f), 0, 0, 8, 8, 8, 8);
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(new DecimalFormat("##").format(lerpVy * 20) + "m/s"),
w / 2 + 146, (int)(h / 2 - 3 - Math.max(lerpVy * 20, -24) * 2.5), (((lerpVy < -20 || lerpVy * 20 < -5 || (lerpVy * 20 < -1 && length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y + 0.06, mobileVehicle.getDeltaMovement().z) * 72 > 100)) && height < 36) || (length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y + 0.06, mobileVehicle.getDeltaMovement().z) * 72 > 40 && blockInWay < 72) ? -65536 : 0x66FF00), false);
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(new DecimalFormat("##").format(mobileVehicle.getY())),
w / 2 + 104, h / 2, 0x66FF00, false);
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/helicopter/speed_frame.png"), (float) w / 2 - 144, (float) h / 2 - 6, 0, 0, 50, 18, 50, 18);
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(new DecimalFormat("##").format(length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y + 0.06, mobileVehicle.getDeltaMovement().z) * 72) + "KM/H"),
w / 2 - 140, h / 2, 0x66FF00, false);
if (((lerpVy * 20 < -5 || (lerpVy * 20 < -1 && length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y + 0.06, mobileVehicle.getDeltaMovement().z) * 72 > 100)) && height < 36)
||(length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y + 0.06, mobileVehicle.getDeltaMovement().z) * 72 > 40 && blockInWay < 72)) {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal( "TERRAIN TERRAIN"),
w / 2 - 42, h / 2 + 24, -65536, false);
} else if (lerpVy * 20 < -20) {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal( "SINK RATEPULL UP!"),
w / 2 - 53, h / 2 + 24, -65536, false);
}
Matrix4f transform = getVehicleTransform(mobileVehicle);
float x0 = 0f;
float y0 = 0.65f;
float z0 = 0.8f;
Vector4f worldPosition = transformPosition(transform, x0, y0, z0);
float fovAdjust2 = (float) (Minecraft.getInstance().options.fov().get() / 30) - 1;
double zoom = 0.96 * 3 + 0.06 * fovAdjust2;
Vec3 pos = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z).add(mobileVehicle.getViewVector(event.getPartialTick()).scale(500));
Vec3 lookAngle = player.getLookAngle().normalize().scale(pos.distanceTo(cameraPos) * (1 - 1.0 / zoom));
var cPos = cameraPos.add(lookAngle);
Vec3 p = RenderHelper.worldToScreen(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z).add(mobileVehicle.getViewVector(event.getPartialTick()).scale(500)),ClientEventHandler.zoom ? cPos : cameraPos);
if (p == null) return;
poseStack.pushPose();
int x = (int) p.x;
int y = (int) p.y;
HudUtil.blit(poseStack, ModUtils.loc("textures/screens/helicopter/crosshair_ind.png"), x-8, y-8, 0, 0, 16, 16, 16, 16, 0x66FF00);
poseStack.popPose();
} else {
scopeScale = 0.7f;
}
}
}
public static Matrix4f getVehicleTransform(VehicleEntity vehicle) {
Matrix4f transform = new Matrix4f();
transform.translate((float) vehicle.getX(), (float) vehicle.getY(), (float) vehicle.getZ());
transform.rotate(Axis.YP.rotationDegrees(-vehicle.getYRot()));
transform.rotate(Axis.XP.rotationDegrees(vehicle.getXRot()));
transform.rotate(Axis.ZP.rotationDegrees(vehicle.getRoll()));
return transform;
}
public static Vector4f transformPosition(Matrix4f transform, float x, float y, float z) {
return transform.transform(new Vector4f(x, y, z, 1));
}
public static double length(double x, double y,double z) {
return Math.sqrt(x * x + y * y + z * z);
}

View file

@ -1,13 +1,15 @@
package com.atsuishio.superbwarfare.entity;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.config.server.ExplosionDestroyConfig;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
import com.atsuishio.superbwarfare.tools.CustomExplosion;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.mojang.math.Axis;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
@ -15,6 +17,7 @@ import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
@ -24,8 +27,10 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.PlayMessages;
import org.jetbrains.annotations.NotNull;
import org.joml.Math;
@ -37,6 +42,8 @@ import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache
import software.bernie.geckolib.core.animation.AnimatableManager;
import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.Comparator;
public class Ah6Entity extends MobileVehicleEntity implements GeoEntity, IHelicopterEntity {
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
@ -247,7 +254,7 @@ public class Ah6Entity extends MobileVehicleEntity implements GeoEntity, IHelico
Matrix4f transform = getVehicleTransform();
float x = 0.45f;
float x = 0.6f;
float y = 1.2f;
float z = 1f;
y += (float) passenger.getMyRidingOffset();
@ -282,20 +289,6 @@ public class Ah6Entity extends MobileVehicleEntity implements GeoEntity, IHelico
return 4;
}
// From Immersive_Aircraft
public Matrix4f getVehicleTransform() {
Matrix4f transform = new Matrix4f();
transform.translate((float) getX(), (float) getY(), (float) getZ());
transform.rotate(Axis.YP.rotationDegrees(-getYRot()));
transform.rotate(Axis.XP.rotationDegrees(getXRot()));
transform.rotate(Axis.ZP.rotationDegrees(getRoll()));
return transform;
}
protected Vector4f transformPosition(Matrix4f transform, float x, float y, float z) {
return transform.transform(new Vector4f(x, y, z, 1));
}
@Override
public void destroy() {
if (level() instanceof ServerLevel) {
@ -332,6 +325,56 @@ public class Ah6Entity extends MobileVehicleEntity implements GeoEntity, IHelico
@Override
public void vehicleShoot(Player player) {
Matrix4f transform = getVehicleTransform();
float x = 1f;
float y = 0.62f;
float z = 0.8f;
Vector4f worldPositionRight = transformPosition(transform, -x, y, z);
ProjectileEntity projectileRight = new ProjectileEntity(player.level())
.shooter(player)
.damage(20)
.headShot(2f)
.zoom(false);
projectileRight.heBullet(true, 8);
projectileRight.bypassArmorRate(1);
projectileRight.setPos(worldPositionRight.x, worldPositionRight.y, worldPositionRight.z);
projectileRight.shoot(player, this.getLookAngle().x, this.getLookAngle().y+ 0.03, this.getLookAngle().z, 20,
(float) 0.2);
this.level().addFreshEntity(projectileRight);
Vector4f worldPositionLeft = transformPosition(transform, x, y, z);
ProjectileEntity projectileLeft = new ProjectileEntity(player.level())
.shooter(player)
.damage(20)
.headShot(2f)
.zoom(false);
projectileLeft.heBullet(true, 8);
projectileLeft.bypassArmorRate(1);
projectileLeft.setPos(worldPositionLeft.x, worldPositionLeft.y, worldPositionLeft.z);
projectileLeft.shoot(player, this.getLookAngle().x, this.getLookAngle().y + 0.03, this.getLookAngle().z, 20,
(float) 0.2);
this.level().addFreshEntity(projectileLeft);
if (!player.level().isClientSide) {
if (player instanceof ServerPlayer serverPlayer) {
serverPlayer.playSound(ModSounds.HELICOPTER_CANNON_FIRE_3P.get(), 4, 1);
serverPlayer.playSound(ModSounds.HELICOPTER_CANNON_FAR.get(), 12, 1);
serverPlayer.playSound(ModSounds.HELICOPTER_CANNON_VERYFAR.get(), 24, 1);
}
}
Level level = player.level();
final Vec3 center = new Vec3(this.getX(), this.getEyeY(), this.getZ());
for (Entity target : level.getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(6), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) {
if (target instanceof ServerPlayer serverPlayer) {
ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShakeClientMessage(6, 5, 7, this.getX(), this.getEyeY(), this.getZ()));
}
}
}
@Override
@ -341,12 +384,12 @@ public class Ah6Entity extends MobileVehicleEntity implements GeoEntity, IHelico
@Override
public int mainGunRpm() {
return 360;
return 300;
}
@Override
public boolean canShoot(Player player) {
return false;
return true;
}
@Override

View file

@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.entity;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.item.ContainerBlockItem;
import com.mojang.math.Axis;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
@ -24,6 +25,8 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.joml.Math;
import org.joml.Matrix4f;
import org.joml.Vector4f;
public class VehicleEntity extends Entity {
@ -239,6 +242,20 @@ public class VehicleEntity extends Entity {
public void travel() {
}
// From Immersive_Aircraft
public Matrix4f getVehicleTransform() {
Matrix4f transform = new Matrix4f();
transform.translate((float) getX(), (float) getY(), (float) getZ());
transform.rotate(Axis.YP.rotationDegrees(-getYRot()));
transform.rotate(Axis.XP.rotationDegrees(getXRot()));
transform.rotate(Axis.ZP.rotationDegrees(getRoll()));
return transform;
}
public Vector4f transformPosition(Matrix4f transform, float x, float y, float z) {
return transform.transform(new Vector4f(x, y, z, 1));
}
protected void handleClientSync() {
if (isControlledByLocalInstance()) {
interpolationSteps = 0;

View file

@ -600,6 +600,11 @@ public class ClientEventHandler {
if (player == null) return;
if (level == null) return;
if (player.getMainHandItem().getItem() instanceof GunItem) {
clientTimerVehicle.stop();
return;
}
if (notInGame()) {
clientTimerVehicle.stop();
holdFire = false;
@ -643,6 +648,9 @@ public class ClientEventHandler {
player.playSound(ModSounds.M_2_FIRE_1P.get(), 1f, pitch);
player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
}
if (iVehicle instanceof Ah6Entity ah6Entity) {
player.playSound(ModSounds.HELICOPTER_CANNON_FIRE_1P.get(), 1f, 1);
}
}
@SubscribeEvent

View file

@ -359,5 +359,9 @@ public class ModSounds {
public static final RegistryObject<SoundEvent> HELICOPTER_ENGINE_START = REGISTRY.register("helicopter_engine_start", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("helicopter_engine_start")));
public static final RegistryObject<SoundEvent> HELICOPTER_ENGINE = REGISTRY.register("helicopter_engine", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("helicopter_engine")));
public static final RegistryObject<SoundEvent> HELICOPTER_CANNON_FIRE_1P = REGISTRY.register("heli_cannon_fire_1p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("heli_cannon_fire_1p")));
public static final RegistryObject<SoundEvent> HELICOPTER_CANNON_FIRE_3P = REGISTRY.register("heli_cannon_fire_3p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("heli_cannon_fire_3p")));
public static final RegistryObject<SoundEvent> HELICOPTER_CANNON_FAR = REGISTRY.register("heli_cannon_far", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("heli_cannon_far")));
public static final RegistryObject<SoundEvent> HELICOPTER_CANNON_VERYFAR = REGISTRY.register("heli_cannon_veryfar", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("heli_cannon_veryfar")));
}

View file

@ -2521,5 +2521,37 @@
"name": "superbwarfare:helicopter/heli_engine"
}
]
},
"heli_cannon_fire_1p": {
"sounds": [
{
"name": "superbwarfare:helicopter/heli_cannon_fire_1p",
"stream": false
}
]
},
"heli_cannon_fire_3p": {
"sounds": [
{
"name": "superbwarfare:helicopter/heli_cannon_fire_3p",
"stream": false
}
]
},
"heli_cannon_far": {
"sounds": [
{
"name": "superbwarfare:helicopter/heli_cannon_far",
"stream": false
}
]
},
"heli_cannon_veryfar": {
"sounds": [
{
"name": "superbwarfare:helicopter/heli_cannon_veryfar",
"stream": false
}
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 B

After

Width:  |  Height:  |  Size: 348 B