添加A10射击功能,添加载具在水中运动的音效

This commit is contained in:
Atsuishio 2025-05-07 03:46:34 +08:00 committed by Light_Quanta
parent 654cd23a14
commit feafd5a54d
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
15 changed files with 548 additions and 27 deletions

View file

@ -58,6 +58,7 @@ public class ClientRenderHandler {
event.registerBelowAll(HandsomeFrameOverlay.ID, new HandsomeFrameOverlay());
event.registerBelowAll(SpyglassRangeOverlay.ID, new SpyglassRangeOverlay());
event.registerBelowAll(HelicopterHudOverlay.ID, new HelicopterHudOverlay());
event.registerBelowAll(AircraftOverlay.ID, new AircraftOverlay());
event.registerBelowAll(MortarInfoOverlay.ID, new MortarInfoOverlay());
}
}

View file

@ -119,7 +119,28 @@ public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance
@Override
protected float getVolume(MobileVehicleEntity mobileVehicle) {
return (float) Mth.lerp(Mth.clamp(mobileVehicle.getDeltaMovement().length(), 0F, 0.3F), 0.0F, 0.3F);
return (float) Mth.lerp(Mth.clamp(mobileVehicle.getDeltaMovement().length(), 0F, 0.3F), 0.0F, 0.3F) * (mobileVehicle.onGround() ? 1 : 0.5f);
}
}
public static class SwimSound extends VehicleSoundInstance {
public SwimSound(MobileVehicleEntity mobileVehicle) {
super(ModSounds.VEHICLE_SWIM.get(), Minecraft.getInstance(), mobileVehicle);
}
@Override
protected boolean canPlay(MobileVehicleEntity mobileVehicle) {
return true;
}
@Override
protected float getPitch(MobileVehicleEntity mobileVehicle) {
return 1;
}
@Override
protected float getVolume(MobileVehicleEntity mobileVehicle) {
return (float) Mth.lerp(Mth.clamp(mobileVehicle.getDeltaMovement().horizontalDistance() * (mobileVehicle.isInWater() ? 1.2 : 0), 0F, 0.6F), 0.0F, 0.6F);
}
}
}

View file

