From c3bdda1a4743237fefd80e741b0515e1893043e6 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Tue, 11 Mar 2025 01:36:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BE=AE=E5=9E=8B=E5=AF=BC?= =?UTF-8?q?=E5=BC=B9=EF=BC=8C=E9=87=8D=E6=9E=84=E7=89=B9=E6=AE=8A=E6=AD=A6?= =?UTF-8?q?=E5=99=A8=E5=8F=91=E5=B0=84=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/init/ModPerks.java | 4 + .../item/gun/SpecialFireWeapon.java | 29 ++ .../item/gun/launcher/JavelinItem.java | 116 ++++- .../item/gun/launcher/M79Item.java | 61 ++- .../item/gun/launcher/RpgItem.java | 74 ++- .../item/gun/launcher/SecondaryCataclysm.java | 84 ++- .../item/gun/special/BocekItem.java | 71 ++- .../item/gun/special/TaserItem.java | 53 +- .../network/message/FireMessage.java | 477 +----------------- .../superbwarfare/perk/PerkHelper.java | 147 +++--- .../assets/superbwarfare/lang/en_us.json | 2 + .../assets/superbwarfare/lang/zh_cn.json | 2 + 12 files changed, 566 insertions(+), 554 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/item/gun/SpecialFireWeapon.java diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java b/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java index 81042a479..660b0c38c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java @@ -45,6 +45,10 @@ public class ModPerks { public static final RegistryObject INCENDIARY_BULLET = AMMO_PERKS.register("incendiary_bullet", () -> new AmmoPerk(new AmmoPerk.Builder("incendiary_bullet", Perk.Type.AMMO).bypassArmorRate(-0.4f).damageRate(0.7f).speedRate(0.75f).slug(false).rgb(230, 131, 65))); + public static final RegistryObject MICRO_MISSILE = AMMO_PERKS.register("micro_missile", + () -> new AmmoPerk(new AmmoPerk.Builder("micro_missile", Perk.Type.AMMO).damageRate(1.25f).speedRate(1.2f))); + + /** * Functional Perks */ diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/SpecialFireWeapon.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/SpecialFireWeapon.java new file mode 100644 index 000000000..fdcf1a744 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/SpecialFireWeapon.java @@ -0,0 +1,29 @@ +package com.atsuishio.superbwarfare.item.gun; + +import net.minecraft.world.entity.player.Player; + + +/** + * 拥有特殊开火方式的武器的开火处理 + */ +public interface SpecialFireWeapon { + + + /** + * 按下按键时武器发射处理 + * + * @param player 玩家 + */ + + default void fireOnPress(Player player) { + } + + /** + * 松开按键时武器发射处理 + * + * @param player 玩家 + */ + default void fireOnRelease(Player player) { + } + +} 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 00a2ad1fe..8a5f59f95 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 @@ -5,12 +5,17 @@ import com.atsuishio.superbwarfare.client.PoseTool; import com.atsuishio.superbwarfare.client.renderer.item.JavelinItemRenderer; import com.atsuishio.superbwarfare.client.tooltip.component.LauncherImageComponent; import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity; +import com.atsuishio.superbwarfare.entity.projectile.JavelinMissileEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; 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.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.ModVariables; +import com.atsuishio.superbwarfare.network.message.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.*; @@ -18,11 +23,16 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ClientboundStopSoundPacket; 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.SoundEvents; import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; @@ -32,10 +42,14 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.client.extensions.common.IClientItemExtensions; +import net.minecraftforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; +import org.joml.Vector3d; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.core.animation.AnimatableManager; @@ -50,7 +64,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Consumer; -public class JavelinItem extends GunItem implements GeoItem { +public class JavelinItem extends GunItem implements GeoItem, SpecialFireWeapon { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -165,7 +179,7 @@ public class JavelinItem extends GunItem implements GeoItem { if (tag.getInt("GuideType") == 0) { if (seekingEntity != null && seekingEntity == targetEntity) { tag.putInt("SeekTime", tag.getInt("SeekTime") + 1); - if (tag.getInt("SeekTime") > 0 && (!seekingEntity.getPassengers().isEmpty() || seekingEntity instanceof VehicleEntity) && seekingEntity.tickCount %3 == 0) { + if (tag.getInt("SeekTime") > 0 && (!seekingEntity.getPassengers().isEmpty() || seekingEntity instanceof VehicleEntity) && seekingEntity.tickCount % 3 == 0) { seekingEntity.level().playSound(null, seekingEntity.getOnPos(), seekingEntity instanceof Pig ? SoundEvents.PIG_HURT : ModSounds.LOCKING_WARNING.get(), SoundSource.PLAYERS, 1, 1f); } } else { @@ -180,7 +194,7 @@ public class JavelinItem extends GunItem implements GeoItem { if (player instanceof ServerPlayer serverPlayer) { SoundTool.playLocalSound(serverPlayer, ModSounds.JAVELIN_LOCKON.get(), 1, 1); } - if ((!seekingEntity.getPassengers().isEmpty() || seekingEntity instanceof VehicleEntity) && seekingEntity.tickCount %2 == 0) { + if ((!seekingEntity.getPassengers().isEmpty() || seekingEntity instanceof VehicleEntity) && seekingEntity.tickCount % 2 == 0) { seekingEntity.level().playSound(null, seekingEntity.getOnPos(), seekingEntity instanceof Pig ? SoundEvents.PIG_HURT : ModSounds.LOCKED_WARNING.get(), SoundSource.PLAYERS, 1, 0.95f); } } @@ -232,6 +246,7 @@ public class JavelinItem extends GunItem implements GeoItem { @Override public boolean canApplyPerk(Perk perk) { + if (perk == ModPerks.MICRO_MISSILE.get()) return false; return PerkHelper.LAUNCHER_PERKS.test(perk); } @@ -244,4 +259,99 @@ public class JavelinItem extends GunItem implements GeoItem { public boolean isMagazineReload(ItemStack stack) { return true; } + + private void fire(Player player) { + Level level = player.level(); + ItemStack stack = player.getMainHandItem(); + CompoundTag tag = stack.getOrCreateTag(); + + if (tag.getInt("SeekTime") < 20) return; + + float yRot = player.getYRot() + 360; + yRot = (yRot + 90) % 360; + + var firePos = new Vector3d(0, -0.2, 0.15); + firePos.rotateZ(-player.getXRot() * Mth.DEG_TO_RAD); + firePos.rotateY(-yRot * Mth.DEG_TO_RAD); + + if (player.level() instanceof ServerLevel serverLevel) { + JavelinMissileEntity missileEntity = new JavelinMissileEntity(player, level, + (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0), + stack.getOrCreateTag().getInt("GuideType"), + new Vec3(stack.getOrCreateTag().getDouble("TargetPosX"), stack.getOrCreateTag().getDouble("TargetPosY"), stack.getOrCreateTag().getDouble("TargetPosZ"))); + + var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); + missileEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); + } + + missileEntity.setPos(player.getX() + firePos.x, player.getEyeY() + firePos.y, player.getZ() + firePos.z); + missileEntity.shoot(player.getLookAngle().x, player.getLookAngle().y + 0.3, player.getLookAngle().z, 3f, 1); + missileEntity.setTargetUuid(tag.getString("TargetEntity")); + missileEntity.setAttackMode(tag.getBoolean("TopMode")); + + level.addFreshEntity(missileEntity); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, + player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y, + player.getZ() + 1.8 * player.getLookAngle().z, + 30, 0.4, 0.4, 0.4, 0.005, true); + + var serverPlayer = (ServerPlayer) player; + + SoundTool.playLocalSound(serverPlayer, ModSounds.JAVELIN_FIRE_1P.get(), 2, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.JAVELIN_FIRE_3P.get(), SoundSource.PLAYERS, 4, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.JAVELIN_FAR.get(), SoundSource.PLAYERS, 10, 1); + + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); + } + + player.getCooldowns().addCooldown(stack.getItem(), 10); + GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); + } + + @Override + public void fireOnRelease(Player player) { + var tag = player.getMainHandItem().getOrCreateTag(); + fire(player); + tag.putBoolean("Seeking", false); + tag.putInt("SeekTime", 0); + tag.putString("TargetEntity", "none"); + if (player instanceof ServerPlayer serverPlayer) { + var clientboundstopsoundpacket = new ClientboundStopSoundPacket(new ResourceLocation(ModUtils.MODID, "javelin_lock"), SoundSource.PLAYERS); + serverPlayer.connection.send(clientboundstopsoundpacket); + } + } + + @Override + public void fireOnPress(Player player) { + var stack = player.getMainHandItem(); + var tag = stack.getOrCreateTag(); + + if (!player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null) + .map(c -> c.zoom) + .orElse(false) + || GunsTool.getGunIntTag(stack, "Ammo", 0) <= 0 + ) return; + + Entity seekingEntity = SeekTool.seekEntity(player, player.level(), 512, 8); + + if (seekingEntity != null && !player.isCrouching()) { + tag.putInt("GuideType", 0); + tag.putString("TargetEntity", seekingEntity.getStringUUID()); + } else { + BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)), + ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)); + Vec3 hitPos = result.getLocation(); + + tag.putInt("GuideType", 1); + tag.putDouble("TargetPosX", hitPos.x); + tag.putDouble("TargetPosY", hitPos.y); + tag.putDouble("TargetPosZ", hitPos.z); + } + tag.putBoolean("Seeking", true); + tag.putInt("SeekTime", 0); + } } \ No newline at end of file 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 cdace2b47..b2600f524 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 @@ -4,20 +4,31 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.client.PoseTool; import com.atsuishio.superbwarfare.client.renderer.item.M79ItemRenderer; import com.atsuishio.superbwarfare.client.tooltip.component.LauncherImageComponent; +import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; 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.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.ModVariables; +import com.atsuishio.superbwarfare.network.message.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.ParticleTool; +import com.atsuishio.superbwarfare.tools.SoundTool; import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.core.particles.ParticleTypes; 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.world.InteractionHand; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; @@ -30,6 +41,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; import net.minecraft.world.level.Level; import net.minecraftforge.client.extensions.common.IClientItemExtensions; +import net.minecraftforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; @@ -44,7 +56,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Consumer; -public class M79Item extends GunItem implements GeoItem { +public class M79Item extends GunItem implements GeoItem, SpecialFireWeapon { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -175,4 +187,51 @@ public class M79Item extends GunItem implements GeoItem { public boolean isMagazineReload(ItemStack stack) { return true; } + + @Override + public void fireOnPress(Player player) { + ItemStack stack = player.getMainHandItem(); + if (GunsTool.getGunBooleanTag(stack, "Reloading")) return; + if (player.getCooldowns().isOnCooldown(stack.getItem()) || GunsTool.getGunIntTag(stack, "Ammo", 0) <= 0) return; + + boolean zooming = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).map(c -> c.zoom).orElse(false); + double spread = GunsTool.getGunDoubleTag(stack, "Spread"); + + if (player.level() instanceof ServerLevel serverLevel) { + GunGrenadeEntity gunGrenadeEntity = new GunGrenadeEntity(player, serverLevel, + (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0)); + + var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); + gunGrenadeEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); + } + + gunGrenadeEntity.setNoGravity(PerkHelper.getPerkByType(stack, Perk.Type.AMMO) == ModPerks.MICRO_MISSILE.get()); + + gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); + gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), + (float) (zooming ? 0.1 : spread)); + serverLevel.addFreshEntity(gunGrenadeEntity); + + ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, + player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y, + player.getZ() + 1.8 * player.getLookAngle().z, + 4, 0.1, 0.1, 0.1, 0.002, true); + + var serverPlayer = (ServerPlayer) player; + + SoundTool.playLocalSound(serverPlayer, ModSounds.M_79_FIRE_1P.get(), 2, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_79_FIRE_3P.get(), SoundSource.PLAYERS, 2, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_79_FAR.get(), SoundSource.PLAYERS, 5, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_79_VERYFAR.get(), SoundSource.PLAYERS, 10, 1); + + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); + } + + player.getCooldowns().addCooldown(stack.getItem(), 2); + GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); + } } \ No newline at end of file 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 ea2c36e40..7f6f1ed6e 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 @@ -4,20 +4,32 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.client.PoseTool; import com.atsuishio.superbwarfare.client.renderer.item.RpgItemRenderer; import com.atsuishio.superbwarfare.client.tooltip.component.LauncherImageComponent; +import com.atsuishio.superbwarfare.entity.projectile.RpgRocketEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; 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.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.ModVariables; +import com.atsuishio.superbwarfare.network.message.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.ParticleTool; +import com.atsuishio.superbwarfare.tools.SoundTool; import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; 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.world.InteractionHand; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; @@ -30,6 +42,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; import net.minecraft.world.level.Level; import net.minecraftforge.client.extensions.common.IClientItemExtensions; +import net.minecraftforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; @@ -44,7 +57,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Consumer; -public class RpgItem extends GunItem implements GeoItem { +public class RpgItem extends GunItem implements GeoItem, SpecialFireWeapon { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -184,4 +197,63 @@ public class RpgItem extends GunItem implements GeoItem { public boolean isMagazineReload(ItemStack stack) { return true; } + + @Override + public void fireOnPress(Player player) { + Level level = player.level(); + ItemStack stack = player.getMainHandItem(); + CompoundTag tag = stack.getOrCreateTag(); + + if (GunsTool.getGunBooleanTag(stack, "Reloading") + || player.getCooldowns().isOnCooldown(stack.getItem()) + || GunsTool.getGunIntTag(stack, "Ammo", 0) <= 0 + ) return; + + boolean zoom = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).map(c -> c.zoom).orElse(false); + double spread = GunsTool.getGunDoubleTag(stack, "Spread"); + + if (player.level() instanceof ServerLevel serverLevel) { + RpgRocketEntity rocketEntity = new RpgRocketEntity(player, level, + (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0)); + + var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); + rocketEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); + } + + if (PerkHelper.getPerkByType(stack, Perk.Type.AMMO) == ModPerks.MICRO_MISSILE.get()) { + rocketEntity.setNoGravity(true); + } + + rocketEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); + rocketEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), + (float) (zoom ? 0.1 : spread)); + level.addFreshEntity(rocketEntity); + + ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, + player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y, + player.getZ() + 1.8 * player.getLookAngle().z, + 30, 0.4, 0.4, 0.4, 0.005, true); + + var serverPlayer = (ServerPlayer) player; + + SoundTool.playLocalSound(serverPlayer, ModSounds.RPG_FIRE_1P.get(), 2, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.RPG_FIRE_3P.get(), SoundSource.PLAYERS, 2, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.RPG_FAR.get(), SoundSource.PLAYERS, 5, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.RPG_VERYFAR.get(), SoundSource.PLAYERS, 10, 1); + + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); + } + + if (GunsTool.getGunIntTag(stack, "Ammo", 0) == 1) { + tag.putBoolean("empty", true); + GunsTool.setGunBooleanTag(stack, "CloseHammer", true); + } + + player.getCooldowns().addCooldown(stack.getItem(), 10); + GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); + } } \ No newline at end of file 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 b472aa875..e42076052 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 @@ -5,22 +5,34 @@ import com.atsuishio.superbwarfare.capability.energy.ItemEnergyProvider; import com.atsuishio.superbwarfare.client.PoseTool; import com.atsuishio.superbwarfare.client.renderer.item.SecondaryCataclysmRenderer; import com.atsuishio.superbwarfare.client.tooltip.component.SecondaryCataclysmImageComponent; +import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; 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.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.ModVariables; +import com.atsuishio.superbwarfare.network.message.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.ParticleTool; import com.atsuishio.superbwarfare.tools.RarityTool; +import com.atsuishio.superbwarfare.tools.SoundTool; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; @@ -37,6 +49,7 @@ import net.minecraft.world.level.Level; import net.minecraftforge.client.extensions.common.IClientItemExtensions; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; @@ -53,15 +66,14 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; -public class SecondaryCataclysm extends GunItem implements GeoItem { - private final Supplier energyCapacity; +public class SecondaryCataclysm extends GunItem implements GeoItem, SpecialFireWeapon { + private final Supplier energyCapacity = () -> 24000; private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; public SecondaryCataclysm() { super(new Properties().stacksTo(1).fireResistant().rarity(RarityTool.LEGENDARY)); - this.energyCapacity = () -> 24000; } @Override @@ -278,7 +290,7 @@ public class SecondaryCataclysm extends GunItem implements GeoItem { if (slot == EquipmentSlot.MAINHAND) { map = HashMultimap.create(map); map.put(Attributes.ATTACK_DAMAGE, - new AttributeModifier(uuid, ModUtils.ATTRIBUTE_MODIFIER,19, AttributeModifier.Operation.ADDITION)); + new AttributeModifier(uuid, ModUtils.ATTRIBUTE_MODIFIER, 19, AttributeModifier.Operation.ADDITION)); } return map; } @@ -297,4 +309,68 @@ public class SecondaryCataclysm extends GunItem implements GeoItem { public int getAvailableFireModes() { return FireMode.SEMI.flag; } + + @Override + public void fireOnPress(Player player) { + ItemStack stack = player.getMainHandItem(); + if (GunsTool.getGunBooleanTag(stack, "Reloading")) return; + if (player.getCooldowns().isOnCooldown(stack.getItem()) || GunsTool.getGunIntTag(stack, "Ammo", 0) <= 0) return; + + boolean zooming = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom; + double spread = GunsTool.getGunDoubleTag(stack, "Spread"); + + var hasEnoughEnergy = stack.getCapability(ForgeCapabilities.ENERGY) + .map(storage -> storage.getEnergyStored() >= 3000) + .orElse(false); + + boolean isChargedFire = zooming && hasEnoughEnergy; + + if (player.level() instanceof ServerLevel serverLevel) { + GunGrenadeEntity gunGrenadeEntity = new GunGrenadeEntity(player, serverLevel, + (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0)); + + var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); + gunGrenadeEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); + } + + gunGrenadeEntity.setNoGravity(PerkHelper.getPerkByType(stack, Perk.Type.AMMO) == ModPerks.MICRO_MISSILE.get()); + gunGrenadeEntity.charged(isChargedFire); + + gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); + gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (isChargedFire ? 4 : 1) * (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), + (float) (zooming ? 0.1 : spread)); + serverLevel.addFreshEntity(gunGrenadeEntity); + + ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, + player.getEyeY() - 0.35 + 1.8 * player.getLookAngle().y, + player.getZ() + 1.8 * player.getLookAngle().z, + 4, 0.1, 0.1, 0.1, 0.002, true); + + + var serverPlayer = (ServerPlayer) player; + + if (isChargedFire) { + SoundTool.playLocalSound(serverPlayer, ModSounds.SECONDARY_CATACLYSM_FIRE_1P_CHARGE.get(), 1, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FIRE_3P_CHARGE.get(), SoundSource.PLAYERS, 3, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FAR_CHARGE.get(), SoundSource.PLAYERS, 5, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_VERYFAR_CHARGE.get(), SoundSource.PLAYERS, 10, 1); + + stack.getCapability(ForgeCapabilities.ENERGY).ifPresent(energy -> energy.extractEnergy(3000, false)); + } else { + SoundTool.playLocalSound(serverPlayer, ModSounds.SECONDARY_CATACLYSM_FIRE_1P.get(), 1, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FIRE_3P.get(), SoundSource.PLAYERS, 3, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FAR.get(), SoundSource.PLAYERS, 5, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_VERYFAR.get(), SoundSource.PLAYERS, 10, 1); + } + + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); + } + + GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); + player.getCooldowns().addCooldown(stack.getItem(), 6); + } } \ No newline at end of file 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 9f9ba28f1..c19a05269 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 @@ -6,15 +6,25 @@ import com.atsuishio.superbwarfare.client.tooltip.component.BocekImageComponent; import com.atsuishio.superbwarfare.event.ClientEventHandler; 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.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.ModVariables; +import com.atsuishio.superbwarfare.network.message.ShootClientMessage; +import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; +import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.InventoryTool; +import com.atsuishio.superbwarfare.tools.SoundTool; import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; @@ -24,6 +34,7 @@ import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.*; import net.minecraft.world.level.Level; import net.minecraftforge.client.extensions.common.IClientItemExtensions; +import net.minecraftforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; @@ -37,7 +48,9 @@ import software.bernie.geckolib.util.GeckoLibUtil; import java.util.Optional; import java.util.function.Consumer; -public class BocekItem extends GunItem implements GeoItem { +import static com.atsuishio.superbwarfare.network.message.FireMessage.spawnBullet; + +public class BocekItem extends GunItem implements GeoItem, SpecialFireWeapon { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static ItemDisplayContext transformType; @@ -167,4 +180,60 @@ public class BocekItem extends GunItem implements GeoItem { public boolean useBackpackAmmo(ItemStack stack) { return true; } + + + @Override + public void fireOnRelease(Player player) { + if (player.level().isClientSide()) return; + + ItemStack stack = player.getMainHandItem(); + var perk = PerkHelper.getPerkByType(stack, 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); + + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); + } + + if (GunsTool.getGunDoubleTag(stack, "Power") >= 6) { + if ((player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).map(c -> c.zoom).orElse(false))) { + spawnBullet(player); + + 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); + } + + SoundTool.playLocalSound(player, ModSounds.BOCEK_SHATTER_CAP_FIRE_1P.get(), 10, 1); + player.playSound(ModSounds.BOCEK_SHATTER_CAP_FIRE_3P.get(), 2, 1); + } + + if (perk == ModPerks.BEAST_BULLET.get()) { + player.playSound(ModSounds.HENG.get(), 4f, 1f); + + if (player instanceof ServerPlayer serverPlayer) { + SoundTool.playLocalSound(serverPlayer, ModSounds.HENG.get(), 4f, 1f); + } + } + + player.getCooldowns().addCooldown(stack.getItem(), 7); + GunsTool.setGunIntTag(stack, "ArrowEmpty", 7); + GunsTool.setGunDoubleTag(stack, "Power", 0); + + if (!InventoryTool.hasCreativeAmmoBox(player) && !player.isCreative()) { + player.getInventory().clearOrCountMatchingItems(p -> Items.ARROW == p.getItem(), 1, player.inventoryMenu.getCraftSlots()); + } + } + } + + @Override + public void fireOnPress(Player player) { + player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).ifPresent(capability -> { + capability.bowPullHold = true; + capability.syncPlayerVariables(player); + }); + } } \ 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 e3ada8c4a..dacba62f0 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 @@ -5,22 +5,29 @@ import com.atsuishio.superbwarfare.capability.energy.ItemEnergyProvider; import com.atsuishio.superbwarfare.client.PoseTool; import com.atsuishio.superbwarfare.client.renderer.item.TaserItemRenderer; import com.atsuishio.superbwarfare.client.tooltip.component.EnergyImageComponent; +import com.atsuishio.superbwarfare.entity.projectile.TaserBulletProjectileEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; 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.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.ModVariables; +import com.atsuishio.superbwarfare.network.message.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.SoundTool; import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; @@ -35,6 +42,7 @@ import net.minecraft.world.level.Level; import net.minecraftforge.client.extensions.common.IClientItemExtensions; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; @@ -51,7 +59,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; -public class TaserItem extends GunItem implements GeoItem { +public class TaserItem extends GunItem implements GeoItem, SpecialFireWeapon { public static final int MAX_ENERGY = 6000; @@ -259,4 +267,47 @@ public class TaserItem extends GunItem implements GeoItem { public boolean isMagazineReload(ItemStack stack) { return true; } + + @Override + public void fireOnPress(Player player) { + ItemStack stack = player.getMainHandItem(); + if (GunsTool.getGunBooleanTag(stack, "Reloading")) return; + + int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.VOLT_OVERLOAD.get(), stack); + var hasEnoughEnergy = stack.getCapability(ForgeCapabilities.ENERGY) + .map(storage -> storage.getEnergyStored() >= 400 + 100 * perkLevel) + .orElse(false); + + if (player.getCooldowns().isOnCooldown(stack.getItem()) + || GunsTool.getGunIntTag(stack, "Ammo", 0) <= 0 + || !hasEnoughEnergy + ) return; + + player.getCooldowns().addCooldown(stack.getItem(), 5); + + if (player instanceof ServerPlayer serverPlayer) { + boolean zoom = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).map(c -> c.zoom).orElse(false); + double spread = GunsTool.getGunDoubleTag(stack, "Spread"); + int volt = PerkHelper.getItemPerkLevel(ModPerks.VOLT_OVERLOAD.get(), stack); + int wireLength = PerkHelper.getItemPerkLevel(ModPerks.LONGER_WIRE.get(), stack); + + SoundTool.playLocalSound(serverPlayer, ModSounds.TASER_FIRE_1P.get(), 1, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.TASER_FIRE_3P.get(), SoundSource.PLAYERS, 1, 1); + + var level = serverPlayer.level(); + TaserBulletProjectileEntity taserBulletProjectile = new TaserBulletProjectileEntity(player, level, + (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), volt, wireLength); + + taserBulletProjectile.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); + taserBulletProjectile.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), + (float) (zoom ? 0.1 : spread)); + level.addFreshEntity(taserBulletProjectile); + + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); + } + + GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); + stack.getCapability(ForgeCapabilities.ENERGY).ifPresent(energy -> energy.extractEnergy(400 + 100 * perkLevel, false)); + stack.getOrCreateTag().putBoolean("shoot", true); + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/FireMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/FireMessage.java index 5f5f2889d..a101c62d4 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/FireMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/FireMessage.java @@ -1,46 +1,23 @@ package com.atsuishio.superbwarfare.network.message; -import com.atsuishio.superbwarfare.ModUtils; -import com.atsuishio.superbwarfare.entity.projectile.*; +import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; 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.SpecialFireWeapon; import com.atsuishio.superbwarfare.network.ModVariables; import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; -import com.atsuishio.superbwarfare.tools.ParticleTool; -import com.atsuishio.superbwarfare.tools.SeekTool; -import com.atsuishio.superbwarfare.tools.SoundTool; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.game.ClientboundStopSoundPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.sounds.SoundSource; -import net.minecraft.util.Mth; 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.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.ClipContext; -import net.minecraft.world.level.Level; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.network.NetworkEvent; -import net.minecraftforge.network.PacketDistributor; -import org.joml.Vector3d; import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; public class FireMessage { @@ -70,13 +47,22 @@ public class FireMessage { } public static void pressAction(Player player, int type) { + if (player.isSpectator()) return; ItemStack stack = player.getMainHandItem(); if (!stack.is(ModTags.Items.GUN)) return; handleGunBolt(player, stack); if (type == 0) { - handlePlayerShoot(player); + // 按下开火 + if (!(stack.getItem() instanceof SpecialFireWeapon specialFireWeapon)) return; + specialFireWeapon.fireOnPress(player); + + var tag = stack.getOrCreateTag(); + if (tag.getDouble("prepare") == 0 && GunsTool.getGunBooleanTag(stack, "Reloading") && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) { + tag.putDouble("force_stop", 1); + } + player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).ifPresent(capability -> { capability.edit = false; capability.holdFire = true; @@ -89,88 +75,21 @@ public class FireMessage { capability.syncPlayerVariables(player); }); - if (stack.getItem() == ModItems.BOCEK.get()) { - handleBowShoot(player); + // 松开开火 + if (stack.getItem() instanceof SpecialFireWeapon specialFireWeapon) { + specialFireWeapon.fireOnRelease(player); } - - if (stack.getItem() == ModItems.JAVELIN.get()) { - var tag = stack.getOrCreateTag(); - handleJavelinFire(player); - tag.putBoolean("Seeking", false); - tag.putInt("SeekTime", 0); - tag.putString("TargetEntity", "none"); - if (player instanceof ServerPlayer serverPlayer) { - var clientboundstopsoundpacket = new ClientboundStopSoundPacket(new ResourceLocation(ModUtils.MODID, "javelin_lock"), SoundSource.PLAYERS); - serverPlayer.connection.send(clientboundstopsoundpacket); - } - } - } - } - - private static void handlePlayerShoot(Player player) { - var stack = player.getMainHandItem(); - - if (!stack.is(ModTags.Items.GUN)) return; - - var tag = stack.getOrCreateTag(); - - if (stack.getItem() == ModItems.TASER.get()) { - handleTaserFire(player); - } - - if (stack.getItem() == ModItems.M_79.get()) { - handleM79Fire(player); - } - - if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) { - handleSecondaryCataclysmFire(player); - } - - if (stack.getItem() == ModItems.RPG.get()) { - handleRpgFire(player); - } - - if (stack.getItem() == ModItems.JAVELIN.get() && player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null) - .orElse(new ModVariables.PlayerVariables()).zoom && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) { - Entity seekingEntity = SeekTool.seekEntity(player, player.level(), 512, 8); - if (seekingEntity != null && !player.isCrouching()) { - tag.putInt("GuideType", 0); - tag.putString("TargetEntity", seekingEntity.getStringUUID()); - tag.putBoolean("Seeking", true); - tag.putInt("SeekTime", 0); - } else { - - BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)), - ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)); - Vec3 hitPos = result.getLocation(); - - tag.putInt("GuideType", 1); - tag.putDouble("TargetPosX", hitPos.x); - tag.putDouble("TargetPosY", hitPos.y); - tag.putDouble("TargetPosZ", hitPos.z); - tag.putBoolean("Seeking", true); - tag.putInt("SeekTime", 0); - } - } - - if (tag.getDouble("prepare") == 0 && GunsTool.getGunBooleanTag(stack, "Reloading") && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) { - tag.putDouble("force_stop", 1); - } - - if (stack.getItem() == ModItems.BOCEK.get()) { - player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).ifPresent(capability -> { - capability.bowPullHold = true; - capability.syncPlayerVariables(player); - }); } } private static void handleGunBolt(Player player, ItemStack stack) { if (!stack.is(ModTags.Items.GUN)) return; - if (GunsTool.getGunIntTag(stack, "BoltActionTime", 0) > 0 && GunsTool.getGunIntTag(stack, "Ammo", 0) > (stack.is(ModTags.Items.REVOLVER) ? -1 : 0) + if (GunsTool.getGunIntTag(stack, "BoltActionTime", 0) > 0 + && GunsTool.getGunIntTag(stack, "Ammo", 0) > (stack.is(ModTags.Items.REVOLVER) ? -1 : 0) && GunsTool.getGunIntTag(stack, "BoltActionTick") == 0 - && !(stack.getOrCreateTag().getBoolean("is_normal_reloading") || stack.getOrCreateTag().getBoolean("is_empty_reloading")) + && !(stack.getOrCreateTag().getBoolean("is_normal_reloading") + || stack.getOrCreateTag().getBoolean("is_empty_reloading")) && !GunsTool.getGunBooleanTag(stack, "Reloading") && !GunsTool.getGunBooleanTag(stack, "Charging")) { if (!player.getCooldowns().isOnCooldown(stack.getItem()) && GunsTool.getGunBooleanTag(stack, "NeedBoltAction", false)) { @@ -196,62 +115,7 @@ public class FireMessage { return 1; } - private static void handleBowShoot(Player player) { - if (player.level().isClientSide()) return; - - ItemStack stack = player.getMainHandItem(); - var perk = PerkHelper.getPerkByType(stack, 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); - } - - if (GunsTool.getGunDoubleTag(stack, "Power") >= 6) { - if ((player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables())).zoom) { - spawnBullet(player); - - SoundTool.playLocalSound(player, ModSounds.BOCEK_ZOOM_FIRE_1P.get(), 10, 1); - player.playSound(ModSounds.BOCEK_ZOOM_FIRE_3P.get(), 2, 1); - } else { - for (int index0 = 0; index0 < (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 1 : 10); index0++) { - spawnBullet(player); - } - - SoundTool.playLocalSound(player, ModSounds.BOCEK_SHATTER_CAP_FIRE_1P.get(), 10, 1); - player.playSound(ModSounds.BOCEK_SHATTER_CAP_FIRE_3P.get(), 2, 1); - } - - if (perk == ModPerks.BEAST_BULLET.get()) { - player.playSound(ModSounds.HENG.get(), 4f, 1f); - - if (player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.HENG.get(), 4f, 1f); - } - } - - player.getCooldowns().addCooldown(stack.getItem(), 7); - GunsTool.setGunIntTag(stack, "ArrowEmpty", 7); - GunsTool.setGunDoubleTag(stack, "Power", 0); - - int count = 0; - for (var inv : player.getInventory().items) { - if (inv.is(ModItems.CREATIVE_AMMO_BOX.get())) { - count++; - } - } - - if (count == 0 && !player.isCreative()) { - player.getInventory().clearOrCountMatchingItems(p -> Items.ARROW == p.getItem(), 1, player.inventoryMenu.getCraftSlots()); - } - - if (player.level() instanceof ServerLevel && player instanceof ServerPlayer serverPlayer) { - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); - } - } - } - - private static void spawnBullet(Player player) { + public static void spawnBullet(Player player) { ItemStack stack = player.getMainHandItem(); if (player.level().isClientSide()) return; @@ -334,311 +198,10 @@ public class FireMessage { } 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); } - private static void handleTaserFire(Player player) { - if (player.isSpectator()) return; - - ItemStack stack = player.getMainHandItem(); - if (!GunsTool.getGunBooleanTag(stack, "Reloading")) { - int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.VOLT_OVERLOAD.get(), stack); - AtomicBoolean flag = new AtomicBoolean(false); - stack.getCapability(ForgeCapabilities.ENERGY).ifPresent( - iEnergyStorage -> flag.set(iEnergyStorage.getEnergyStored() >= 400 + 100 * perkLevel) - ); - - if (!player.getCooldowns().isOnCooldown(stack.getItem()) && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0 && flag.get()) { - player.getCooldowns().addCooldown(stack.getItem(), 5); - - if (player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.TASER_FIRE_1P.get(), 1, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.TASER_FIRE_3P.get(), SoundSource.PLAYERS, 1, 1); - } - - int volt = PerkHelper.getItemPerkLevel(ModPerks.VOLT_OVERLOAD.get(), stack); - int wireLength = PerkHelper.getItemPerkLevel(ModPerks.LONGER_WIRE.get(), stack); - - boolean zoom = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom; - double spread = GunsTool.getGunDoubleTag(stack, "Spread"); - - Level level = player.level(); - if (!level.isClientSide()) { - TaserBulletProjectileEntity taserBulletProjectile = new TaserBulletProjectileEntity(player, level, - (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), volt, wireLength); - - taserBulletProjectile.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); - taserBulletProjectile.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), - (float) (zoom ? 0.1 : spread)); - level.addFreshEntity(taserBulletProjectile); - } - - GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); - - stack.getCapability(ForgeCapabilities.ENERGY).ifPresent( - energy -> energy.extractEnergy(400 + 100 * perkLevel, false) - ); - - stack.getOrCreateTag().putBoolean("shoot", true); - if (player.level() instanceof ServerLevel && player instanceof ServerPlayer serverPlayer) { - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); - } - } - } - } - - private static void handleM79Fire(Player player) { - if (player.isSpectator()) return; - - ItemStack stack = player.getMainHandItem(); - if (!GunsTool.getGunBooleanTag(stack, "Reloading")) { - if (!player.getCooldowns().isOnCooldown(stack.getItem()) && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) { - boolean zoom = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom; - double spread = GunsTool.getGunDoubleTag(stack, "Spread"); - - Level level = player.level(); - if (!level.isClientSide()) { - GunGrenadeEntity gunGrenadeEntity = new GunGrenadeEntity(player, level, - (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0)); - - var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); - if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { - int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); - gunGrenadeEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); - } - - gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); - gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), - (float) (zoom ? 0.1 : spread)); - level.addFreshEntity(gunGrenadeEntity); - } - - if (player.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, - player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y, - player.getZ() + 1.8 * player.getLookAngle().z, - 4, 0.1, 0.1, 0.1, 0.002, true); - } - player.getCooldowns().addCooldown(stack.getItem(), 2); - - if (player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.M_79_FIRE_1P.get(), 2, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_79_FIRE_3P.get(), SoundSource.PLAYERS, 2, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_79_FAR.get(), SoundSource.PLAYERS, 5, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.M_79_VERYFAR.get(), SoundSource.PLAYERS, 10, 1); - } - - GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); - - if (player.level() instanceof ServerLevel && player instanceof ServerPlayer serverPlayer) { - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); - } - } - } - } - - private static void handleRpgFire(Player player) { - if (player.isSpectator()) return; - - Level level = player.level(); - ItemStack stack = player.getMainHandItem(); - CompoundTag tag = stack.getOrCreateTag(); - - if (!GunsTool.getGunBooleanTag(stack, "Reloading") && !player.getCooldowns().isOnCooldown(stack.getItem()) && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) { - boolean zoom = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom; - double spread = GunsTool.getGunDoubleTag(stack, "Spread"); - - if (!level.isClientSide()) { - RpgRocketEntity rocketEntity = new RpgRocketEntity(player, level, - (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0)); - - var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); - if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { - int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); - rocketEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); - } - - rocketEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); - rocketEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), - (float) (zoom ? 0.1 : spread)); - level.addFreshEntity(rocketEntity); - } - - if (player.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, - player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y, - player.getZ() + 1.8 * player.getLookAngle().z, - 30, 0.4, 0.4, 0.4, 0.005, true); - } - - if (GunsTool.getGunIntTag(stack, "Ammo", 0) == 1) { - tag.putBoolean("empty", true); - GunsTool.setGunBooleanTag(stack, "CloseHammer", true); - } - - player.getCooldowns().addCooldown(stack.getItem(), 10); - - if (player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.RPG_FIRE_1P.get(), 2, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.RPG_FIRE_3P.get(), SoundSource.PLAYERS, 2, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.RPG_FAR.get(), SoundSource.PLAYERS, 5, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.RPG_VERYFAR.get(), SoundSource.PLAYERS, 10, 1); - } - - GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); - - if (player.level() instanceof ServerLevel && player instanceof ServerPlayer serverPlayer) { - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); - } - } - } - - private static void handleJavelinFire(Player player) { - if (player.isSpectator()) return; - - Level level = player.level(); - ItemStack stack = player.getMainHandItem(); - CompoundTag tag = stack.getOrCreateTag(); - - if (tag.getInt("SeekTime") < 20) return; - - float yRot = player.getYRot(); - if (yRot < 0) { - yRot += 360; - } - yRot = yRot + 90 % 360; - - var firePos = new Vector3d(0, -0.2, 0.15); - firePos.rotateZ(-player.getXRot() * Mth.DEG_TO_RAD); - firePos.rotateY(-yRot * Mth.DEG_TO_RAD); - - if (!level.isClientSide()) { - JavelinMissileEntity missileEntity = new JavelinMissileEntity(player, level, - (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0), - stack.getOrCreateTag().getInt("GuideType"), - new Vec3(stack.getOrCreateTag().getDouble("TargetPosX"), stack.getOrCreateTag().getDouble("TargetPosY"), stack.getOrCreateTag().getDouble("TargetPosZ"))); - - var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); - if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { - int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); - missileEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); - } - - missileEntity.setPos(player.getX() + firePos.x, player.getEyeY() + firePos.y, player.getZ() + firePos.z); - missileEntity.shoot(player.getLookAngle().x, player.getLookAngle().y + 0.3, player.getLookAngle().z, 3f, 1); - missileEntity.setTargetUuid(tag.getString("TargetEntity")); - missileEntity.setAttackMode(tag.getBoolean("TopMode")); - - level.addFreshEntity(missileEntity); - } - - if (player.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, - player.getY() + player.getBbHeight() - 0.1 + 1.8 * player.getLookAngle().y, - player.getZ() + 1.8 * player.getLookAngle().z, - 30, 0.4, 0.4, 0.4, 0.005, true); - } - - player.getCooldowns().addCooldown(stack.getItem(), 10); - - if (player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.JAVELIN_FIRE_1P.get(), 2, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.JAVELIN_FIRE_3P.get(), SoundSource.PLAYERS, 4, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.JAVELIN_FAR.get(), SoundSource.PLAYERS, 10, 1); - } - - GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); - - if (player.level() instanceof ServerLevel && player instanceof ServerPlayer serverPlayer) { - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); - } - } - - private static void handleSecondaryCataclysmFire(Player player) { - if (player.isSpectator()) return; - - ItemStack stack = player.getMainHandItem(); - if (!GunsTool.getGunBooleanTag(stack, "Reloading")) { - if (!player.getCooldowns().isOnCooldown(stack.getItem()) && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) { - boolean zoom = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom; - double spread = GunsTool.getGunDoubleTag(stack, "Spread"); - - AtomicBoolean flag = new AtomicBoolean(false); - stack.getCapability(ForgeCapabilities.ENERGY).ifPresent( - iEnergyStorage -> flag.set(iEnergyStorage.getEnergyStored() >= 3000) - ); - - boolean chargeFire = zoom && flag.get(); - - Level level = player.level(); - if (!level.isClientSide()) { - GunGrenadeEntity gunGrenadeEntity = new GunGrenadeEntity(player, level, - (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), - (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0)); - - var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); - if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { - int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); - gunGrenadeEntity.setMonsterMultiplier(0.1f + 0.1f * perkLevel); - } - - if (chargeFire) { - gunGrenadeEntity.charged(true); - } - - gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); - gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (chargeFire ? 4 : 1) * (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0), - (float) (zoom ? 0.1 : spread)); - level.addFreshEntity(gunGrenadeEntity); - } - - if (player.level() instanceof ServerLevel serverLevel) { - ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, player.getX() + 1.8 * player.getLookAngle().x, - player.getEyeY() - 0.35 + 1.8 * player.getLookAngle().y, - player.getZ() + 1.8 * player.getLookAngle().z, - 4, 0.1, 0.1, 0.1, 0.002, true); - } - player.getCooldowns().addCooldown(stack.getItem(), 2); - - if (chargeFire) { - if (player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.SECONDARY_CATACLYSM_FIRE_1P_CHARGE.get(), 1, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FIRE_3P_CHARGE.get(), SoundSource.PLAYERS, 3, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FAR_CHARGE.get(), SoundSource.PLAYERS, 5, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_VERYFAR_CHARGE.get(), SoundSource.PLAYERS, 10, 1); - } - stack.getCapability(ForgeCapabilities.ENERGY).ifPresent( - energy -> energy.extractEnergy(3000, false) - ); - } else { - if (player instanceof ServerPlayer serverPlayer) { - SoundTool.playLocalSound(serverPlayer, ModSounds.SECONDARY_CATACLYSM_FIRE_1P.get(), 1, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FIRE_3P.get(), SoundSource.PLAYERS, 3, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_FAR.get(), SoundSource.PLAYERS, 5, 1); - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.SECONDARY_CATACLYSM_VERYFAR.get(), SoundSource.PLAYERS, 10, 1); - } - } - - - GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); - player.getCooldowns().addCooldown(stack.getItem(), 6); - - if (player.level() instanceof ServerLevel && player instanceof ServerPlayer serverPlayer) { - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); - } - } - } - } } diff --git a/src/main/java/com/atsuishio/superbwarfare/perk/PerkHelper.java b/src/main/java/com/atsuishio/superbwarfare/perk/PerkHelper.java index fcf169578..d5fbf9e62 100644 --- a/src/main/java/com/atsuishio/superbwarfare/perk/PerkHelper.java +++ b/src/main/java/com/atsuishio/superbwarfare/perk/PerkHelper.java @@ -180,23 +180,17 @@ public class PerkHelper { return resourceLocation.getNamespace() + ":" + resourceLocation.getPath(); } - public static final Predicate SHOTGUN_PERKS = perk -> { - switch (perk.type) { - case AMMO -> { - return !perk.descriptionId.equals("butterfly_bullet"); - } - case FUNCTIONAL -> { - return perk == ModPerks.SUBSISTENCE.get() || perk == ModPerks.POWERFUL_ATTRACTION.get() || perk == ModPerks.HEAL_CLIP.get() || - perk == ModPerks.FIELD_DOCTOR.get() || perk == ModPerks.INTELLIGENT_CHIP.get(); - } - case DAMAGE -> { - return perk == ModPerks.GUTSHOT_STRAIGHT.get() || perk == ModPerks.MONSTER_HUNTER.get() || perk == ModPerks.KILL_CLIP.get() || - perk == ModPerks.VORPAL_WEAPON.get(); - } - default -> { - return false; - } - } + public static final Predicate SHOTGUN_PERKS = perk -> switch (perk.type) { + case AMMO -> !perk.descriptionId.equals("butterfly_bullet"); + case FUNCTIONAL -> perk == ModPerks.SUBSISTENCE.get() + || perk == ModPerks.POWERFUL_ATTRACTION.get() + || perk == ModPerks.HEAL_CLIP.get() + || perk == ModPerks.FIELD_DOCTOR.get() + || perk == ModPerks.INTELLIGENT_CHIP.get(); + case DAMAGE -> perk == ModPerks.GUTSHOT_STRAIGHT.get() + || perk == ModPerks.MONSTER_HUNTER.get() + || perk == ModPerks.KILL_CLIP.get() + || perk == ModPerks.VORPAL_WEAPON.get(); }; public static final Predicate RIFLE_PERKS = perk -> { @@ -219,84 +213,65 @@ public class PerkHelper { } }; - public static final Predicate HANDGUN_PERKS = perk -> { - switch (perk.type) { - case AMMO -> { - return !perk.descriptionId.equals("butterfly_bullet"); - } - case FUNCTIONAL -> { - return perk == ModPerks.HEAL_CLIP.get() || perk == ModPerks.FIELD_DOCTOR.get() || - perk == ModPerks.SUBSISTENCE.get() || perk == ModPerks.POWERFUL_ATTRACTION.get() - || perk == ModPerks.INTELLIGENT_CHIP.get(); - } - case DAMAGE -> { - return perk == ModPerks.KILL_CLIP.get() || perk == ModPerks.GUTSHOT_STRAIGHT.get() || perk == ModPerks.MONSTER_HUNTER.get() || - perk == ModPerks.VORPAL_WEAPON.get(); - } - default -> { - return false; - } - } + public static final Predicate HANDGUN_PERKS = perk -> switch (perk.type) { + case AMMO -> !perk.descriptionId.equals("butterfly_bullet"); + case FUNCTIONAL -> perk == ModPerks.HEAL_CLIP.get() + || perk == ModPerks.FIELD_DOCTOR.get() + || perk == ModPerks.SUBSISTENCE.get() + || perk == ModPerks.POWERFUL_ATTRACTION.get() + || perk == ModPerks.INTELLIGENT_CHIP.get(); + case DAMAGE -> perk == ModPerks.KILL_CLIP.get() + || perk == ModPerks.GUTSHOT_STRAIGHT.get() + || perk == ModPerks.MONSTER_HUNTER.get() + || perk == ModPerks.VORPAL_WEAPON.get(); }; - public static final Predicate SNIPER_RIFLE_PERKS = perk -> { - switch (perk.type) { - case AMMO -> { - return !perk.descriptionId.equals("butterfly_bullet"); - } - case FUNCTIONAL -> { - return perk == ModPerks.HEAL_CLIP.get() || perk == ModPerks.FOURTH_TIMES_CHARM.get() || perk == ModPerks.POWERFUL_ATTRACTION.get() - || perk == ModPerks.INTELLIGENT_CHIP.get(); - } - case DAMAGE -> { - return perk == ModPerks.KILL_CLIP.get() || perk == ModPerks.MONSTER_HUNTER.get() || perk == ModPerks.VORPAL_WEAPON.get(); - } - default -> { - return false; - } - } + public static final Predicate SNIPER_RIFLE_PERKS = perk -> switch (perk.type) { + case AMMO -> !perk.descriptionId.equals("butterfly_bullet"); + + case FUNCTIONAL -> perk == ModPerks.HEAL_CLIP.get() + || perk == ModPerks.FOURTH_TIMES_CHARM.get() + || perk == ModPerks.POWERFUL_ATTRACTION.get() + || perk == ModPerks.INTELLIGENT_CHIP.get(); + + case DAMAGE -> perk == ModPerks.KILL_CLIP.get() + || perk == ModPerks.MONSTER_HUNTER.get() + || perk == ModPerks.VORPAL_WEAPON.get(); }; - public static final Predicate SMG_PERKS = perk -> { - switch (perk.type) { - case AMMO -> { - return true; - } - case FUNCTIONAL -> { - return perk == ModPerks.HEAL_CLIP.get() || perk == ModPerks.FOURTH_TIMES_CHARM.get() || perk == ModPerks.SUBSISTENCE.get() || - perk == ModPerks.POWERFUL_ATTRACTION.get() || perk == ModPerks.INTELLIGENT_CHIP.get(); - } - case DAMAGE -> { - return perk == ModPerks.KILL_CLIP.get() || perk == ModPerks.GUTSHOT_STRAIGHT.get() || perk == ModPerks.MONSTER_HUNTER.get() || - perk == ModPerks.HEAD_SEEKER.get() || perk == ModPerks.DESPERADO.get() || perk == ModPerks.VORPAL_WEAPON.get(); - } - default -> { - return false; - } - } + public static final Predicate SMG_PERKS = perk -> switch (perk.type) { + case AMMO -> true; + case FUNCTIONAL -> perk == ModPerks.HEAL_CLIP.get() + || perk == ModPerks.FOURTH_TIMES_CHARM.get() + || perk == ModPerks.SUBSISTENCE.get() + || perk == ModPerks.POWERFUL_ATTRACTION.get() + || perk == ModPerks.INTELLIGENT_CHIP.get(); + case DAMAGE -> perk == ModPerks.KILL_CLIP.get() + || perk == ModPerks.GUTSHOT_STRAIGHT.get() + || perk == ModPerks.MONSTER_HUNTER.get() + || perk == ModPerks.HEAD_SEEKER.get() + || perk == ModPerks.DESPERADO.get() + || perk == ModPerks.VORPAL_WEAPON.get(); }; - public static final Predicate MACHINE_GUN_PERKS = perk -> { - switch (perk.type) { - case AMMO -> { - return true; - } - case FUNCTIONAL -> { - return perk == ModPerks.FOURTH_TIMES_CHARM.get() || perk == ModPerks.SUBSISTENCE.get() || perk == ModPerks.POWERFUL_ATTRACTION.get() || - perk == ModPerks.INTELLIGENT_CHIP.get(); - } - case DAMAGE -> { - return perk == ModPerks.MONSTER_HUNTER.get() || perk == ModPerks.KILLING_TALLY.get() || perk == ModPerks.VORPAL_WEAPON.get(); - } - default -> { - return false; - } - } + public static final Predicate MACHINE_GUN_PERKS = perk -> switch (perk.type) { + case AMMO -> true; + + case FUNCTIONAL -> perk == ModPerks.FOURTH_TIMES_CHARM.get() + || perk == ModPerks.SUBSISTENCE.get() + || perk == ModPerks.POWERFUL_ATTRACTION.get() + || perk == ModPerks.INTELLIGENT_CHIP.get(); + case DAMAGE -> perk == ModPerks.MONSTER_HUNTER.get() + || perk == ModPerks.KILLING_TALLY.get() + || perk == ModPerks.VORPAL_WEAPON.get(); }; public static final Predicate MAGAZINE_PERKS = perk -> false; - public static final Predicate LAUNCHER_PERKS = perk -> perk == ModPerks.MONSTER_HUNTER.get() || perk == ModPerks.POWERFUL_ATTRACTION.get() || - perk == ModPerks.INTELLIGENT_CHIP.get() || perk == ModPerks.VORPAL_WEAPON.get(); + public static final Predicate LAUNCHER_PERKS = perk -> perk == ModPerks.MONSTER_HUNTER.get() + || perk == ModPerks.POWERFUL_ATTRACTION.get() + || perk == ModPerks.INTELLIGENT_CHIP.get() + || perk == ModPerks.VORPAL_WEAPON.get() + || perk == ModPerks.MICRO_MISSILE.get(); } diff --git a/src/main/resources/assets/superbwarfare/lang/en_us.json b/src/main/resources/assets/superbwarfare/lang/en_us.json index c6ea404a7..8343d2806 100644 --- a/src/main/resources/assets/superbwarfare/lang/en_us.json +++ b/src/main/resources/assets/superbwarfare/lang/en_us.json @@ -328,6 +328,8 @@ "des.superbwarfare.desperado": "Reload after a precision final blow increases your rate of fire", "item.superbwarfare.vorpal_weapon": "Vorpal Weapon", "des.superbwarfare.vorpal_weapon": "Increases damage against bosses", + "item.superbwarfare.micro_missile": "Micro Missile", + "des.superbwarfare.micro_missile": "Fires a high-speed projectile without gravity", "item.superbwarfare.empty_perk": "Empty Perk", "item.superbwarfare.shortcut_pack": "Shortcut Pack", diff --git a/src/main/resources/assets/superbwarfare/lang/zh_cn.json b/src/main/resources/assets/superbwarfare/lang/zh_cn.json index 9bf41b0a2..c406048d7 100644 --- a/src/main/resources/assets/superbwarfare/lang/zh_cn.json +++ b/src/main/resources/assets/superbwarfare/lang/zh_cn.json @@ -326,6 +326,8 @@ "des.superbwarfare.desperado": "精准击杀后进行换弹,可暂时提升射速", "item.superbwarfare.vorpal_weapon": "斩首武器", "des.superbwarfare.vorpal_weapon": "提升对强大敌人造成的伤害", + "item.superbwarfare.micro_missile": "微型导弹", + "des.superbwarfare.micro_missile": "使武器发射无视重力前进的高速弹药", "item.superbwarfare.empty_perk": "空白模组", "item.superbwarfare.shortcut_pack": "捷径包",