优化炮塔音效,添加快艇配置项,添加载具UI

This commit is contained in:
Atsuihsio 2024-12-15 05:22:31 +08:00
parent f38f594044
commit 8dcfff022e
10 changed files with 201 additions and 40 deletions

View file

@ -61,7 +61,7 @@ public class CrossHairOverlay {
float moveY = 0;
var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
if (DisplayConfig.FLOAT_CROSS_HAIR.get()) {
if (DisplayConfig.FLOAT_CROSS_HAIR.get() && player.getVehicle() == null) {
moveX = (float) (-6 * ClientEventHandler.turnRot[1] - (player.isSprinting() ? 10 : 6) * ClientEventHandler.movePosX);
moveY = (float) (-6 * ClientEventHandler.turnRot[0] + 6 * (float) ClientEventHandler.velocityY - (player.isSprinting() ? 10 : 6) * ClientEventHandler.movePosY - 0.25 * ClientEventHandler.firePos);
}

View file

@ -0,0 +1,78 @@
package com.atsuishio.superbwarfare.client.screens;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.config.server.CannonConfig;
import com.atsuishio.superbwarfare.entity.ICannonEntity;
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
import com.atsuishio.superbwarfare.entity.SpeedboatEntity;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
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;
@Mod.EventBusSubscriber(value = Dist.CLIENT)
public class VehicleHudOverlay {
public static float health = 0;
public static float maxHealth = 0;
public static float energy = 0;
public static float maxEnergy = 0;
private static final ResourceLocation ARMOR = ModUtils.loc("textures/screens/armor.png");
private static final ResourceLocation ENERGY = ModUtils.loc("textures/screens/energy.png");
private static final ResourceLocation HEALTH = ModUtils.loc("textures/screens/armor_value.png");
private static final ResourceLocation HEALTH_FRAME = ModUtils.loc("textures/screens/armor_value_frame.png");
@SubscribeEvent(priority = EventPriority.NORMAL)
public static void eventHandler(RenderGuiEvent.Pre event) {
int w = event.getWindow().getGuiScaledWidth();
int h = event.getWindow().getGuiScaledHeight();
Player player = Minecraft.getInstance().player;
if (!shouldRenderCrossHair(player)) return;
Entity vehicle = player.getVehicle();
if (vehicle == null) return;
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);
GuiGraphics guiGraphics = event.getGuiGraphics();
if (vehicle instanceof SpeedboatEntity) {
health = vehicle.getEntityData().get(SpeedboatEntity.HEALTH);
maxHealth = CannonConfig.SPEEDBOAT_HP.get();
energy = vehicle.getEntityData().get(SpeedboatEntity.ENERGY);
maxEnergy = CannonConfig.SPEEDBOAT_MAX_ENERGY.get().floatValue();
}
guiGraphics.pose().pushPose();
guiGraphics.blit(ENERGY, w - 96, h - 28, 0, 0, 12, 12, 12, 12);
guiGraphics.blit(HEALTH_FRAME, w - 83, h - 26, 0, 0, 80, 8, 80, 8);
guiGraphics.blit(HEALTH, w - 83, h - 26, 0, 0, (int) (80 * energy / maxEnergy), 8, 80, 8);
guiGraphics.blit(ARMOR, w - 96, h - 14, 0, 0, 12, 12, 12, 12);
guiGraphics.blit(HEALTH_FRAME, w - 83, h - 12, 0, 0, 80, 8, 80, 8);
guiGraphics.blit(HEALTH, w - 83, h - 12, 0, 0, (int) (80 * health / maxHealth), 8, 80, 8);
guiGraphics.pose().popPose();
}
private static boolean shouldRenderCrossHair(Player player) {
if (player == null) return false;
return !player.isSpectator()
&& (player.getVehicle() != null && player.getVehicle() instanceof IVehicleEntity && !(player.getVehicle() instanceof ICannonEntity));
}
}

View file

@ -24,6 +24,11 @@ public class CannonConfig {
public static ForgeConfigSpec.DoubleValue ANNIHILATOR_SHOOT_COST;
public static ForgeConfigSpec.DoubleValue ANNIHILATOR_MAX_ENERGY;
public static ForgeConfigSpec.IntValue SPEEDBOAT_HP;
public static ForgeConfigSpec.DoubleValue SPEEDBOAT_ENERGY_COST;
public static ForgeConfigSpec.DoubleValue SPEEDBOAT_MAX_ENERGY;
public static ForgeConfigSpec.IntValue SPEEDBOAT_GUN_DAMAGE;
public static void init(ForgeConfigSpec.Builder builder) {
builder.push("mk_42");
@ -87,6 +92,22 @@ public class CannonConfig {
ANNIHILATOR_MAX_ENERGY = builder.defineInRange("annihilator_max_energy", 20000000d, 0d, Double.POSITIVE_INFINITY);
builder.pop();
builder.push("speedboat");
builder.comment("The HealthPoint of Speedboat");
SPEEDBOAT_HP = builder.defineInRange("speedboat_hp", 300, 1, 10000000);
builder.comment("The energy cost of Speedboat per control tick");
SPEEDBOAT_ENERGY_COST = builder.defineInRange("speedboat_energy_cost", 1d, 0d, Double.POSITIVE_INFINITY);
builder.comment("The max energy storage of Speedboat");
SPEEDBOAT_MAX_ENERGY = builder.defineInRange("speedboat_max_energy", 100000d, 0d, Double.POSITIVE_INFINITY);
builder.comment("The gun damage of Speedboat");
SPEEDBOAT_GUN_DAMAGE = builder.defineInRange("speedboat_gun_damage", 25, 1, 10000000);
builder.pop();
}
}

View file

@ -9,6 +9,7 @@ import com.atsuishio.superbwarfare.item.ContainerBlockItem;
import com.atsuishio.superbwarfare.network.ModVariables;
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.atsuishio.superbwarfare.tools.SoundTool;
import net.minecraft.core.BlockPos;
@ -61,7 +62,6 @@ import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.Comparator;
public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity, IVehicleEntity {
public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> ENERGY = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> ROT_Y = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
@ -69,8 +69,10 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
public static final EntityDataAccessor<Float> POWER = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> ROTOR = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Integer> COOL_DOWN = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.INT);
protected static final EntityDataAccessor<String> LAST_ATTACKER_UUID = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.STRING);
public static final float MAX_HEALTH = CannonConfig.MK42_HP.get();
public static final float MAX_HEALTH = CannonConfig.SPEEDBOAT_HP.get();
public static final float MAX_ENERGY = CannonConfig.SPEEDBOAT_MAX_ENERGY.get().floatValue();
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private int lerpSteps;
@ -105,22 +107,27 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
this.entityData.define(POWER, 0f);
this.entityData.define(ROTOR, 0f);
this.entityData.define(COOL_DOWN, 0);
this.entityData.define(LAST_ATTACKER_UUID, "undefined");
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
compound.putFloat("Health", this.entityData.get(HEALTH));
compound.putFloat("Energy", this.entityData.get(ENERGY));
compound.putString("LastAttacker", this.entityData.get(LAST_ATTACKER_UUID));
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
this.entityData.set(ROTOR, compound.getFloat("Rotor"));
this.entityData.set(ENERGY, compound.getFloat("Energy"));
if (compound.contains("Health")) {
this.entityData.set(HEALTH, compound.getFloat("Health"));
} else {
this.entityData.set(HEALTH, MAX_HEALTH);
}
if (compound.contains("LastAttacker")) {
this.entityData.set(LAST_ATTACKER_UUID, compound.getString("LastAttacker"));
}
}
@Override
@ -181,17 +188,21 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
if (source.is(DamageTypes.WITHER_SKULL))
return false;
if (source.is(ModDamageTypes.PROJECTILE_BOOM)) {
amount *= 0.5f;
amount *= 2f;
}
if (source.is(ModDamageTypes.CANNON_FIRE)) {
amount *= 1.4f;
amount *= 3f;
}
if (source.is(ModDamageTypes.GUN_FIRE_ABSOLUTE)) {
amount *= 1.6f;
amount *= 1.2f;
}
if (source.getEntity() != null) {
this.entityData.set(LAST_ATTACKER_UUID, source.getEntity().getStringUUID());
}
this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1);
this.entityData.set(HEALTH, this.entityData.get(HEALTH) - 0.5f * amount);
this.entityData.set(HEALTH, this.entityData.get(HEALTH) - 0.5f * java.lang.Math.max(amount - 3, 0));
return true;
}
@ -243,6 +254,16 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
cannotFire = false;
}
Entity driver = this.getFirstPassenger();
if (driver instanceof Player player) {
if (heat > 100) {
cannotFire = true;
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 1f, 1f);
}
}
}
double fluidFloat;
fluidFloat = -0.05 + 0.1 * getSubmergedHeight(this);
this.setDeltaMovement(this.getDeltaMovement().add(0.0, fluidFloat, 0.0));
@ -281,55 +302,53 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
this.refreshDimensions();
}
public boolean zooming() {
Entity driver = this.getFirstPassenger();
if (driver == null) return false;
if (driver instanceof Player player) {
return player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom;
}
return false;
}
private void gunnerFire() {
if (this.entityData.get(COOL_DOWN) != 0 || cannotFire) return;
Entity driver = this.getFirstPassenger();
if (driver == null) return;
if (driver instanceof Player player) {
if (player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).holdFire) {
if (driver instanceof Player player && !(player.getMainHandItem().is(ModTags.Items.GUN))) {
Level level = player.level();
if (level instanceof ServerLevel && player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).holdFire) {
ProjectileEntity projectile = new ProjectileEntity(driver.level())
.shooter(player)
.damage(30)
.damage(CannonConfig.SPEEDBOAT_GUN_DAMAGE.get())
.headShot(2f)
.zoom(false);
projectile.bypassArmorRate(0.9f);
projectile.setPos(this.xo - this.getViewVector(1).scale(0.54).x - this.getDeltaMovement().x, this.yo + 3.0, this.zo - this.getViewVector(1).scale(0.54).z - this.getDeltaMovement().z);
projectile.shoot(player, player.getLookAngle().x, player.getLookAngle().y + 0.001f, player.getLookAngle().z, 25,
projectile.shoot(player, player.getLookAngle().x, player.getLookAngle().y + (zooming() ? 0.002f : -0.009f), player.getLookAngle().z, 25,
(float) 0.6);
this.level().addFreshEntity(projectile);
float pitch = heat <= 60 ? 1 : (float) (1 - 0.015 * java.lang.Math.abs(60 - heat));
if (player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_FIRE_1P.get(), 2, 1);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MINIGUN_FIRE_3P.get(), SoundSource.PLAYERS, 3, pitch);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MINIGUN_FAR.get(), SoundSource.PLAYERS, 8, pitch);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MINIGUN_VERYFAR.get(), SoundSource.PLAYERS, 16, pitch);
SoundTool.playLocalSound(serverPlayer, ModSounds.M_2_FIRE_1P.get(), 2, 1);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_2_FIRE_3P.get(), SoundSource.PLAYERS, 4, pitch);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_2_FAR.get(), SoundSource.PLAYERS, 12, pitch);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_2_VERYFAR.get(), SoundSource.PLAYERS, 24, pitch);
}
final Vec3 center = new Vec3(this.getX(), this.getEyeY(), this.getZ());
Level level = player.level();
if (level instanceof ServerLevel) {
for (Entity target : level.getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(4), 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(4, 4, 10, this.getX(), this.getEyeY(), this.getZ()));
ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShakeClientMessage(6, 5, 7, this.getX(), this.getEyeY(), this.getZ()));
}
}
}
this.entityData.set(COOL_DOWN, 3);
heat += 4;
if (heat > 100) {
cannotFire = true;
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 1f, 1f);
}
}
}
}
}
@ -371,6 +390,8 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
private void controlBoat() {
Entity passenger0 = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
if (this.entityData.get(ENERGY) <= 0) return;
if (passenger0 == null) {
this.getPersistentData().putBoolean("left", false);
this.getPersistentData().putBoolean("right", false);
@ -402,6 +423,10 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
}
}
if (this.getPersistentData().getBoolean("forward") || this.getPersistentData().getBoolean("backward")) {
this.entityData.set(ENERGY, Math.max(this.entityData.get(ENERGY) - CannonConfig.SPEEDBOAT_ENERGY_COST.get().floatValue(), 0));
}
if (level().isClientSide) {
level().playLocalSound(this.getX(), this.getY() + this.getBbHeight() * 0.5, this.getZ(), this.getEngineSound(), this.getSoundSource(), Math.min((this.getPersistentData().getBoolean("forward") || this.getPersistentData().getBoolean("backward") ? 7.5f : 5f) * 2 * Mth.abs(this.entityData.get(POWER)), 0.25f), (random.nextFloat() * 0.1f + 1f), false);
}
@ -477,7 +502,7 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
@Override
protected void positionRider(Entity pPassenger, MoveFunction pCallback) {
super.positionRider(pPassenger, pCallback);
if (this.hasPassenger(pPassenger) && (this.isInWater() || this.isUnderWater())) {
if (this.hasPassenger(pPassenger) && !zooming()) {
pPassenger.setYRot(pPassenger.getYRot() - 1.27f * this.entityData.get(DELTA_ROT));
pPassenger.setYHeadRot(pPassenger.getYHeadRot() - 1.27f * this.entityData.get(DELTA_ROT));
}
@ -526,14 +551,14 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
}
private void destroy() {
CustomExplosion explosion = new CustomExplosion(this.level(), this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this), 20f,
this.getX(), this.getY(), this.getZ(), 4.5f, ExplosionDestroyConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
Entity attacker = EntityFindUtil.findEntity(this.level(), this.entityData.get(LAST_ATTACKER_UUID));
CustomExplosion explosion = new CustomExplosion(this.level(), attacker,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), attacker, attacker), 45f,
this.getX(), this.getY(), this.getZ(), 3f, ExplosionDestroyConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
explosion.explode();
net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion);
explosion.finalizeExplosion(false);
ParticleTool.spawnHugeExplosionParticles(this.level(), this.position());
ParticleTool.spawnMediumExplosionParticles(this.level(), this.position());
this.discard();
}
@ -576,6 +601,6 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
@Override
public void charge(int amount) {
this.entityData.set(ENERGY, Math.min(this.entityData.get(ENERGY) + amount, CannonConfig.ANNIHILATOR_MAX_ENERGY.get().floatValue()));
this.entityData.set(ENERGY, Math.min(this.entityData.get(ENERGY) + amount, MAX_ENERGY));
}
}

