From c14ab91b83b0eac96bdeb170922ca68c4fb8d265 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Wed, 16 Apr 2025 22:03:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E5=8F=96=E5=BC=80=E7=81=AB=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=A4=84=E7=90=86=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../superbwarfare/event/GunEventHandler.java | 100 ----------- .../superbwarfare/item/gun/GunItem.java | 162 +++++++++++++++++- .../item/gun/PressFireSpecialWeapon.java | 19 -- .../item/gun/ReleaseSpecialWeapon.java | 30 ---- .../item/gun/launcher/JavelinItem.java | 13 +- .../item/gun/launcher/M79Item.java | 5 +- .../item/gun/launcher/RpgItem.java | 5 +- .../item/gun/launcher/SecondaryCataclysm.java | 5 +- .../item/gun/machinegun/M60Item.java | 4 +- .../item/gun/machinegun/MinigunItem.java | 38 ++++ .../item/gun/shotgun/HomemadeShotgunItem.java | 4 +- .../item/gun/sniper/SentinelItem.java | 4 +- .../item/gun/special/BocekItem.java | 115 +++++++++++-- .../item/gun/special/TaserItem.java | 5 +- .../network/message/send/FireKeyMessage.java | 131 +------------- .../network/message/send/ShootMessage.java | 83 +-------- 16 files changed, 330 insertions(+), 393 deletions(-) delete mode 100644 src/main/java/com/atsuishio/superbwarfare/item/gun/PressFireSpecialWeapon.java delete mode 100644 src/main/java/com/atsuishio/superbwarfare/item/gun/ReleaseSpecialWeapon.java diff --git a/src/main/java/com/atsuishio/superbwarfare/event/GunEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/GunEventHandler.java index 87c5ed7bf..2af78e52d 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/GunEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/GunEventHandler.java @@ -1,25 +1,19 @@ package com.atsuishio.superbwarfare.event; import com.atsuishio.superbwarfare.Mod; -import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.event.events.ReloadEvent; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.PressFireSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.item.gun.data.value.AttachmentType; import com.atsuishio.superbwarfare.item.gun.data.value.ReloadState; -import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.tools.Ammo; import com.atsuishio.superbwarfare.tools.InventoryTool; import com.atsuishio.superbwarfare.tools.SoundTool; -import net.minecraft.core.Holder; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ClipContext; @@ -30,8 +24,6 @@ import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.tick.PlayerTickEvent; -import java.util.ArrayList; - @EventBusSubscriber(modid = Mod.MODID) public class GunEventHandler { @@ -171,98 +163,6 @@ public class GunEventHandler { } } - public static void gunShoot(Player player, GunData data, double spared, boolean zoom) { - var stack = data.stack(); - - if (!player.level().isClientSide()) { - if (stack.getItem() instanceof PressFireSpecialWeapon pressFireSpecialWeapon) { - pressFireSpecialWeapon.fireOnPress(player, data, spared, zoom); - } else { - float headshot = (float) data.headshot(); - float damage = (float) data.damage(); - float velocity = (float) (data.velocity() * perkSpeed(data)); - int projectileAmount = data.projectileAmount(); - float bypassArmorRate = (float) data.bypassArmor(); - var perkInstance = data.perk.getInstance(Perk.Type.AMMO); - var perk = perkInstance != null ? perkInstance.perk() : null; - - ProjectileEntity projectile = new ProjectileEntity(player.level()) - .shooter(player) - .damage(perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? projectileAmount * damage : damage) - .damage(damage) - .headShot(headshot) - .zoom(zoom) - .setGunItemId(stack); - - if (perk instanceof AmmoPerk ammoPerk) { - int level = data.perk.getLevel(perk); - - bypassArmorRate += ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0); - projectile.setRGB(ammoPerk.rgb); - - if (!ammoPerk.mobEffects.get().isEmpty()) { - int amplifier; - if (perk.descriptionId.equals("blade_bullet")) { - amplifier = level / 3; - } else if (perk.descriptionId.equals("bread_bullet")) { - amplifier = 1; - } else { - amplifier = level - 1; - } - - ArrayList mobEffectInstances = new ArrayList<>(); - for (MobEffect effect : ammoPerk.mobEffects.get()) { - mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier)); - } - projectile.effect(mobEffectInstances); - } - - if (perk.descriptionId.equals("bread_bullet")) { - projectile.knockback(level * 0.3f); - projectile.forceKnockback(); - } - } - - bypassArmorRate = Math.max(bypassArmorRate, 0); - projectile.bypassArmorRate(bypassArmorRate); - - if (perk == ModPerks.SILVER_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.undeadMultiple(1.0f + 0.5f * level); - } else if (perk == ModPerks.BEAST_BULLET.get()) { - projectile.beast(); - } else if (perk == ModPerks.JHP_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.jhpBullet(level); - } else if (perk == ModPerks.HE_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.heBullet(level); - } else if (perk == ModPerks.INCENDIARY_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.fireBullet(level, stack.is(ModTags.Items.SHOTGUN)); - } - - var dmgPerk = data.perk.get(Perk.Type.DAMAGE); - if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { - int level = data.perk.getLevel(dmgPerk); - projectile.monsterMultiple(0.1f + 0.1f * level); - } - - projectile.setPos(player.getX() - 0.1 * player.getLookAngle().x, player.getEyeY() - 0.1 - 0.1 * player.getLookAngle().y, player.getZ() + -0.1 * player.getLookAngle().z); - projectile.shoot(player, player.getLookAngle().x, player.getLookAngle().y + 0.001f, player.getLookAngle().z, stack.is(ModTags.Items.SHOTGUN) && perk == ModPerks.INCENDIARY_BULLET.get() ? 4.5f : velocity, (float) spared); - player.level().addFreshEntity(projectile); - } - } - } - - public static double perkSpeed(GunData data) { - var perk = data.perk.get(Perk.Type.AMMO); - if (perk instanceof AmmoPerk ammoPerk) { - return ammoPerk.speedRate; - } - return 1; - } - /** * 通用的武器换弹流程 */ diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java index 670420c5b..4a43fb3d8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java @@ -3,12 +3,16 @@ package com.atsuishio.superbwarfare.item.gun; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.client.PoseTool; import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent; +import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import com.atsuishio.superbwarfare.event.GunEventHandler; import com.atsuishio.superbwarfare.init.ModAttachments; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModPerks; +import com.atsuishio.superbwarfare.init.ModTags; import com.atsuishio.superbwarfare.item.CustomRendererItem; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.item.gun.data.value.AttachmentType; +import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.tools.Ammo; import net.minecraft.client.model.HumanoidModel; @@ -18,6 +22,8 @@ import net.minecraft.core.Holder; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.InteractionHand; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.entity.LivingEntity; @@ -490,9 +496,161 @@ public abstract class GunItem extends Item implements CustomRendererItem { } /** - * 添加服务端在开火时的额外行为 + * 服务端在开火前的额外行为 */ - public void onShoot(GunData data, Player player) { + public void beforeShoot(GunData data, Player player, double spread, boolean zoom) { + // 空仓挂机 + if (data.ammo.get() == 1) { + data.holdOpen.set(true); + } + + // TODO 替换左轮判断方式 + if (data.stack.is(ModTags.Items.REVOLVER)) { + data.canImmediatelyShoot.set(true); + } + + // TODO 替换左轮判断方式 + // 判断是否为栓动武器(BoltActionTime > 0),并在开火后给一个需要上膛的状态 + if (data.defaultActionTime() > 0 && data.ammo.get() > (data.stack.is(ModTags.Items.REVOLVER) ? 0 : 1)) { + data.bolt.needed.set(true); + } + + data.ammo.set(data.ammo.get() - 1); + data.isEmpty.set(true); + } + + /** + * 服务端处理开火 + */ + public void onShoot(GunData data, Player player, double spread, boolean zoom) { + if (data.ammo.get() <= 0) return; + + // 开火前事件 + data.item.beforeShoot(data, player, spread, zoom); + + int projectileAmount = data.projectileAmount(); + var perk = data.perk.get(Perk.Type.AMMO); + + // 生成所有子弹 + for (int index0 = 0; index0 < (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 1 : projectileAmount); index0++) { + shootBullet(player, data, spread, zoom); + } + + // TODO 提取对应方法 + // 播放音效 + GunEventHandler.playGunSounds(player, zoom); + } + + /** + * 服务端处理按下开火按键时的额外行为 + */ + public void onFireKeyPress(final GunData data, Player player, boolean zoom) { + if (data.reload.prepareTimer.get() == 0 && data.reloading() && data.ammo.get() > 0) { + data.forceStop.set(true); + } + + player.getData(ModAttachments.PLAYER_VARIABLE).modify(player, cap -> cap.edit = false); + } + + /** + * 服务端处理松开开火按键时的额外行为 + */ + public void onFireKeyRelease(final GunData data, Player player, double power, boolean zoom) { + } + + public static double perkSpeed(GunData data) { + var perk = data.perk.get(Perk.Type.AMMO); + if (perk instanceof AmmoPerk ammoPerk) { + return ammoPerk.speedRate; + } + return 1; + } + + public static double perkDamage(Perk perk) { + if (perk instanceof AmmoPerk ammoPerk) { + return ammoPerk.damageRate; + } + return 1; + } + + /** + * 服务端发射单发子弹 + */ + public void shootBullet(Player player, GunData data, double spread, boolean zoom) { + var stack = data.stack; + + float headshot = (float) data.headshot(); + float damage = (float) data.damage(); + float velocity = (float) (data.velocity() * perkSpeed(data)); + int projectileAmount = data.projectileAmount(); + float bypassArmorRate = (float) data.bypassArmor(); + var perkInstance = data.perk.getInstance(Perk.Type.AMMO); + var perk = perkInstance != null ? perkInstance.perk() : null; + + ProjectileEntity projectile = new ProjectileEntity(player.level()) + .shooter(player) + .damage(perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? projectileAmount * damage : damage) + .headShot(headshot) + .zoom(zoom) + .setGunItemId(stack); + + if (perk instanceof AmmoPerk ammoPerk) { + int level = data.perk.getLevel(perk); + + bypassArmorRate += ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0); + projectile.setRGB(ammoPerk.rgb); + + if (!ammoPerk.mobEffects.get().isEmpty()) { + int amplifier; + if (perk.descriptionId.equals("blade_bullet")) { + amplifier = level / 3; + } else if (perk.descriptionId.equals("bread_bullet")) { + amplifier = 1; + } else { + amplifier = level - 1; + } + + ArrayList mobEffectInstances = new ArrayList<>(); + for (MobEffect effect : ammoPerk.mobEffects.get()) { + mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier)); + } + projectile.effect(mobEffectInstances); + } + + if (perk.descriptionId.equals("bread_bullet")) { + projectile.knockback(level * 0.3f); + projectile.forceKnockback(); + } + } + + bypassArmorRate = Math.max(bypassArmorRate, 0); + projectile.bypassArmorRate(bypassArmorRate); + + if (perk == ModPerks.SILVER_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.undeadMultiple(1.0f + 0.5f * level); + } else if (perk == ModPerks.BEAST_BULLET.get()) { + projectile.beast(); + } else if (perk == ModPerks.JHP_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.jhpBullet(level); + } else if (perk == ModPerks.HE_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.heBullet(level); + } else if (perk == ModPerks.INCENDIARY_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.fireBullet(level, stack.is(ModTags.Items.SHOTGUN)); + } + + var dmgPerk = data.perk.get(Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int level = data.perk.getLevel(dmgPerk); + projectile.monsterMultiple(0.1f + 0.1f * level); + } + + projectile.setPos(player.getX() - 0.1 * player.getLookAngle().x, player.getEyeY() - 0.1 - 0.1 * player.getLookAngle().y, player.getZ() + -0.1 * player.getLookAngle().z); + projectile.shoot(player, player.getLookAngle().x, player.getLookAngle().y + 0.001f, player.getLookAngle().z, stack.is(ModTags.Items.SHOTGUN) && perk == ModPerks.INCENDIARY_BULLET.get() ? 4.5f : velocity, (float) spread); + player.level().addFreshEntity(projectile); } @SubscribeEvent diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/PressFireSpecialWeapon.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/PressFireSpecialWeapon.java deleted file mode 100644 index 17e1b30ee..000000000 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/PressFireSpecialWeapon.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.atsuishio.superbwarfare.item.gun; - -import com.atsuishio.superbwarfare.item.gun.data.GunData; -import net.minecraft.world.entity.player.Player; - -/** - * 不使用普通子弹的按下开火武器的开火处理 - */ -public interface PressFireSpecialWeapon { - - /** - * 按下按键时武器发射处理 - * - * @param player 玩家 - */ - - default void fireOnPress(Player player, GunData data, double spread, boolean zoom) { - } -} diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/ReleaseSpecialWeapon.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/ReleaseSpecialWeapon.java deleted file mode 100644 index d3a9bd27f..000000000 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/ReleaseSpecialWeapon.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.atsuishio.superbwarfare.item.gun; - -import com.atsuishio.superbwarfare.item.gun.data.GunData; -import net.minecraft.world.entity.player.Player; - - -/** - * 拥有特殊开火方式的武器的开火处理 - */ -public interface ReleaseSpecialWeapon { - - - /** - * 按下按键时武器发射处理 - * - * @param player 玩家 - */ - - default void fireOnPress(Player player, final GunData data, boolean zoom) { - } - - /** - * 松开按键时武器发射处理 - * - * @param player 玩家 - */ - default void fireOnRelease(Player player, final GunData data, double power, boolean zoom) { - } - -} diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java index f5c3476f3..1e6e4cb98 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java @@ -11,7 +11,6 @@ import com.atsuishio.superbwarfare.init.ModEnumExtensions; import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.ReleaseSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.network.message.receive.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; @@ -55,7 +54,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; -public class JavelinItem extends GunItem implements GeoItem, ReleaseSpecialWeapon { +public class JavelinItem extends GunItem implements GeoItem { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -270,8 +269,11 @@ public class JavelinItem extends GunItem implements GeoItem, ReleaseSpecialWeapo } @Override - public void fireOnRelease(Player player, final GunData data, double power, boolean zoom) { + public void onFireKeyRelease(GunData data, Player player, double power, boolean zoom) { + super.onFireKeyRelease(data, player, power, zoom); + fire(player); + var tag = data.tag(); tag.putBoolean("Seeking", false); tag.putInt("SeekTime", 0); @@ -283,11 +285,12 @@ public class JavelinItem extends GunItem implements GeoItem, ReleaseSpecialWeapo } @Override - public void fireOnPress(Player player, final GunData data, boolean zoom) { - var tag = data.tag(); + public void onFireKeyPress(GunData data, Player player, boolean zoom) { + super.onFireKeyPress(data, player, zoom); if (!zoom || data.ammo.get() <= 0) return; + var tag = data.tag(); Entity seekingEntity = SeekTool.seekEntity(player, player.level(), 512, 8); if (seekingEntity != null && !player.isCrouching()) { diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/M79Item.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/M79Item.java index 8fda27644..b5cdefa3b 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/M79Item.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/M79Item.java @@ -8,7 +8,6 @@ import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.PressFireSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; @@ -36,7 +35,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; -public class M79Item extends GunItem implements GeoItem, PressFireSpecialWeapon { +public class M79Item extends GunItem implements GeoItem { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -122,7 +121,7 @@ public class M79Item extends GunItem implements GeoItem, PressFireSpecialWeapon } @Override - public void fireOnPress(Player player, final GunData data, double spread, boolean zoom) { + public void shootBullet(Player player, GunData data, double spread, boolean zoom) { if (data.reloading()) return; if (player.level() instanceof ServerLevel serverLevel) { diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/RpgItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/RpgItem.java index d89709b73..fdb0ca3f6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/RpgItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/RpgItem.java @@ -8,7 +8,6 @@ import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.PressFireSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; @@ -41,7 +40,7 @@ import java.util.Set; import java.util.function.Consumer; import java.util.function.Supplier; -public class RpgItem extends GunItem implements GeoItem, PressFireSpecialWeapon { +public class RpgItem extends GunItem implements GeoItem { @Override public String getAmmoDisplayName(GunData data) { @@ -145,7 +144,7 @@ public class RpgItem extends GunItem implements GeoItem, PressFireSpecialWeapon } @Override - public void fireOnPress(Player player, final GunData data, double spread, boolean zoom) { + public void shootBullet(Player player, GunData data, double spread, boolean zoom) { Level level = player.level(); if (data.reloading()) return; diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/SecondaryCataclysm.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/SecondaryCataclysm.java index 8d2fa9222..f560f9af6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/SecondaryCataclysm.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/SecondaryCataclysm.java @@ -10,7 +10,6 @@ import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.item.EnergyStorageItem; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.PressFireSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; @@ -44,7 +43,7 @@ import java.util.ArrayList; import java.util.Optional; import java.util.function.Supplier; -public class SecondaryCataclysm extends GunItem implements GeoItem, PressFireSpecialWeapon, EnergyStorageItem { +public class SecondaryCataclysm extends GunItem implements GeoItem, EnergyStorageItem { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -232,7 +231,7 @@ public class SecondaryCataclysm extends GunItem implements GeoItem, PressFireSpe } @Override - public void fireOnPress(Player player, final GunData data, double spread, boolean zoom) { + public void shootBullet(Player player, GunData data, double spread, boolean zoom) { if (data.reloading()) return; ItemStack stack = data.stack(); diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/M60Item.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/M60Item.java index a2bfbaccd..016b74563 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/M60Item.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/M60Item.java @@ -162,8 +162,8 @@ public class M60Item extends GunItem implements GeoItem { } @Override - public void onShoot(GunData data, Player player) { - super.onShoot(data, player); + public void beforeShoot(GunData data, Player player, double spread, boolean zoom) { + super.beforeShoot(data, player, spread, zoom); if (data.ammo.get() <= 5) { data.hideBulletChain.set(true); diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/MinigunItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/MinigunItem.java index c941b5e93..e9c92df13 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/MinigunItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/machinegun/MinigunItem.java @@ -6,11 +6,13 @@ import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModEnumExtensions; import com.atsuishio.superbwarfare.init.ModParticleTypes; import com.atsuishio.superbwarfare.init.ModPerks; +import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.tools.NBTTool; import com.atsuishio.superbwarfare.tools.ParticleTool; +import com.atsuishio.superbwarfare.tools.SoundTool; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.particles.ParticleTypes; @@ -19,6 +21,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; @@ -153,6 +156,41 @@ public class MinigunItem extends GunItem implements GeoItem { data.save(); } + @Override + public void onShoot(GunData data, Player player, double spread, boolean zoom) { + var tag = data.tag(); + + if (!data.hasAmmo(player)) return; + + // TODO 替换为通用过热处理 + tag.putDouble("heat", (tag.getDouble("heat") + 0.1)); + if (tag.getDouble("heat") >= 50.5) { + tag.putDouble("overheat", 40); + player.getCooldowns().addCooldown(data.item(), 40); + if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) { + SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 2f, 1f); + } + } + + float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat"))); + var perk = data.perk.get(Perk.Type.AMMO); + + if (!player.level().isClientSide() && player instanceof ServerPlayer) { + float soundRadius = (float) data.soundRadius(); + + player.playSound(ModSounds.MINIGUN_FIRE_3P.get(), soundRadius * 0.2f, pitch); + player.playSound(ModSounds.MINIGUN_FAR.get(), soundRadius * 0.5f, pitch); + player.playSound(ModSounds.MINIGUN_VERYFAR.get(), soundRadius, pitch); + + if (perk == ModPerks.BEAST_BULLET.get()) { + player.playSound(ModSounds.HENG.get(), 4f, pitch); + } + } + + shootBullet(player, data, spread, zoom); + data.consumeAmmo(player, 1); + } + @Override public ResourceLocation getGunIcon() { return Mod.loc("textures/gun_icon/minigun_icon.png"); diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/shotgun/HomemadeShotgunItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/shotgun/HomemadeShotgunItem.java index 7658856da..a66c976cb 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/shotgun/HomemadeShotgunItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/shotgun/HomemadeShotgunItem.java @@ -124,8 +124,8 @@ public class HomemadeShotgunItem extends GunItem implements GeoItem { } @Override - public void onShoot(GunData data, Player player) { - super.onShoot(data, player); + public void beforeShoot(GunData data, Player player, double spread, boolean zoom) { + super.beforeShoot(data, player, spread, zoom); var stack = data.stack(); stack.hurtAndBreak(1, (ServerLevel) player.level(), player, p -> { diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/sniper/SentinelItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/sniper/SentinelItem.java index c7b66991a..080f52643 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/sniper/SentinelItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/sniper/SentinelItem.java @@ -191,8 +191,8 @@ public class SentinelItem extends GunItem implements GeoItem, EnergyStorageItem } @Override - public void onShoot(GunData data, Player player) { - super.onShoot(data, player); + public void beforeShoot(GunData data, Player player, double spread, boolean zoom) { + super.beforeShoot(data, player, spread, zoom); var cap = data.stack.getCapability(Capabilities.EnergyStorage.ITEM); if (cap != null) { diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/special/BocekItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/special/BocekItem.java index 764115c90..d281d6461 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/special/BocekItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/special/BocekItem.java @@ -3,11 +3,11 @@ package com.atsuishio.superbwarfare.item.gun.special; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.client.renderer.item.BocekItemRenderer; import com.atsuishio.superbwarfare.client.tooltip.component.BocekImageComponent; +import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.ReleaseSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.network.message.receive.ShootClientMessage; import com.atsuishio.superbwarfare.perk.AmmoPerk; @@ -17,9 +17,12 @@ import com.atsuishio.superbwarfare.tools.InventoryTool; import com.atsuishio.superbwarfare.tools.SoundTool; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.Holder; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.tooltip.TooltipComponent; @@ -37,12 +40,11 @@ import software.bernie.geckolib.renderer.GeoItemRenderer; import software.bernie.geckolib.util.GeckoLibUtil; import javax.annotation.ParametersAreNonnullByDefault; +import java.util.ArrayList; import java.util.Optional; import java.util.function.Supplier; -import static com.atsuishio.superbwarfare.network.message.send.FireKeyMessage.spawnBullet; - -public class BocekItem extends GunItem implements GeoItem, ReleaseSpecialWeapon { +public class BocekItem extends GunItem implements GeoItem { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -145,14 +147,17 @@ public class BocekItem extends GunItem implements GeoItem, ReleaseSpecialWeapon } @Override - public void fireOnRelease(Player player, final GunData data, double power, boolean zoom) { - if (player.level().isClientSide()) return; + public void onShoot(GunData data, Player player, double spread, boolean zoom) { + } - ItemStack stack = player.getMainHandItem(); - var perk = data.perk.get(Perk.Type.AMMO); + @Override + public void onFireKeyRelease(GunData data, Player player, double power, boolean zoom) { + super.onFireKeyRelease(data, player, power, zoom); if (data.ammo.get() == 0) return; + var perk = data.perk.get(Perk.Type.AMMO); + if (player instanceof ServerPlayer serverPlayer) { SoundTool.stopSound(serverPlayer, ModSounds.BOCEK_PULL_1P.getId(), SoundSource.PLAYERS); SoundTool.stopSound(serverPlayer, ModSounds.BOCEK_PULL_3P.getId(), SoundSource.PLAYERS); @@ -161,13 +166,13 @@ public class BocekItem extends GunItem implements GeoItem, ReleaseSpecialWeapon if (power * 12 >= 6) { if (zoom) { - spawnBullet(player, power, true); + spawnBullet(data, player, power, true); SoundTool.playLocalSound(player, ModSounds.BOCEK_ZOOM_FIRE_1P.get(), 10, 1); player.playSound(ModSounds.BOCEK_ZOOM_FIRE_3P.get(), 2, 1); } else { for (int i = 0; i < (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 1 : 10); i++) { - spawnBullet(player, power, false); + spawnBullet(data, player, power, false); } SoundTool.playLocalSound(player, ModSounds.BOCEK_SHATTER_CAP_FIRE_1P.get(), 10, 1); @@ -182,9 +187,97 @@ public class BocekItem extends GunItem implements GeoItem, ReleaseSpecialWeapon } } - GunsTool.setGunIntTag(GunData.from(stack).tag, "ArrowEmpty", 7); + GunsTool.setGunIntTag(data.tag, "ArrowEmpty", 7); data.ammo.set(data.ammo.get() - 1); data.save(); } } + + + public void spawnBullet(GunData data, Player player, double power, boolean zoom) { + ItemStack stack = data.stack; + + var perk = data.perk.get(Perk.Type.AMMO); + float headshot = (float) data.headshot(); + float velocity = (float) (24 * power * (float) perkSpeed(data)); + float bypassArmorRate = (float) data.bypassArmor(); + double damage; + + float spread; + if (zoom) { + spread = 0.01f; + damage = 0.08333333 * data.damage() * + 12 * power * perkDamage(perk); + } else { + spread = perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 0.5f : 2.5f; + damage = (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 0.08333333 : 0.008333333) * + data.damage() * 12 * power * perkDamage(perk); + } + + ProjectileEntity projectile = new ProjectileEntity(player.level()) + .shooter(player) + .headShot(headshot) + .zoom(zoom) + .setGunItemId(stack); + + if (perk instanceof AmmoPerk ammoPerk) { + int level = data.perk.getLevel(perk); + + bypassArmorRate += ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0); + projectile.setRGB(ammoPerk.rgb); + + if (!ammoPerk.mobEffects.get().isEmpty()) { + int amplifier; + if (perk.descriptionId.equals("blade_bullet")) { + amplifier = level / 3; + } else if (perk.descriptionId.equals("bread_bullet")) { + amplifier = 1; + } else { + amplifier = level - 1; + } + + ArrayList mobEffectInstances = new ArrayList<>(); + for (MobEffect effect : ammoPerk.mobEffects.get()) { + mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier)); + } + projectile.effect(mobEffectInstances); + } + + if (perk.descriptionId.equals("bread_bullet")) { + projectile.knockback(level * 0.3f); + projectile.forceKnockback(); + } + } + + bypassArmorRate = Math.max(bypassArmorRate, 0); + projectile.bypassArmorRate(bypassArmorRate); + + if (perk == ModPerks.SILVER_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.undeadMultiple(1.0f + 0.5f * level); + } else if (perk == ModPerks.BEAST_BULLET.get()) { + projectile.beast(); + } else if (perk == ModPerks.JHP_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.jhpBullet(level); + } else if (perk == ModPerks.HE_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.heBullet(level); + } else if (perk == ModPerks.INCENDIARY_BULLET.get()) { + int level = data.perk.getLevel(perk); + projectile.fireBullet(level, !zoom); + } + + var dmgPerk = data.perk.get(Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int perkLevel = data.perk.getLevel(dmgPerk); + projectile.monsterMultiple(0.1f + 0.1f * perkLevel); + } + + projectile.setPos(player.getX() - 0.1 * player.getLookAngle().x, player.getEyeY() - 0.1 - 0.1 * player.getLookAngle().y, player.getZ() + -0.1 * player.getLookAngle().z); + projectile.shoot(player, player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (!zoom && perk == ModPerks.INCENDIARY_BULLET.get() ? 0.2f : 1) * velocity, spread); + projectile.damage((float) damage); + + player.level().addFreshEntity(projectile); + } } \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/special/TaserItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/special/TaserItem.java index 037a46614..8744ec6eb 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/special/TaserItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/special/TaserItem.java @@ -10,7 +10,6 @@ import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.item.EnergyStorageItem; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.PressFireSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.perk.Perk; import net.minecraft.client.Minecraft; @@ -39,7 +38,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; -public class TaserItem extends GunItem implements GeoItem, EnergyStorageItem, PressFireSpecialWeapon { +public class TaserItem extends GunItem implements GeoItem, EnergyStorageItem { public static final int MAX_ENERGY = 6000; @@ -185,7 +184,7 @@ public class TaserItem extends GunItem implements GeoItem, EnergyStorageItem, Pr } @Override - public void fireOnPress(Player player, final GunData data, double spread, boolean zoom) { + public void shootBullet(Player player, GunData data, double spread, boolean zoom) { if (data.reloading()) return; ItemStack stack = data.stack(); diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireKeyMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireKeyMessage.java index bcbca65d0..a1a0db0f9 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireKeyMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireKeyMessage.java @@ -1,30 +1,19 @@ package com.atsuishio.superbwarfare.network.message.send; import com.atsuishio.superbwarfare.Mod; -import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.event.GunEventHandler; -import com.atsuishio.superbwarfare.init.ModAttachments; -import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.init.ModTags; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.item.gun.ReleaseSpecialWeapon; import com.atsuishio.superbwarfare.item.gun.data.GunData; -import com.atsuishio.superbwarfare.perk.AmmoPerk; -import com.atsuishio.superbwarfare.perk.Perk; import io.netty.buffer.ByteBuf; -import net.minecraft.core.Holder; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; - /** * 开火按键按下/松开时的处理 */ @@ -54,24 +43,14 @@ public record FireKeyMessage(int msgType, double power, boolean zoom) implements handleGunBolt(player, stack); - if (type == 0) { - if (data.reload.prepareTimer.get() == 0 && data.reloading() && data.ammo.get() > 0) { - data.forceStop.set(true); - } - - player.getData(ModAttachments.PLAYER_VARIABLE).modify(player, cap -> cap.edit = false); - // 按下开火 - if (stack.getItem() instanceof ReleaseSpecialWeapon releaseSpecialWeapon) { - releaseSpecialWeapon.fireOnPress(player, data, zoom); - } + data.item.onFireKeyPress(data, player, zoom); } else if (type == 1) { // 松开开火 - if (stack.getItem() instanceof ReleaseSpecialWeapon releaseSpecialWeapon) { - releaseSpecialWeapon.fireOnRelease(player, data, power, zoom); - } + data.item.onFireKeyRelease(data, player, power, zoom); } + data.save(); } @@ -93,110 +72,6 @@ public record FireKeyMessage(int msgType, double power, boolean zoom) implements } } - public static double perkDamage(Perk perk) { - if (perk instanceof AmmoPerk ammoPerk) { - return ammoPerk.damageRate; - } - return 1; - } - - public static double perkSpeed(Perk perk) { - if (perk instanceof AmmoPerk ammoPerk) { - return ammoPerk.speedRate; - } - return 1; - } - - public static void spawnBullet(Player player, double power, boolean zoom) { - ItemStack stack = player.getMainHandItem(); - if (player.level().isClientSide()) return; - if (!(stack.getItem() instanceof GunItem)) return; - var data = GunData.from(stack); - - var perk = data.perk.get(Perk.Type.AMMO); - float headshot = (float) data.headshot(); - float velocity = (float) (24 * power * (float) perkSpeed(perk)); - float bypassArmorRate = (float) data.bypassArmor(); - double damage; - - float spread; - if (zoom) { - spread = 0.01f; - damage = 0.08333333 * data.damage() * - 12 * power * perkDamage(perk); - } else { - spread = perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 0.5f : 2.5f; - damage = (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 0.08333333 : 0.008333333) * - data.damage() * 12 * power * perkDamage(perk); - } - - ProjectileEntity projectile = new ProjectileEntity(player.level()) - .shooter(player) - .headShot(headshot) - .zoom(zoom) - .setGunItemId(stack); - - if (perk instanceof AmmoPerk ammoPerk) { - int level = data.perk.getLevel(perk); - - bypassArmorRate += ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0); - projectile.setRGB(ammoPerk.rgb); - - if (!ammoPerk.mobEffects.get().isEmpty()) { - int amplifier; - if (perk.descriptionId.equals("blade_bullet")) { - amplifier = level / 3; - } else if (perk.descriptionId.equals("bread_bullet")) { - amplifier = 1; - } else { - amplifier = level - 1; - } - - ArrayList mobEffectInstances = new ArrayList<>(); - for (MobEffect effect : ammoPerk.mobEffects.get()) { - mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier)); - } - projectile.effect(mobEffectInstances); - } - - if (perk.descriptionId.equals("bread_bullet")) { - projectile.knockback(level * 0.3f); - projectile.forceKnockback(); - } - } - - bypassArmorRate = Math.max(bypassArmorRate, 0); - projectile.bypassArmorRate(bypassArmorRate); - - if (perk == ModPerks.SILVER_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.undeadMultiple(1.0f + 0.5f * level); - } else if (perk == ModPerks.BEAST_BULLET.get()) { - projectile.beast(); - } else if (perk == ModPerks.JHP_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.jhpBullet(level); - } else if (perk == ModPerks.HE_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.heBullet(level); - } else if (perk == ModPerks.INCENDIARY_BULLET.get()) { - int level = data.perk.getLevel(perk); - projectile.fireBullet(level, !zoom); - } - - var dmgPerk = data.perk.get(Perk.Type.DAMAGE); - if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { - int perkLevel = data.perk.getLevel(dmgPerk); - projectile.monsterMultiple(0.1f + 0.1f * perkLevel); - } - - projectile.setPos(player.getX() - 0.1 * player.getLookAngle().x, player.getEyeY() - 0.1 - 0.1 * player.getLookAngle().y, player.getZ() + -0.1 * player.getLookAngle().z); - projectile.shoot(player, player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (!zoom && perk == ModPerks.INCENDIARY_BULLET.get() ? 0.2f : 1) * velocity, spread); - projectile.damage((float) damage); - - player.level().addFreshEntity(projectile); - } - @Override public @NotNull Type type() { return TYPE; diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/ShootMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ShootMessage.java index 62ff63c51..d7b7ed073 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/send/ShootMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ShootMessage.java @@ -1,24 +1,13 @@ package com.atsuishio.superbwarfare.network.message.send; import com.atsuishio.superbwarfare.Mod; -import com.atsuishio.superbwarfare.event.GunEventHandler; -import com.atsuishio.superbwarfare.init.ModItems; -import com.atsuishio.superbwarfare.init.ModPerks; -import com.atsuishio.superbwarfare.init.ModSounds; -import com.atsuishio.superbwarfare.init.ModTags; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.data.GunData; -import com.atsuishio.superbwarfare.perk.AmmoPerk; -import com.atsuishio.superbwarfare.perk.Perk; -import com.atsuishio.superbwarfare.tools.InventoryTool; -import com.atsuishio.superbwarfare.tools.SoundTool; import io.netty.buffer.ByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; @@ -38,79 +27,13 @@ public record ShootMessage(double spread, boolean zoom) implements CustomPacketP pressAction(context.player(), message.spread, message.zoom); } - public static void pressAction(Player player, double spared, boolean zoom) { - ItemStack stack = player.getMainHandItem(); + public static void pressAction(Player player, double spread, boolean zoom) { + var stack = player.getMainHandItem(); if (!(stack.getItem() instanceof GunItem)) return; var data = GunData.from(stack); - var tag = data.tag(); - if (stack.is(ModTags.Items.NORMAL_GUN)) { - int projectileAmount = data.projectileAmount(); + data.item.onShoot(data, player, spread, zoom); - if (data.ammo.get() > 0) { - // 空仓挂机 - if (data.ammo.get() == 1) { - data.holdOpen.set(true); - } - - // TODO 替换左轮判断方式 - if (stack.is(ModTags.Items.REVOLVER)) { - data.canImmediatelyShoot.set(true); - } - - // TODO 替换左轮判断方式 - // 判断是否为栓动武器(BoltActionTime > 0),并在开火后给一个需要上膛的状态 - if (data.defaultActionTime() > 0 && data.ammo.get() > (stack.is(ModTags.Items.REVOLVER) ? 0 : 1)) { - data.bolt.needed.set(true); - } - - // 调用事件 - data.item.onShoot(data, player); - - data.ammo.set(data.ammo.get() - 1); - data.isEmpty.set(true); - - var perk = data.perk.get(Perk.Type.AMMO); - - for (int index0 = 0; index0 < (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 1 : projectileAmount); index0++) { - GunEventHandler.gunShoot(player, data, spared, zoom); - } - - GunEventHandler.playGunSounds(player, zoom); - } - } else if (stack.is(ModItems.MINIGUN.get())) { - if (data.hasAmmo(player)) { - // TODO 替换为通用过热处理 - tag.putDouble("heat", (tag.getDouble("heat") + 0.1)); - if (tag.getDouble("heat") >= 50.5) { - tag.putDouble("overheat", 40); - player.getCooldowns().addCooldown(stack.getItem(), 40); - if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 2f, 1f); - } - } - - float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat"))); - var perk = data.perk.get(Perk.Type.AMMO); - - if (!player.level().isClientSide() && player instanceof ServerPlayer) { - float soundRadius = (float) data.soundRadius(); - - player.playSound(ModSounds.MINIGUN_FIRE_3P.get(), soundRadius * 0.2f, pitch); - player.playSound(ModSounds.MINIGUN_FAR.get(), soundRadius * 0.5f, pitch); - player.playSound(ModSounds.MINIGUN_VERYFAR.get(), soundRadius, pitch); - - if (perk == ModPerks.BEAST_BULLET.get()) { - player.playSound(ModSounds.HENG.get(), 4f, pitch); - } - } - - GunEventHandler.gunShoot(player, data, spared, false); - if (!InventoryTool.hasCreativeAmmoBox(player)) { - data.consumeAmmo(player, 1); - } - } - } data.save(); }