@ -0,0 +1,236 @@
package com.atsuishio.superbwarfare.client.overlay;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.ClickHandler;
import com.atsuishio.superbwarfare.client.RenderHelper;
import com.atsuishio.superbwarfare.entity.vehicle.base.AircraftEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.tools.FormatTool;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.minecraft.client.Camera;
import net.minecraft.client.CameraType;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.LayeredDraw;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
import org.joml.Math;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
@OnlyIn(Dist.CLIENT)
public class AircraftOverlay implements LayeredDraw.Layer {
public static final ResourceLocation ID = Mod.loc("aircraft_hud");
private static float scopeScale = 1;
private static float lerpVy = 1;
private static float lerpPower = 1;
@Override
public void render(GuiGraphics guiGraphics, @NotNull DeltaTracker deltaTracker) {
int screenWidth = guiGraphics.guiWidth();
int screenHeight = guiGraphics.guiHeight();
Minecraft mc = Minecraft.getInstance();
Player player = mc.player;
Camera camera = mc.gameRenderer.getMainCamera();
Vec3 cameraPos = camera.getPosition();
PoseStack poseStack = guiGraphics.pose();
var partialTick = deltaTracker.getGameTimeDeltaPartialTick(true);
if (player == null) return;
if (ClickHandler.isEditing)
return;
if (player.getVehicle() instanceof AircraftEntity aircraftEntity && aircraftEntity instanceof MobileVehicleEntity mobileVehicle && aircraftEntity.isDriver(player) && player.getVehicle() instanceof WeaponVehicleEntity weaponVehicle) {
poseStack.pushPose();
RenderSystem.disableDepthTest();
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
RenderSystem.setShaderColor(1, 1, 1, 1);
scopeScale = Mth.lerp(partialTick, scopeScale, 1F);
float f = (float) Math.min(screenWidth, screenHeight);
float f1 = Math.min((float) screenWidth / f, (float) screenHeight / f) * scopeScale;
float i = Mth.floor(f * f1);
float j = Mth.floor(f * f1);
float k = ((screenWidth - i) / 2);
float l = ((screenHeight - j) / 2);
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) {
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/heli_base.png"), k, l, 0, 0.0F, i, j, i, j);
renderDriverAngle(guiGraphics, player, mobileVehicle, k, l, i, j, partialTick);
preciseBlit(guiGraphics, Mod.loc("textures/screens/compass.png"), (float) screenWidth / 2 - 128, (float) 6, 128 + ((float) 64 / 45 * mobileVehicle.getYRot()), 0, 256, 16, 512, 16);
poseStack.pushPose();
poseStack.rotateAround(Axis.ZP.rotationDegrees(-aircraftEntity.getRotZ(partialTick)), screenWidth / 2f, screenHeight / 2f, 0);
float pitch = aircraftEntity.getRotX(partialTick);
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/heli_line.png"), (float) screenWidth / 2 - 128, (float) screenHeight / 2 - 512 - 5.475f * pitch, 0, 0, 256, 1024, 256, 1024);
poseStack.popPose();
poseStack.pushPose();
poseStack.rotateAround(Axis.ZP.rotationDegrees(aircraftEntity.getRotZ(partialTick)), screenWidth / 2f, screenHeight / 2f - 56, 0);
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/roll_ind.png"), (float) screenWidth / 2 - 8, (float) screenHeight / 2 - 88, 0, 0, 16, 16, 16, 16);
poseStack.popPose();
guiGraphics.blit(Mod.loc("textures/screens/helicopter/heli_power_ruler.png"), screenWidth / 2 + 100, screenHeight / 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 = aircraftEntity.getPower();
lerpPower = Mth.lerp(0.001f * partialTick, lerpPower, power);
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/heli_power.png"), (float) screenWidth / 2 + 130f, ((float) screenHeight / 2 - 64 + 124 - power * 980), 0, 0, 4, power * 980, 4, power * 980);
lerpVy = (float) Mth.lerp(0.021f * partialTick, lerpVy, mobileVehicle.getDeltaMovement().y());
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/heli_vy_move.png"), (float) screenWidth / 2 + 138, ((float) screenHeight / 2 - 3 - Math.max(lerpVy * 20, -24) * 2.5f), 0, 0, 8, 8, 8, 8);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(lerpVy * 20, "m/s")),
screenWidth / 2 + 146, (int) (screenHeight / 2 - 3 - Math.max(lerpVy * 20, -24) * 2.5), (lerpVy * 20 < -24 || ((lerpVy * 20 < -10 || (lerpVy * 20 < -1 && length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 100)) && height < 36) || (length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 40 && blockInWay < 72) ? -65536 : 0x66FF00), false);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(mobileVehicle.getY())),
screenWidth / 2 + 104, screenHeight / 2, 0x66FF00, false);
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/speed_frame.png"), (float) screenWidth / 2 - 144, (float) screenHeight / 2 - 6, 0, 0, 50, 18, 50, 18);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72, "km/h")),
screenWidth / 2 - 140, screenHeight / 2, 0x66FF00, false);
// if (mobileVehicle instanceof Ah6Entity ah6Entity) {
// if (weaponVehicle.getWeaponIndex(0) == 0) {
// double heat = 1 - ah6Entity.getEntityData().get(HEAT) / 100.0F;
// guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("20MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : aircraftEntity.getAmmoCount(player))), screenWidth / 2 - 160, screenHeight / 2 - 60, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
// } else {
// guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("70MM ROCKET " + aircraftEntity.getAmmoCount(player)), screenWidth / 2 - 160, screenHeight / 2 - 60, 0x66FF00, false);
// }
// }
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("FLARE " + aircraftEntity.getDecoy()), screenWidth / 2 - 160, screenHeight / 2 - 50, 0x66FF00, false);
if (lerpVy * 20 < -24) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("SINK RATEPULL UP!"),
screenWidth / 2 - 53, screenHeight / 2 + 24, -65536, false);
} else if (((lerpVy * 20 < -10 || (lerpVy * 20 < -1 && length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 100)) && height < 36)
|| (length(mobileVehicle.getDeltaMovement().x, mobileVehicle.getDeltaMovement().y, mobileVehicle.getDeltaMovement().z) * 72 > 40 && blockInWay < 72)) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("TERRAIN TERRAIN"),
screenWidth / 2 - 42, screenHeight / 2 + 24, -65536, false);
}
if (mobileVehicle.getEnergy() < 0.02 * mobileVehicle.getMaxEnergy()) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("NO POWER!"),
screenWidth / 2 - 144, screenHeight / 2 + 14, -65536, false);
} else if (mobileVehicle.getEnergy() < 0.2 * mobileVehicle.getMaxEnergy()) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("LOW POWER"),
screenWidth / 2 - 144, screenHeight / 2 + 14, 0xFF6B00, false);
}
}
Matrix4f transform = getVehicleTransform(mobileVehicle, partialTick);
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(partialTick).scale(192));
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(partialTick).scale(192)), ClientEventHandler.zoomVehicle ? cPos : cameraPos);
if (p != null) {
poseStack.pushPose();
float x = (float) p.x;
float y = (float) p.y;
if (mc.options.getCameraType() == CameraType.FIRST_PERSON) {
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/crosshair_ind.png"), x - 8, y - 8, 0, 0, 16, 16, 16, 16);
renderKillIndicator(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f)));
} else if (mc.options.getCameraType() == CameraType.THIRD_PERSON_BACK) {
poseStack.pushPose();
poseStack.rotateAround(Axis.ZP.rotationDegrees(aircraftEntity.getRotZ(partialTick)), x, y, 0);
preciseBlit(guiGraphics, Mod.loc("textures/screens/drone.png"), x - 8, y - 8, 0, 0, 16, 16, 16, 16);
renderKillIndicator(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f)));
poseStack.pushPose();
poseStack.translate(x, y, 0);
poseStack.scale(0.75f, 0.75f, 1);
// if (mobileVehicle instanceof Ah6Entity ah6Entity) {
// if (weaponVehicle.getWeaponIndex(0) == 0) {
// double heat = ah6Entity.getEntityData().get(HEAT) / 100.0F;
// guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("20MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : aircraftEntity.getAmmoCount(player))), 25, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
// } else {
// guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("70MM ROCKET " + aircraftEntity.getAmmoCount(player)), 25, -9, -1, false);
// }
// }
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("FLARE " + aircraftEntity.getDecoy()), 25, 1, -1, false);
poseStack.popPose();
poseStack.popPose();
}
poseStack.popPose();
}
poseStack.popPose();
} else {
scopeScale = 0.7f;
}
}
private static void renderKillIndicator(GuiGraphics guiGraphics, float posX, float posY) {
VehicleHudOverlay.renderKillIndicator3P(guiGraphics, posX, posY);
}
private static void renderDriverAngle(GuiGraphics guiGraphics, Player player, Entity heli, float k, float l, float i, float j, float ticks) {
float diffY = Mth.wrapDegrees(Mth.lerp(ticks, player.yHeadRotO, player.getYHeadRot()) - Mth.lerp(ticks, heli.yRotO, heli.getYRot())) * 0.35f;
float diffX = Mth.wrapDegrees(Mth.lerp(ticks, player.xRotO, player.getXRot()) - Mth.lerp(ticks, heli.xRotO, heli.getXRot())) * 0.072f;
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/heli_driver_angle.png"), k + diffY, l + diffX, 0, 0.0F, i, j, i, j);
}
public static Matrix4f getVehicleTransform(VehicleEntity vehicle, float partialTicks) {
Matrix4f transform = new Matrix4f();
transform.translate((float) Mth.lerp(partialTicks, vehicle.xo, vehicle.getX()), (float) Mth.lerp(partialTicks, vehicle.yo + 1.45, vehicle.getY() + 1.45), (float) Mth.lerp(partialTicks, vehicle.zo, 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

@ -6,26 +6,31 @@ import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity;
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition;
import com.atsuishio.superbwarfare.entity.vehicle.base.*;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.SmallCannonShellWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon;
import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.tools.CustomExplosion;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.FormatTool;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.network.message.receive.ShakeClientMessage;
import com.atsuishio.superbwarfare.tools.*;
import com.mojang.math.Axis;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
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;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.Entity;
@ -35,8 +40,10 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull;
import org.joml.Math;
import org.joml.Matrix4f;
@ -46,12 +53,17 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.util.GeckoLibUtil;
public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity {
import java.util.Comparator;
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity, WeaponVehicleEntity, AircraftEntity {
public static final EntityDataAccessor<Integer> LOADED_ROCKET = SynchedEntityData.defineId(A10Entity.class, EntityDataSerializers.INT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private float yRotSync;
private boolean fly;
private int flyTime;
public int fireIndex;
public A10Entity(EntityType<A10Entity> type, Level world) {
super(type, world);
@ -62,6 +74,25 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
return 0.5f;
}
@Override
public VehicleWeapon[][] initWeapons() {
return new VehicleWeapon[][]{
new VehicleWeapon[]{
new SmallCannonShellWeapon()
.damage(VehicleConfig.BMP_2_CANNON_DAMAGE.get())
.explosionDamage(VehicleConfig.BMP_2_CANNON_EXPLOSION_DAMAGE.get().floatValue())
.explosionRadius(VehicleConfig.BMP_2_CANNON_EXPLOSION_RADIUS.get().floatValue())
.sound(ModSounds.INTO_CANNON.get())
.icon(Mod.loc("textures/screens/vehicle_weapon/cannon_20mm.png")),
new HeliRocketWeapon()
.damage(VehicleConfig.AH_6_ROCKET_DAMAGE.get())
.explosionDamage(VehicleConfig.AH_6_ROCKET_EXPLOSION_DAMAGE.get())
.explosionRadius(VehicleConfig.AH_6_ROCKET_EXPLOSION_RADIUS.get())
.sound(ModSounds.INTO_MISSILE.get()),
}
};
}
@Override
public ThirdPersonCameraPosition getThirdPersonCameraPosition(int index) {
return new ThirdPersonCameraPosition(17, 3, 0);
@ -70,16 +101,19 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
builder.define(LOADED_ROCKET, 0);
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
compound.putInt("LoadedRocket", this.entityData.get(LOADED_ROCKET));
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
this.entityData.set(LOADED_ROCKET, compound.getInt("LoadedRocket"));
}
@Override
@ -146,10 +180,55 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
}
}
this.terrainCompact(5f, 5f);
if (this.level() instanceof ServerLevel) {
if (reloadCoolDown > 0) {
reloadCoolDown--;
}
handleAmmo();
}
if (this.getFirstPassenger() instanceof Player player && fireInputDown) {
if (this.getWeaponIndex(0) == 0) {
if ((this.entityData.get(AMMO) > 0 || InventoryTool.hasCreativeAmmoBox(player)) && !cannotFire) {
vehicleShoot(player, 0);
}
} else {
if (this.entityData.get(AMMO) > 0) {
vehicleShoot(player, 0);
}
}
}
this.terrainCompact(4f, 4f);
this.refreshDimensions();
}
private void handleAmmo() {
if (!(this.getFirstPassenger() instanceof Player player)) return;
int ammoCount = this.getItemStacks().stream().filter(stack -> {
if (stack.is(ModItems.AMMO_BOX.get())) {
return Ammo.HEAVY.get(stack) > 0;
}
return false;
}).mapToInt(Ammo.HEAVY::get).sum() + countItem(ModItems.SMALL_SHELL.get());
if ((hasItem(ModItems.ROCKET_70.get()) || InventoryTool.hasCreativeAmmoBox(player)) && reloadCoolDown == 0 && this.getEntityData().get(LOADED_ROCKET) < 28) {
this.entityData.set(LOADED_ROCKET, this.getEntityData().get(LOADED_ROCKET) + 1);
reloadCoolDown = 15;
if (!InventoryTool.hasCreativeAmmoBox(player)) {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.ROCKET_70.get())).findFirst().ifPresent(stack -> stack.shrink(1));
}
this.level().playSound(null, this, ModSounds.MISSILE_RELOAD.get(), this.getSoundSource(), 1, 1);
}
if (this.getWeaponIndex(0) == 0) {
this.entityData.set(AMMO, ammoCount);
} else {
this.entityData.set(AMMO, this.getEntityData().get(LOADED_ROCKET));
}
}
@Override
public void travel() {
Entity passenger = this.getFirstPassenger();
@ -435,4 +514,163 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
public boolean allowFreeCam() {
return true;
}
@Override
public void vehicleShoot(Player player, int type) {
Matrix4f transform = getVehicleTransform(1);
if (getWeaponIndex(0) == 0) {
if (this.cannotFire) return;
boolean hasCreativeAmmo = (getFirstPassenger() instanceof Player pPlayer && InventoryTool.hasCreativeAmmoBox(pPlayer)) || hasItem(ModItems.CREATIVE_AMMO_BOX.get());
Vector4f worldPosition = transformPosition(transform, 0.1321625f, -0.56446875f, 7.85210625f);
if (this.entityData.get(AMMO) > 0 || hasCreativeAmmo) {
var entityToSpawn = ((SmallCannonShellWeapon) getWeapon(0)).create(player);
entityToSpawn.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
entityToSpawn.shoot(getLookAngle().x, getLookAngle().y - 0.01, getLookAngle().z, 20, 0.5f);
level().addFreshEntity(entityToSpawn);
sendParticle((ServerLevel) this.level(), ParticleTypes.LARGE_SMOKE, worldPosition.x, worldPosition.y, worldPosition.z, 1, 0, 0, 0, 0, false);
if (!player.level().isClientSide) {
if (player instanceof ServerPlayer serverPlayer) {
serverPlayer.level().playSound(null, this.getOnPos(), ModSounds.HPJ_11_FIRE_3P.get(), SoundSource.PLAYERS, 6, random.nextFloat() * 0.05f + 1);
serverPlayer.level().playSound(null, this.getOnPos(), ModSounds.HPJ_11_FAR.get(), SoundSource.PLAYERS, 12, random.nextFloat() * 0.05f + 1);
serverPlayer.level().playSound(null, this.getOnPos(), ModSounds.HPJ_11_VERYFAR.get(), SoundSource.PLAYERS, 24, random.nextFloat() * 0.05f + 1);
}
}
if (!hasCreativeAmmo) {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.SMALL_SHELL.get())).findFirst().ifPresent(stack -> stack.shrink(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(5), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) {
if (target instanceof ServerPlayer serverPlayer) {
PacketDistributor.sendToPlayer(serverPlayer, new ShakeClientMessage(6, 5, 12, this.getX(), this.getEyeY(), this.getZ()));
}
}
this.entityData.set(HEAT, this.entityData.get(HEAT) + 2);
} else if (getWeaponIndex(0) == 1 && this.getEntityData().get(LOADED_ROCKET) > 0) {
var heliRocketEntity = ((HeliRocketWeapon) getWeapon(0)).create(player);
Vector4f worldPosition;
Vector4f worldPosition2;
Vec3 shootAngle;
if (fireIndex == 0) {
worldPosition = transformPosition(transform, -6.63f, -0.55f, 1.83f);
worldPosition2 = transformPosition(transform, -6.61f, -0.55f, 2.83f);
fireIndex = 1;
} else if (fireIndex == 1) {
worldPosition = transformPosition(transform, -5.28f, -1.76f, 1.87f);
worldPosition2 = transformPosition(transform, -5.27f, -1.76f, 2.87f);
fireIndex = 2;
} else if (fireIndex == 2) {
worldPosition = transformPosition(transform, 5.28f, -1.76f, 1.87f);
worldPosition2 = transformPosition(transform, 5.27f, -1.76f, 2.87f);
fireIndex = 3;
} else {
worldPosition = transformPosition(transform, 6.63f, -0.55f, 1.83f);
worldPosition2 = transformPosition(transform, 6.61f, -0.55f, 2.83f);
fireIndex = 0;
}
shootAngle = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z).vectorTo(new Vec3(worldPosition2.x, worldPosition2.y, worldPosition2.z)).normalize();
heliRocketEntity.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
heliRocketEntity.shoot(shootAngle.x, shootAngle.y - 0.01, shootAngle.z, 8, 0.5f);
player.level().addFreshEntity(heliRocketEntity);
this.level().playSound(null, BlockPos.containing(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z)), ModSounds.HELICOPTER_ROCKET_FIRE_3P.get(), SoundSource.PLAYERS, 5, 1);
this.entityData.set(LOADED_ROCKET, this.getEntityData().get(LOADED_ROCKET) - 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(5), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) {
if (target instanceof ServerPlayer serverPlayer) {
PacketDistributor.sendToPlayer(serverPlayer, new ShakeClientMessage(6, 5, 12, this.getX(), this.getEyeY(), this.getZ()));
}
}
reloadCoolDown = 15;
}
}
@Override
public int mainGunRpm(Player player) {
return 0;
}
@Override
public boolean canShoot(Player player) {
if (getWeaponIndex(0) == 0) {
return false;
} else if (getWeaponIndex(0) == 1) {
return this.entityData.get(AMMO) > 0;
}
return false;
}
@Override
public int getAmmoCount(Player player) {
return this.entityData.get(AMMO);
}
@Override
public boolean banHand(Player player) {
return true;
}
@Override
public boolean hidePassenger(Entity entity) {
return false;
}
@Override
public int zoomFov() {
return 3;
}
@Override
public int getWeaponHeat(Player player) {
return entityData.get(HEAT);
}
@Override
public float getRotX(float tickDelta) {
return this.getPitch(tickDelta);
}
@Override
public float getRotY(float tickDelta) {
return this.getYaw(tickDelta);
}
@Override
public float getRotZ(float tickDelta) {
return this.getRoll(tickDelta);
}
@Override
public float getPower() {
return this.entityData.get(POWER);
}
@Override
public int getDecoy() {
return this.entityData.get(DECOY_COUNT);
}
}