View file

@ -310,6 +310,11 @@ public class ModSounds {
public static final RegistryObject<SoundEvent> JAVELIN_LOCK = REGISTRY.register("javelin_lock", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "javelin_lock")));
public static final RegistryObject<SoundEvent> JAVELIN_LOCKON = REGISTRY.register("javelin_lockon", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "javelin_lockon")));
public static final RegistryObject<SoundEvent> M_2_FIRE_1P = REGISTRY.register("m2_fire_1p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "m2_fire_1p")));
public static final RegistryObject<SoundEvent> M_2_FIRE_3P = REGISTRY.register("m2_fire_3p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "m2_fire_3p")));
public static final RegistryObject<SoundEvent> M_2_FAR = REGISTRY.register("m2_far", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "m2_far")));
public static final RegistryObject<SoundEvent> M_2_VERYFAR = REGISTRY.register("m2_veryfar", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "m2_veryfar")));
public static final RegistryObject<SoundEvent> MK_42_FIRE_1P = REGISTRY.register("mk_42_fire_1p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "mk_42_fire_1p")));
public static final RegistryObject<SoundEvent> MK_42_FIRE_3P = REGISTRY.register("mk_42_fire_3p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "mk_42_fire_3p")));
public static final RegistryObject<SoundEvent> MK_42_FAR = REGISTRY.register("mk_42_far", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "mk_42_far")));

View file

@ -2445,5 +2445,37 @@
"stream": false
}
]
},
"m2_fire_1p": {
"sounds": [
{
"name": "superbwarfare:m2/m2_fire_1p",
"stream": false
}
]
},
"m2_fire_3p": {
"sounds": [
{
"name": "superbwarfare:m2/m2_fire_3p",
"stream": false
}
]
},
"m2_far": {
"sounds": [
{
"name": "superbwarfare:m2/m2_far",
"stream": false
}
]
},
"m2_veryfar": {
"sounds": [
{
"name": "superbwarfare:m2/m2_veryfar",
"stream": false
}
]
}
}