将载具自动武器射速逻辑移到客户端计算,优化炮塔瞄准视角hud

This commit is contained in:
Atsuihsio 2024-12-20 12:22:00 +08:00
parent 0f9d8a5e25
commit bb82b004d1
14 changed files with 309 additions and 95 deletions

View file

@ -155,7 +155,7 @@ public class ClickHandler {
double scroll = event.getScrollDelta();
if (stack.is(ModTags.Items.GUN) && player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom) {
if (stack.is(ModTags.Items.GUN) && ClientEventHandler.zoom) {
var tag = stack.getOrCreateTag();
if (tag.getBoolean("CanSwitchScope")) {
ModUtils.PACKET_HANDLER.sendToServer(new SwitchScopeMessage(scroll));
@ -165,6 +165,11 @@ public class ClickHandler {
event.setCanceled(true);
}
if (player.getVehicle() instanceof IVehicleEntity iVehicle && iVehicle.isDriver(player) && ClientEventHandler.zoom) {
ClientEventHandler.vehicleFov = Mth.clamp(ClientEventHandler.vehicleFov + 0.4 * scroll, 1, 6);
event.setCanceled(true);
}
if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked")) {
ClientEventHandler.droneFov = Mth.clamp(ClientEventHandler.droneFov + 0.4 * scroll, 1, 6);
event.setCanceled(true);
@ -293,13 +298,13 @@ public class ClickHandler {
ModUtils.PACKET_HANDLER.sendToServer(new DroneFireMessage(0));
}
if (player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity) {
if (player.getVehicle() instanceof ICannonEntity) {
ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(0));
return;
}
if ((player.getVehicle() != null && player.getVehicle() instanceof SpeedboatEntity boat && boat.getFirstPassenger() == player)) {
ModUtils.PACKET_HANDLER.sendToServer(new FireMessage(0));
if (player.getVehicle() instanceof IVehicleEntity iVehicle && iVehicle.isDriver(player)) {
ClientEventHandler.holdFire = true;
}
if (stack.is(ModTags.Items.GUN) && !(player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity)) {

View file

@ -1,9 +1,11 @@
package com.atsuishio.superbwarfare.client.model.entity;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModTags;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
@ -27,7 +29,8 @@ public class ProjectileEntityModel extends GeoModel<ProjectileEntity> {
if ((ClientEventHandler.zoom && !player.getMainHandItem().is(ModItems.MINIGUN.get()))
|| player.getMainHandItem().is(ModItems.GLOCK_17.get())
|| player.getMainHandItem().is(ModItems.GLOCK_18.get())
|| player.getMainHandItem().is(ModItems.BOCEK.get())) {
|| player.getMainHandItem().is(ModItems.BOCEK.get())
|| (player.getVehicle() instanceof IVehicleEntity iVehicle && iVehicle.isDriver(player) && !player.getMainHandItem().is(ModTags.Items.GUN))) {
return new ResourceLocation(ModUtils.MODID, "geo/projectile_entity.geo.json");
} else {
return new ResourceLocation(ModUtils.MODID, "geo/projectile_entity2.geo.json");

View file

@ -0,0 +1,72 @@
package com.atsuishio.superbwarfare.client.screens;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.client.RenderHelper;
import com.atsuishio.superbwarfare.entity.SpeedboatEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
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.network.chat.Component;
import net.minecraft.util.Mth;
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;
import java.text.DecimalFormat;
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
@Mod.EventBusSubscriber(value = Dist.CLIENT)
public class VehicleMgHudOverlay {
public static float indicatorPosH = 0;
@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 cannon = player.getVehicle();
if (cannon == 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);
float fovAdjust = (float) 70 / Minecraft.getInstance().options.fov().get();
float f = (float) Math.min(w, h);
float f1 = Math.min((float) w / f, (float) h / f) * fovAdjust;
int i = Mth.floor(f * f1);
int j = Mth.floor(f * f1);
int k = (w - i) / 2;
int l = (h - j) / 2;
RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair_notzoom.png"), k, l, 0, 0.0F, i, j, i, j);
if (ClientEventHandler.vehicleFovLerp > 1.01) {
event.getGuiGraphics().blit(ModUtils.loc("textures/screens/drone_fov.png"), w / 2 + 100, h / 2 - 64, 0, 0, 64, 129, 64, 129);
GuiGraphics guiGraphics = event.getGuiGraphics();
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/drone_fov_move.png"), (float) w / 2 + 100, (float) (h / 2 - 64 - ((ClientEventHandler.vehicleFovLerp - 1) * 23.8)), 0, 0, 64, 129, 64, 129);
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(new DecimalFormat("##.#").format(ClientEventHandler.vehicleFovLerp) + "x"),
w / 2 + 144, h / 2 + 56 - (int) ((ClientEventHandler.vehicleFovLerp - 1) * 23.8), -1, false);
}
}
private static boolean shouldRenderCrossHair(Player player) {
if (player == null) return false;
return !player.isSpectator()
&& player.getVehicle() instanceof SpeedboatEntity && ClientEventHandler.zoom;
}
}

View file

@ -105,7 +105,7 @@ public class CannonConfig {
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);
SPEEDBOAT_GUN_DAMAGE = builder.defineInRange("speedboat_gun_damage", 45, 1, 10000000);
builder.pop();
}

View file

@ -550,4 +550,19 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
public float getMaxHealth() {
return (int)MAX_HEALTH;
}
@Override
public boolean isDriver(Player player) {
return false;
}
@Override
public int mainGunRpm() {
return 0;
}
@Override
public boolean canShoot(Player player) {
return true;
}
}

View file

@ -1,9 +1,6 @@
package com.atsuishio.superbwarfare.entity;
import net.minecraft.world.entity.player.Player;
public interface ICannonEntity extends IVehicleEntity {
void cannonShoot(Player player);
float getHealth();
float getMaxHealth();
}

View file

@ -1,5 +1,12 @@
package com.atsuishio.superbwarfare.entity;
import net.minecraft.world.entity.player.Player;
public interface IVehicleEntity {
void cannonShoot(Player player);
float getHealth();
float getMaxHealth();
boolean isDriver(Player player);
int mainGunRpm();
boolean canShoot(Player player);
}

View file

@ -431,4 +431,18 @@ public class Mk42Entity extends Entity implements GeoEntity, ICannonEntity {
return (int)MAX_HEALTH;
}
@Override
public boolean isDriver(Player player) {
return false;
}
@Override
public int mainGunRpm() {
return 0;
}
@Override
public boolean canShoot(Player player) {
return true;
}
}

View file

@ -526,4 +526,18 @@ public class Mle1934Entity extends Entity implements GeoEntity, ICannonEntity {
return (int)MAX_HEALTH;
}
@Override
public boolean isDriver(Player player) {
return false;
}
@Override
public int mainGunRpm() {
return 0;
}
@Override
public boolean canShoot(Player player) {
return true;
}
}

View file

@ -85,13 +85,13 @@ import java.util.List;
public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity, IVehicleEntity, HasCustomInventoryScreen, ContainerEntity {
public static final EntityDataAccessor<Integer> FIRE_ANIM = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.INT);
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);
public static final EntityDataAccessor<Float> DELTA_ROT = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
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);
public static final EntityDataAccessor<Integer> HEAT = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.INT);
protected static final EntityDataAccessor<String> LAST_ATTACKER_UUID = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.STRING);
@ -127,13 +127,13 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
@Override
protected void defineSynchedData() {
this.entityData.define(FIRE_ANIM, 0);
this.entityData.define(HEALTH, MAX_HEALTH);
this.entityData.define(ENERGY, 0f);
this.entityData.define(ROT_Y, 0f);
this.entityData.define(DELTA_ROT, 0f);
this.entityData.define(POWER, 0f);
this.entityData.define(ROTOR, 0f);
this.entityData.define(COOL_DOWN, 0);
this.entityData.define(HEAT, 0);
this.entityData.define(LAST_ATTACKER_UUID, "undefined");
}
@ -297,14 +297,14 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
public void baseTick() {
super.baseTick();
if (this.entityData.get(COOL_DOWN) > 0) {
this.entityData.set(COOL_DOWN, this.entityData.get(COOL_DOWN) - 1);
}
if (this.entityData.get(HEAT) > 0) {
this.entityData.set(HEAT, this.entityData.get(HEAT) - 1);
}
if (this.entityData.get(FIRE_ANIM) > 0) {
this.entityData.set(FIRE_ANIM, this.entityData.get(FIRE_ANIM) - 1);
}
if (this.entityData.get(HEAT) < 40) {
cannotFire = false;
}
@ -355,7 +355,6 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
collideBlock();
gunnerAngle();
gunnerFire();
pickUpItem();
this.refreshDimensions();
@ -373,89 +372,82 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
/**
* 机枪塔开火
*/
private void gunnerFire() {
if (this.entityData.get(COOL_DOWN) != 0 || this.cannotFire) return;
Entity driver = this.getFirstPassenger();
if (driver == null) return;
@Override
public void cannonShoot(Player player) {
if (this.cannotFire) return;
if (driver instanceof Player player && !(player.getMainHandItem().is(ModTags.Items.GUN))) {
if (this.getItemStacks().stream().noneMatch(stack -> stack.is(ModItems.HEAVY_AMMO.get())) && !player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get())))
return;
if (player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).holdFire) {
ProjectileEntity projectile = new ProjectileEntity(player.level())
.shooter(player)
.damage(CannonConfig.SPEEDBOAT_GUN_DAMAGE.get())
.headShot(2f)
.zoom(false);
ProjectileEntity projectile = new ProjectileEntity(driver.level())
.shooter(player)
.damage(CannonConfig.SPEEDBOAT_GUN_DAMAGE.get())
.headShot(2f)
.zoom(false);
if (this.getItemStacks().size() > 102) {
ItemStack perkItem = this.getItemStacks().get(102);
if (perkItem.getItem() instanceof PerkItem perk) {
if (perk.getPerk() == ModPerks.SILVER_BULLET.get()) {
projectile.undeadMultiple(2.5f);
} else if (perk.getPerk() == ModPerks.BEAST_BULLET.get()) {
projectile.beast();
} else if (perk.getPerk() == ModPerks.JHP_BULLET.get()) {
projectile.jhpBullet(true, 3);
} else if (perk.getPerk() == ModPerks.HE_BULLET.get()) {
projectile.heBullet(true, 3);
} else if (perk.getPerk() == ModPerks.INCENDIARY_BULLET.get()) {
projectile.fireBullet(true, 3, 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 + (zooming() ? 0.002f : -0.009f), player.getLookAngle().z, 20,
(float) 0.4);
this.level().addFreshEntity(projectile);
if (this.getItemStacks().size() > 102) {
ItemStack perkItem = this.getItemStacks().get(102);
if (perkItem.getItem() instanceof PerkItem perk) {
if (perk.getPerk() == ModPerks.SILVER_BULLET.get()) {
projectile.undeadMultiple(2.5f);
} else if (perk.getPerk() == ModPerks.BEAST_BULLET.get()) {
projectile.beast();
} else if (perk.getPerk() == ModPerks.JHP_BULLET.get()) {
projectile.jhpBullet(true, 3);
} else if (perk.getPerk() == ModPerks.HE_BULLET.get()) {
projectile.heBullet(true, 3);
} else if (perk.getPerk() == ModPerks.INCENDIARY_BULLET.get()) {
projectile.fireBullet(true, 3, false);
}
if (perk.getPerk() instanceof AmmoPerk ammoPerk) {
projectile.setRGB(ammoPerk.rgb);
if (!ammoPerk.mobEffects.get().isEmpty()) {
ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
for (MobEffect effect : ammoPerk.mobEffects.get()) {
mobEffectInstances.add(new MobEffectInstance(effect, 160, 2));
}
projectile.effect(mobEffectInstances);
}
if (perk.getPerk() instanceof AmmoPerk ammoPerk) {
projectile.setRGB(ammoPerk.rgb);
if (!ammoPerk.mobEffects.get().isEmpty()) {
ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
for (MobEffect effect : ammoPerk.mobEffects.get()) {
mobEffectInstances.add(new MobEffectInstance(effect, 160, 2));
}
projectile.effect(mobEffectInstances);
}
}
if (this.getItemStacks().size() > 104) {
ItemStack perkItem = this.getItemStacks().get(104);
if (perkItem.getItem() instanceof PerkItem perk) {
if (perk.getPerk() == ModPerks.MONSTER_HUNTER.get()) {
projectile.monsterMultiple(0.5f);
}
}
}
float pitch = this.entityData.get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * java.lang.Math.abs(60 - this.entityData.get(HEAT)));
if (player instanceof ServerPlayer serverPlayer) {
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);
}
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(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(6, 5, 5, this.getX(), this.getEyeY(), this.getZ()));
}
}
if (level instanceof ServerLevel) {
this.entityData.set(COOL_DOWN, 3);
this.entityData.set(HEAT, this.entityData.get(HEAT) + 4);
}
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.HEAVY_AMMO.get())).findFirst().ifPresent(stack -> stack.shrink(1));
}
}
if (this.getItemStacks().size() > 104) {
ItemStack perkItem = this.getItemStacks().get(104);
if (perkItem.getItem() instanceof PerkItem perk) {
if (perk.getPerk() == ModPerks.MONSTER_HUNTER.get()) {
projectile.monsterMultiple(0.5f);
}
}
}
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 + (zooming() ? 0.002f : -0.009f), player.getLookAngle().z, 20,
(float) 0.4);
this.level().addFreshEntity(projectile);
float pitch = this.entityData.get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * java.lang.Math.abs(60 - this.entityData.get(HEAT)));
if (!player.level().isClientSide) {
if (player instanceof ServerPlayer serverPlayer) {
serverPlayer.playSound(ModSounds.M_2_FIRE_3P.get(), 4, pitch);
serverPlayer.playSound(ModSounds.M_2_FAR.get(), 12, pitch);
serverPlayer.playSound(ModSounds.M_2_VERYFAR.get(), 24, pitch);
}
}
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(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(6, 5, 5, this.getX(), this.getEyeY(), this.getZ()));
}
}
this.entityData.set(HEAT, this.entityData.get(HEAT) + 3);
this.entityData.set(FIRE_ANIM, 3);
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.HEAVY_AMMO.get())).findFirst().ifPresent(stack -> stack.shrink(1));
}
/**
@ -543,7 +535,7 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
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);
}
this.entityData.set(POWER, this.entityData.get(POWER) * 0.9f);
this.entityData.set(POWER, this.entityData.get(POWER) * 0.87f);
this.entityData.set(ROTOR, this.entityData.get(ROTOR) + this.entityData.get(POWER));
this.entityData.set(DELTA_ROT, this.entityData.get(DELTA_ROT) * 0.8f);
@ -724,9 +716,10 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
}
private PlayState firePredicate(AnimationState<SpeedboatEntity> event) {
if (this.entityData.get(COOL_DOWN) > 1 && !cannotFire) {
if (this.entityData.get(FIRE_ANIM) > 1) {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.speedboat.fire"));
}
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.speedboat.idle"));
}
@ -911,4 +904,21 @@ public class SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity,
public float getMaxHealth() {
return (int) MAX_HEALTH;
}
@Override
public boolean isDriver(Player player) {
return player == this.getFirstPassenger();
}
@Override
public int mainGunRpm() {
return 500;
}
@Override
public boolean canShoot(Player player) {
return (this.getItemStacks().stream().anyMatch(stack -> stack.is(ModItems.HEAVY_AMMO.get())) || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get())))
&& !player.getMainHandItem().is(ModTags.Items.GUN)
&& !cannotFire;
}
}

View file

@ -5,11 +5,13 @@ import com.atsuishio.superbwarfare.client.ClickHandler;
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
import com.atsuishio.superbwarfare.entity.DroneEntity;
import com.atsuishio.superbwarfare.entity.ICannonEntity;
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
import com.atsuishio.superbwarfare.entity.SpeedboatEntity;
import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.network.ModVariables;
import com.atsuishio.superbwarfare.network.message.LaserShootMessage;
import com.atsuishio.superbwarfare.network.message.ShootMessage;
import com.atsuishio.superbwarfare.network.message.VehicleFireMessage;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkHelper;
@ -51,6 +53,8 @@ import software.bernie.geckolib.core.animatable.model.CoreGeoBone;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import static com.atsuishio.superbwarfare.entity.SpeedboatEntity.HEAT;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class ClientEventHandler {
@ -110,6 +114,7 @@ public class ClientEventHandler {
public static double customZoom = 0;
public static MillisTimer clientTimer = new MillisTimer();
public static MillisTimer clientTimerVehicle = new MillisTimer();
public static boolean holdFire = false;
@ -131,6 +136,8 @@ public class ClientEventHandler {
public static double shakeAmplitude = 0;
public static double[] shakePos = {0, 0, 0};
public static double shakeType = 0;
public static double vehicleFov = 1;
public static double vehicleFovLerp = 1;
@SubscribeEvent
public static void handleWeaponTurn(RenderHandEvent event) {
@ -537,6 +544,59 @@ public class ClientEventHandler {
});
}
@SubscribeEvent
public static void handleVehicleFire(TickEvent.RenderTickEvent event) {
ClientLevel level = Minecraft.getInstance().level;
Player player = Minecraft.getInstance().player;
if (player == null) return;
if (level == null) return;
if (player.getVehicle() instanceof IVehicleEntity iVehicle && iVehicle.isDriver(player) && iVehicle.canShoot(player)) {
int rpm = iVehicle.mainGunRpm();
if (rpm == 0) {
rpm = 240;
}
// player.displayClientMessage(Component.literal("114 : " + clientTimerVehicle.getProgress()), true);
double rps = (double) rpm / 60;
// cooldown in ms
int cooldown = (int) (1000 / rps);
if ((holdFire)) {
if (!clientTimerVehicle.started()) {
clientTimerVehicle.start();
// 首发瞬间发射
clientTimerVehicle.setProgress((cooldown + 1));
}
if (clientTimerVehicle.getProgress() >= cooldown) {
ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(0));
playVehicleClientSounds(player, iVehicle);
clientTimerVehicle.setProgress((clientTimerVehicle.getProgress() - cooldown));
}
if (notInGame()) {
clientTimerVehicle.stop();
}
} else {
clientTimerVehicle.stop();
}
} else {
clientTimerVehicle.stop();
}
}
public static void playVehicleClientSounds(Player player, IVehicleEntity iVehicle) {
if (iVehicle instanceof SpeedboatEntity speedboat) {
float pitch = speedboat.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * java.lang.Math.abs(60 - speedboat.getEntityData().get(HEAT)));
player.playSound(ModSounds.M_2_FIRE_1P.get(), 1f, pitch);
player.playSound(ModSounds.SHELL_CASING_50CAL.get(),0.3f, 1);
}
}
@SubscribeEvent
public static void handleWeaponBreathSway(TickEvent.RenderTickEvent event) {
Player player = Minecraft.getInstance().player;
@ -1142,6 +1202,13 @@ public class ClientEventHandler {
event.setFOV(event.getFOV() / droneFovLerp);
}
if (player.getVehicle() instanceof IVehicleEntity && !(player.getVehicle() instanceof ICannonEntity) && zoom) {
vehicleFovLerp = Mth.lerp(0.1 * Minecraft.getInstance().getDeltaFrameTime(), vehicleFovLerp, vehicleFov);
event.setFOV(event.getFOV() / vehicleFovLerp);
}
}
@SubscribeEvent
@ -1168,6 +1235,10 @@ public class ClientEventHandler {
return;
}
if (mc.player.getVehicle() instanceof SpeedboatEntity && zoom) {
event.setCanceled(true);
}
if (mc.player.getMainHandItem().is(ModTags.Items.GUN) || (mc.player.getVehicle() != null && mc.player.getVehicle() instanceof ICannonEntity)) {
event.setCanceled(true);
}

View file

@ -1,6 +1,7 @@
package com.atsuishio.superbwarfare.mixins;
import com.atsuishio.superbwarfare.entity.ICannonEntity;
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModMobEffects;
@ -16,6 +17,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import static com.atsuishio.superbwarfare.event.ClientEventHandler.droneFovLerp;
import static com.atsuishio.superbwarfare.event.ClientEventHandler.vehicleFovLerp;
/**
* Author: MrCrayfish
@ -50,6 +52,10 @@ public class MouseHandlerMixin {
return 0.33 / (1 + 0.08 * (droneFovLerp - 1));
}
if (player.getVehicle() instanceof IVehicleEntity iVehicle && iVehicle.isDriver(player) && ClientEventHandler.zoom) {
return 0.33 / (1 + 0.08 * (vehicleFovLerp - 1));
}
if (!stack.is(ModTags.Items.GUN)) {
return original;
}

View file

@ -1,6 +1,6 @@
package com.atsuishio.superbwarfare.network.message;
import com.atsuishio.superbwarfare.entity.ICannonEntity;
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent;
@ -34,7 +34,7 @@ public class VehicleFireMessage {
return;
}
if (player.getVehicle() instanceof ICannonEntity entity) {
if (player.getVehicle() instanceof IVehicleEntity entity) {
entity.cannonShoot(player);
}
}