View file

@ -295,10 +295,6 @@ public class SpeedboatEntity extends ContainerMobileVehicleEntity implements Geo
this.consumeEnergy(VehicleConfig.SPEEDBOAT_ENERGY_COST.get());
}
if (level().isClientSide) {
level().playLocalSound(this.getX(), this.getY() + this.getBbHeight() * 0.5, this.getZ(), this.getEngineSound(), this.getSoundSource(), Math.min((this.forwardInputDown || this.backInputDown ? 7.5f : 5f) * 2 * Mth.abs(this.entityData.get(POWER)), 0.25f), (random.nextFloat() * 0.1f + 1f), false);
}
this.entityData.set(POWER, this.entityData.get(POWER) * 0.96f);
this.entityData.set(DELTA_ROT, this.entityData.get(DELTA_ROT) * 0.8f);
@ -327,6 +323,11 @@ public class SpeedboatEntity extends ContainerMobileVehicleEntity implements Geo
return ModSounds.BOAT_ENGINE.get();
}
@Override
public float getEngineSoundVolume() {
return (Mth.abs(entityData.get(POWER)) - 0.01f) * 2f;
}
@Override
@ParametersAreNonnullByDefault
protected void positionRider(Entity passenger, MoveFunction callback) {

View file

@ -0,0 +1,14 @@
package com.atsuishio.superbwarfare.entity.vehicle.base;
public interface AirEntity extends ArmedVehicleEntity {
float getRotX(float tickDelta);
float getRotY(float tickDelta);
float getRotZ(float tickDelta);
float getPower();
int getDecoy();
}

View file

@ -0,0 +1,5 @@
package com.atsuishio.superbwarfare.entity.vehicle.base;
public interface AircraftEntity extends AirEntity {
}

View file

@ -1,14 +1,5 @@
package com.atsuishio.superbwarfare.entity.vehicle.base;
public interface HelicopterEntity extends ArmedVehicleEntity {
public interface HelicopterEntity extends AirEntity {
float getRotX(float tickDelta);
float getRotY(float tickDelta);
float getRotZ(float tickDelta);
float getPower();
int getDecoy();
}

View file

@ -19,6 +19,7 @@ public class ClientSoundHandler {
if (event.getLevel().isClientSide) {
if (event.getEntity() instanceof MobileVehicleEntity mobileVehicle) {
Minecraft.getInstance().getSoundManager().play(new VehicleSoundInstance.EngineSound(mobileVehicle, mobileVehicle.getEngineSound()));
Minecraft.getInstance().getSoundManager().play(new VehicleSoundInstance.SwimSound(mobileVehicle));
}
if (event.getEntity() instanceof MobileVehicleEntity mobileVehicle && mobileVehicle instanceof TrackEntity) {
Minecraft.getInstance().getSoundManager().play(new VehicleSoundInstance.TrackSound(mobileVehicle));

View file

@ -444,6 +444,7 @@ public class ModSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> ROCKET_FLY = REGISTRY.register("rocket_fly", () -> SoundEvent.createVariableRangeEvent(Mod.loc("rocket_fly")));
public static final DeferredHolder<SoundEvent, SoundEvent> SHELL_FLY = REGISTRY.register("shell_fly", () -> SoundEvent.createVariableRangeEvent(Mod.loc("shell_fly")));
public static final DeferredHolder<SoundEvent, SoundEvent> ROCKET_ENGINE = REGISTRY.register("rocket_engine", () -> SoundEvent.createVariableRangeEvent(Mod.loc("rocket_engine")));
public static final DeferredHolder<SoundEvent, SoundEvent> VEHICLE_SWIM = REGISTRY.register("vehicle_swim", () -> SoundEvent.createVariableRangeEvent(Mod.loc("vehicle_swim")));
public static final DeferredHolder<SoundEvent, SoundEvent> A_10_ENGINE = REGISTRY.register("a10_engine", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_engine")));
}

View file

@ -449,6 +449,7 @@
"entity.superbwarfare.swarm_drone": "Swarm Drone",
"entity.superbwarfare.smoke_decoy": "Smoke",
"entity.superbwarfare.hpj_11": "H/PJ-11 CIWS",
"entity.superbwarfare.a_10a": "A-10 Thunderbolt II",
"key.categories.superbwarfare": "Superb Warfare",
"key.superbwarfare.hold_zoom": "Zoom (Hold)",

View file

@ -448,6 +448,7 @@
"entity.superbwarfare.swarm_drone": "蜂群无人机",
"entity.superbwarfare.smoke_decoy": "烟雾",
"entity.superbwarfare.hpj_11": "H/PJ-11近防炮",
"entity.superbwarfare.a_10a": "A-10“雷电Ⅱ”攻击机",
"key.categories.superbwarfare": "卓越前线",
"key.superbwarfare.hold_zoom": "瞄准(按住)",

View file

@ -2427,8 +2427,9 @@
"boat_engine": {
"sounds": [
{
"name": "superbwarfare:speedboat/engine",
"stream": false
"attenuation_distance": 48,
"stream": false,
"name": "superbwarfare:speedboat/engine"
}
]
},
@ -3100,6 +3101,15 @@
}
]
},
"vehicle_swim": {
"sounds": [
{
"attenuation_distance": 48,
"stream": true,
"name": "superbwarfare:vehicle_swim"
}
]
},
"a10_engine": {
"sounds": [
{