From 616818d15b23a998b8a845edbc3a0103fecd183c Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Sat, 29 Mar 2025 13:47:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=88=E5=87=A0=E4=B9=8E?= =?UTF-8?q?=E6=89=80=E6=9C=89=EF=BC=89=E7=BD=91=E7=BB=9C=E5=8C=85=E5=92=8C?= =?UTF-8?q?Mixin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../superbwarfare/client/ClickHandler.java | 50 ++-- .../client/screens/ChargingStationScreen.java | 2 +- .../client/screens/FuMO25Screen.java | 19 +- .../client/screens/ReforgingTableScreen.java | 20 +- .../event/ClientEventHandler.java | 21 +- .../event/ClientMouseHandler.java | 97 ++++++++ .../event/LivingEventHandler.java | 4 +- .../atsuishio/superbwarfare/item/Monitor.java | 5 +- .../item/gun/launcher/JavelinItem.java | 79 ++++--- .../item/gun/launcher/M79Item.java | 87 +++---- .../item/gun/launcher/RpgItem.java | 89 ++++---- .../item/gun/launcher/SecondaryCataclysm.java | 117 +++++----- .../item/gun/special/BocekItem.java | 17 +- .../item/gun/special/TaserItem.java | 5 +- .../superbwarfare/menu/EnergyMenu.java | 83 ++++--- .../superbwarfare/menu/FuMO25Menu.java | 24 -- .../superbwarfare/mixins/CameraMixin.java | 174 ++++++++++++++ .../mixins/ClientPacketListenerMixin.java | 72 ++++++ .../mixins/ClientPlayerEntityMixin.java | 29 +++ .../ClientboundSetPassengersPacketMixin.java | 37 +++ .../mixins/GameRendererMixin.java | 94 ++++++++ .../mixins/ItemInHandLayerMixin.java | 32 +++ .../mixins/KeyboardInputMixin.java | 54 +++++ .../superbwarfare/mixins/KeymappingMixin.java | 52 +++++ .../mixins/LivingEntityRendererMixin.java | 61 +++++ .../superbwarfare/mixins/MinecraftMixin.java | 77 +++++++ .../mixins/MouseHandlerMixin.java | 60 +++++ .../superbwarfare/mixins/PlayerMixin.java | 38 ++++ .../network/ClientPacketHandler.java | 67 ++---- .../network/NetworkRegistry.java | 32 +++ .../receive/ClientIndicatorMessage.java | 10 +- .../message/receive/ContainerDataMessage.java | 47 ++++ .../message/receive/DrawClientMessage.java | 29 +++ .../receive/ResetCameraTypeMessage.java | 29 +++ .../message/receive/ShakeClientMessage.java | 2 +- .../message/receive/ShootClientMessage.java | 29 +++ .../send/AdjustMortarAngleMessage.java | 46 ++++ .../message/send/AdjustZoomFovMessage.java | 73 ++++++ .../message/send/AimVillagerMessage.java | 41 ++++ .../network/message/send/BreathMessage.java | 8 +- .../send/ChangeVehicleSeatMessage.java | 35 +++ .../message/send/DroneFireMessage.java | 85 +++++++ .../network/message/send/EditMessage.java | 82 +++++++ .../network/message/send/EditModeMessage.java | 51 +++++ .../network/message/send/FireMessage.java | 215 ++++++++++++++++++ .../network/message/send/FireModeMessage.java | 127 +++++++++++ .../message/send/GunReforgeMessage.java | 39 ++++ .../network/message/send/InteractMessage.java | 87 +++++++ .../message/send/LungeMineAttackMessage.java | 92 ++++++++ .../message/send/MeleeAttackMessage.java | 38 ++++ .../message/send/PlayerStopRidingMessage.java | 35 +++ .../message/send/RadarChangeModeMessage.java | 40 ++++ .../message/send/RadarMenuCloseMessage.java | 30 +++ .../message/send/RadarMenuOpenMessage.java | 30 +++ .../send/RadarSetParametersMessage.java | 39 ++++ .../message/send/RadarSetPosMessage.java | 38 ++++ .../message/send/RadarSetTargetMessage.java | 49 ++++ .../network/message/send/ReloadMessage.java | 105 +++++++++ .../message/send/SensitivityMessage.java | 45 ++++ .../send/SetFiringParametersMessage.java | 69 ++++++ .../message/send/SetPerkLevelMessage.java | 40 ++++ .../message/send/SwitchScopeMessage.java | 37 +++ .../send/SwitchVehicleWeaponMessage.java | 40 ++++ .../message/send/VehicleFireMessage.java | 32 +++ .../network/message/send/ZoomMessage.java | 82 +++++++ src/main/resources/mixins.superbwarfare.json | 17 +- 66 files changed, 3128 insertions(+), 363 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/CameraMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/ClientPacketListenerMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/ClientPlayerEntityMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/ClientboundSetPassengersPacketMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/GameRendererMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/ItemInHandLayerMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/KeyboardInputMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/KeymappingMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityRendererMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/MinecraftMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/MouseHandlerMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/mixins/PlayerMixin.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/receive/ContainerDataMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/receive/DrawClientMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/receive/ResetCameraTypeMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShootClientMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustMortarAngleMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustZoomFovMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/AimVillagerMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/ChangeVehicleSeatMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/DroneFireMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/EditMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/EditModeMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/FireMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/FireModeMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/GunReforgeMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/InteractMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/LungeMineAttackMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/MeleeAttackMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/PlayerStopRidingMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarChangeModeMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuCloseMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuOpenMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetParametersMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetPosMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetTargetMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/ReloadMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/SensitivityMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/SetPerkLevelMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchScopeMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchVehicleWeaponMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/VehicleFireMessage.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/send/ZoomMessage.java diff --git a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java index dd46b43e8..f6fe8364e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java @@ -10,7 +10,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.network.message.send.DoubleJumpMessage; +import com.atsuishio.superbwarfare.network.message.send.*; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; import com.atsuishio.superbwarfare.tools.NBTTool; @@ -40,7 +40,7 @@ import org.lwjgl.glfw.GLFW; import static com.atsuishio.superbwarfare.event.ClientEventHandler.cantFireTime; import static com.atsuishio.superbwarfare.event.ClientEventHandler.drawTime; -// TODO 发送亿堆网络包 + @EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) public class ClickHandler { @@ -156,7 +156,7 @@ public class ClickHandler { && weaponVehicle.hasWeapon(vehicle.getSeatIndex(player)) ) { int index = vehicle.getSeatIndex(player); -// PacketDistributor.sendToServer(new SwitchVehicleWeaponMessage(index, -scroll, true)); + PacketDistributor.sendToServer(new SwitchVehicleWeaponMessage(index, -scroll, true)); event.setCanceled(true); } @@ -164,9 +164,9 @@ public class ClickHandler { if (stack.is(ModTags.Items.GUN) && ClientEventHandler.zoom) { if (GunsTool.getGunBooleanTag(stack, "CanSwitchScope", false)) { -// PacketDistributor.sendToServer(new SwitchScopeMessage(scroll)); + PacketDistributor.sendToServer(new SwitchScopeMessage(scroll)); } else if (tag.getBoolean("CanAdjustZoomFov") || stack.is(ModItems.MINIGUN.get())) { -// PacketDistributor.sendToServer(new AdjustZoomFovMessage(scroll)); + PacketDistributor.sendToServer(new AdjustZoomFovMessage(scroll)); } event.setCanceled(true); } @@ -179,7 +179,7 @@ public class ClickHandler { Entity looking = TraceTool.findLookingEntity(player, 6); if (looking == null) return; if (looking instanceof MortarEntity && player.isShiftKeyDown()) { -// PacketDistributor.sendToServer(new AdjustMortarAngleMessage(scroll)); + PacketDistributor.sendToServer(new AdjustMortarAngleMessage(scroll)); event.setCanceled(true); } } @@ -208,20 +208,20 @@ public class ClickHandler { // } if (key == ModKeyMappings.RELOAD.getKey().getValue()) { -// PacketDistributor.sendToServer(new ReloadMessage(0)); + PacketDistributor.sendToServer(new ReloadMessage(0)); } if (key == ModKeyMappings.FIRE_MODE.getKey().getValue()) { -// PacketDistributor.sendToServer(new FireModeMessage(0)); + PacketDistributor.sendToServer(new FireModeMessage(0)); } if (key == ModKeyMappings.INTERACT.getKey().getValue()) { -// PacketDistributor.sendToServer(new InteractMessage(0)); + PacketDistributor.sendToServer(new InteractMessage(0)); } if (key == ModKeyMappings.DISMOUNT.getKey().getValue()) { handleDismountPress(player); } if (key == ModKeyMappings.EDIT_MODE.getKey().getValue() && ClientEventHandler.burstFireSize == 0) { ClientEventHandler.holdFire = false; -// PacketDistributor.sendToServer(new EditModeMessage(0)); + PacketDistributor.sendToServer(new EditModeMessage(0)); } var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); @@ -229,30 +229,30 @@ public class ClickHandler { if (!(stack.getItem() instanceof GunItem gunItem)) return; if (ModKeyMappings.EDIT_GRIP.getKeyModifier().isActive(KeyConflictContext.IN_GAME)) { if (key == ModKeyMappings.EDIT_GRIP.getKey().getValue() && gunItem.hasCustomGrip(stack)) { -// PacketDistributor.sendToServer(new EditMessage(4)); + PacketDistributor.sendToServer(new EditMessage(4)); editModelShake(); } } else { if (key == ModKeyMappings.EDIT_SCOPE.getKey().getValue() && gunItem.hasCustomScope(stack)) { -// PacketDistributor.sendToServer(new EditMessage(0)); + PacketDistributor.sendToServer(new EditMessage(0)); editModelShake(); } else if (key == ModKeyMappings.EDIT_BARREL.getKey().getValue() && gunItem.hasCustomBarrel(stack)) { -// PacketDistributor.sendToServer(new EditMessage(1)); + PacketDistributor.sendToServer(new EditMessage(1)); editModelShake(); } else if (key == ModKeyMappings.EDIT_MAGAZINE.getKey().getValue() && gunItem.hasCustomMagazine(stack)) { -// PacketDistributor.sendToServer(new EditMessage(2)); + PacketDistributor.sendToServer(new EditMessage(2)); editModelShake(); } else if (key == ModKeyMappings.EDIT_STOCK.getKey().getValue() && gunItem.hasCustomStock(stack)) { -// PacketDistributor.sendToServer(new EditMessage(3)); + PacketDistributor.sendToServer(new EditMessage(3)); editModelShake(); } } } if (key == ModKeyMappings.SENSITIVITY_INCREASE.getKey().getValue()) { -// PacketDistributor.sendToServer(new SensitivityMessage(true)); + PacketDistributor.sendToServer(new SensitivityMessage(true)); } if (key == ModKeyMappings.SENSITIVITY_REDUCE.getKey().getValue()) { -// PacketDistributor.sendToServer(new SensitivityMessage(false)); + PacketDistributor.sendToServer(new SensitivityMessage(false)); } if (stack.is(ModTags.Items.GUN) @@ -295,11 +295,11 @@ public class ClickHandler { if (player.hasEffect(ModMobEffects.SHOCK)) return; if (stack.is(Items.SPYGLASS) && player.isScoping() && player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) { -// PacketDistributor.sendToServer(new SetFiringParametersMessage(0)); + PacketDistributor.sendToServer(new SetFiringParametersMessage(0)); } if (stack.is(ModItems.MONITOR.get())) { -// PacketDistributor.sendToServer(new DroneFireMessage(0)); + PacketDistributor.sendToServer(new DroneFireMessage(0)); } @@ -328,10 +328,10 @@ public class ClickHandler { if (!gunItem.useBackpackAmmo(stack) && GunsTool.getGunIntTag(stack, "Ammo", 0) <= 0 && GunsTool.getGunIntTag(stack, "ReloadTime") == 0) { if (ReloadConfig.LEFT_CLICK_RELOAD.get()) { -// PacketDistributor.sendToServer(new ReloadMessage(0)); + PacketDistributor.sendToServer(new ReloadMessage(0)); } } else { -// PacketDistributor.sendToServer(new FireMessage(0)); + PacketDistributor.sendToServer(new FireMessage(0)); if (!stack.is(ModItems.BOCEK.get())) { ClientEventHandler.holdFire = true; } @@ -343,14 +343,14 @@ public class ClickHandler { } public static void handleWeaponFireRelease() { -// PacketDistributor.sendToServer(new FireMessage(1)); + PacketDistributor.sendToServer(new FireMessage(1)); ClientEventHandler.holdFire = false; ClientEventHandler.holdFireVehicle = false; ClientEventHandler.customRpm = 0; } public static void handleWeaponZoomPress(Player player, ItemStack stack) { -// PacketDistributor.sendToServer(new ZoomMessage(0)); + PacketDistributor.sendToServer(new ZoomMessage(0)); if (player.getVehicle() instanceof VehicleEntity pVehicle && player.getVehicle() instanceof WeaponVehicleEntity iVehicle && iVehicle.hasWeapon(pVehicle.getSeatIndex(player))) { ClientEventHandler.zoomVehicle = true; @@ -367,7 +367,7 @@ public class ClickHandler { } public static void handleWeaponZoomRelease() { -// PacketDistributor.sendToServer(new ZoomMessage(1)); + PacketDistributor.sendToServer(new ZoomMessage(1)); ClientEventHandler.zoom = false; ClientEventHandler.zoomVehicle = false; ClientEventHandler.entity = null; @@ -415,6 +415,6 @@ public class ClickHandler { ClientEventHandler.dismountCountdown = 20; return; } -// PacketDistributor.sendToServer(new PlayerStopRidingMessage(0)); + PacketDistributor.sendToServer(new PlayerStopRidingMessage(0)); } } \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/ChargingStationScreen.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/ChargingStationScreen.java index cbd5d5220..0398d6ec2 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/screens/ChargingStationScreen.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/ChargingStationScreen.java @@ -92,7 +92,7 @@ public class ChargingStationScreen extends AbstractContainerScreen { double moveZ = (entity.getZ() - pos.getZ()) / range * 74; if (pMouseX >= centerX + moveX && pMouseX <= centerX + moveX + 4 && pMouseY >= centerY + moveZ && pMouseY <= centerY + moveZ + 4) { - // TODO network - // ModUtils.PACKET_HANDLER.sendToServer(new RadarSetPosMessage(entity.getOnPos())); + PacketDistributor.sendToServer(new RadarSetPosMessage(entity.getOnPos())); this.currentPos = entity.getOnPos(); this.currentTarget = entity; return true; @@ -287,12 +291,10 @@ public class FuMO25Screen extends AbstractContainerScreen { @Override public void onPress() { if (FuMO25Screen.this.menu.getFuncType() == 3 && FuMO25Screen.this.menu.getSlot(0).getItem().isEmpty()) { - if (FuMO25Screen.this.currentTarget == null) { - } - // TODO network -// ModUtils.PACKET_HANDLER.sendToServer(new RadarSetTargetMessage(FuMO25Screen.this.currentTarget.getUUID())); + if (FuMO25Screen.this.currentTarget == null) return; + PacketDistributor.sendToServer(new RadarSetTargetMessage(FuMO25Screen.this.currentTarget.getUUID())); } else { -// ModUtils.PACKET_HANDLER.sendToServer(new RadarSetParametersMessage((byte) 0)); + PacketDistributor.sendToServer(new RadarSetParametersMessage((byte) 0)); } } @@ -322,8 +324,7 @@ public class FuMO25Screen extends AbstractContainerScreen { @Override public void onPress() { - // TODO network -// ModUtils.PACKET_HANDLER.sendToServer(new RadarChangeModeMessage((byte) this.mode)); + PacketDistributor.sendToServer(new RadarChangeModeMessage((byte) this.mode)); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/ReforgingTableScreen.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/ReforgingTableScreen.java index 9f471601f..268b226f8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/screens/ReforgingTableScreen.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/ReforgingTableScreen.java @@ -2,6 +2,8 @@ package com.atsuishio.superbwarfare.client.screens; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.menu.ReforgingTableMenu; +import com.atsuishio.superbwarfare.network.message.send.GunReforgeMessage; +import com.atsuishio.superbwarfare.network.message.send.SetPerkLevelMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; @@ -14,6 +16,7 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; @OnlyIn(Dist.CLIENT) @@ -113,13 +116,11 @@ public class ReforgingTableScreen extends AbstractContainerScreen { if (ReforgingTableScreen.this.menu.ammoPerkLevel.get() >= ReforgingTableMenu.MAX_PERK_LEVEL) { + return; } } case FUNCTIONAL -> { if (ReforgingTableScreen.this.menu.funcPerkLevel.get() >= ReforgingTableMenu.MAX_PERK_LEVEL) { + + return; } } case DAMAGE -> { if (ReforgingTableScreen.this.menu.damagePerkLevel.get() >= ReforgingTableMenu.MAX_PERK_LEVEL) { + return; } } } - // TODO network -// ModUtils.PACKET_HANDLER.sendToServer(new SetPerkLevelMessage(type.ordinal(), true)); + PacketDistributor.sendToServer(new SetPerkLevelMessage(type.ordinal(), true)); } @Override @@ -189,20 +193,22 @@ public class ReforgingTableScreen extends AbstractContainerScreen { if (ReforgingTableScreen.this.menu.ammoPerkLevel.get() <= 1) { + return; } } case FUNCTIONAL -> { if (ReforgingTableScreen.this.menu.funcPerkLevel.get() <= 1) { + return; } } case DAMAGE -> { if (ReforgingTableScreen.this.menu.damagePerkLevel.get() <= 1) { + return; } } } - // TODO network -// ModUtils.PACKET_HANDLER.sendToServer(new SetPerkLevelMessage(type.ordinal(), false)); + PacketDistributor.sendToServer(new SetPerkLevelMessage(type.ordinal(), false)); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java index 8c1cb7d06..735df4d28 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java @@ -11,9 +11,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.gun.GunItem; -import com.atsuishio.superbwarfare.network.message.send.LaserShootMessage; -import com.atsuishio.superbwarfare.network.message.send.ShootMessage; -import com.atsuishio.superbwarfare.network.message.send.VehicleMovementMessage; +import com.atsuishio.superbwarfare.network.message.send.*; import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; @@ -319,9 +317,7 @@ public class ClientEventHandler { if (gunMelee == 22) { Entity lookingEntity = TraceTool.findMeleeEntity(player, player.entityInteractionRange()); if (lookingEntity != null) { - - // TODO melee attack msg -// ModUtils.PACKET_HANDLER.sendToServer(new MeleeAttackMessage(lookingEntity.getUUID())); + PacketDistributor.sendToServer(new MeleeAttackMessage(lookingEntity.getUUID())); } } } @@ -348,13 +344,12 @@ public class ClientEventHandler { BlockState blockState = player.level().getBlockState(BlockPos.containing(looking.x(), looking.y(), looking.z())); if (lookingEntity != null) { - // TODO lunge mine attack msg -// ModUtils.PACKET_HANDLER.sendToServer(new LungeMineAttackMessage(0, lookingEntity.getUUID(), result)); + PacketDistributor.sendToServer(new LungeMineAttackMessage(0, lookingEntity.getUUID(), result.getLocation())); lungeSprint = 0; lungeAttack = 0; lungeDraw = 30; } else if ((blockState.canOcclude() || blockState.getBlock() instanceof DoorBlock || blockState.getBlock() instanceof CrossCollisionBlock || blockState.getBlock() instanceof BellBlock) && lungeSprint == 0) { -// ModUtils.PACKET_HANDLER.sendToServer(new LungeMineAttackMessage(1, player.getUUID(), result)); + PacketDistributor.sendToServer(new LungeMineAttackMessage(1, player.getUUID(), result.getLocation())); lungeSprint = 0; lungeAttack = 0; lungeDraw = 30; @@ -645,7 +640,7 @@ public class ClientEventHandler { randomShell[2] = (0.7 + (Math.random() - 0.5)); } - public static void handleShakeClient(double time, double radius, double amplitude, double x, double y, double z, final IPayloadContext context) { + public static void handleShakeClient(double time, double radius, double amplitude, double x, double y, double z) { Player player = Minecraft.getInstance().player; if (player == null) return; shakeTime = time; @@ -739,8 +734,7 @@ public class ClientEventHandler { } if (clientTimerVehicle.getProgress() >= cooldown) { - // TODO vehicle fire msg -// ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(pVehicle.getSeatIndex(player))); + PacketDistributor.sendToServer(new VehicleFireMessage(pVehicle.getSeatIndex(player))); playVehicleClientSounds(player, iVehicle, pVehicle.getSeatIndex(player)); clientTimerVehicle.setProgress((clientTimerVehicle.getProgress() - cooldown)); @@ -1533,8 +1527,7 @@ public class ClientEventHandler { List entities = SeekTool.seekLivingEntities(villager, villager.level(), 16, 120); for (var e : entities) { if (e == player) { - // TODO aim villager msg -// ModUtils.PACKET_HANDLER.sendToServer(new AimVillagerMessage(villager.getId())); + PacketDistributor.sendToServer(new AimVillagerMessage(villager.getId())); aimVillagerCountdown = 80; break; } diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java index a70b4d116..d5856ae2c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientMouseHandler.java @@ -1,15 +1,28 @@ package com.atsuishio.superbwarfare.event; import com.atsuishio.superbwarfare.client.MouseMovementHandler; +import com.atsuishio.superbwarfare.config.client.VehicleControlConfig; +import com.atsuishio.superbwarfare.entity.vehicle.*; +import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModMobEffects; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.NBTTool; +import net.minecraft.client.CameraType; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec2; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.CalculatePlayerTurnEvent; import net.neoforged.neoforge.client.event.ViewportEvent; +import static com.atsuishio.superbwarfare.event.ClientEventHandler.droneFovLerp; import static com.atsuishio.superbwarfare.event.ClientEventHandler.isFreeCam; @EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) @@ -73,4 +86,88 @@ public class ClientMouseHandler { freeCameraPitch *= 0.8; } } + + @SubscribeEvent + public static void calculatePlayerTurn(CalculatePlayerTurnEvent event) { + var newSensitivity = changeSensitivity(event.getMouseSensitivity()) * invertY(); + } + + public static float invertY() { + Minecraft mc = Minecraft.getInstance(); + Player player = mc.player; + + if (player == null) return 1; + + if (player.getVehicle() instanceof Ah6Entity ah6Entity && ah6Entity.getFirstPassenger() == player) { + return VehicleControlConfig.INVERT_AIRCRAFT_CONTROL.get() ? -1 : 1; + } + + if (player.getVehicle() instanceof Tom6Entity tom6 && tom6.getFirstPassenger() == player) { + return VehicleControlConfig.INVERT_AIRCRAFT_CONTROL.get() ? -1 : 1; + } + return 1; + } + + private static double changeSensitivity(double original) { + Minecraft mc = Minecraft.getInstance(); + Player player = mc.player; + + if (player == null) return original; + + if (player.hasEffect(ModMobEffects.SHOCK) && !player.isSpectator()) { + return 0; + } + + ItemStack stack = mc.player.getMainHandItem(); + + if (isFreeCam(player)) { + return 0; + } + + if (player.getVehicle() instanceof CannonEntity) { + return ClientEventHandler.zoomVehicle ? 0.15 : 0.3; + } + + if (player.getVehicle() instanceof Lav150Entity) { + return ClientEventHandler.zoomVehicle ? 0.23 : 0.3; + } + + if (player.getVehicle() instanceof Bmp2Entity) { + return ClientEventHandler.zoomVehicle ? 0.22 : 0.27; + } + + if (player.getVehicle() instanceof Yx100Entity yx100) { + if (player == yx100.getFirstPassenger()) { + return ClientEventHandler.zoomVehicle ? 0.17 : 0.22; + } else if (player == yx100.getNthEntity(1)) { + return ClientEventHandler.zoomVehicle ? 0.25 : 0.35; + } + } + + if (player.getVehicle() instanceof Ah6Entity ah6Entity && !ah6Entity.onGround() && ah6Entity.getFirstPassenger() == player) { + return 0.33; + } + + if (player.getVehicle() instanceof Tom6Entity) { + return 0.3; + } + + var tag = NBTTool.getTag(stack); + if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) { + return 0.33 / (1 + 0.08 * (droneFovLerp - 1)); + } + + if (!stack.is(ModTags.Items.GUN)) { + return original; + } + + double zoom = 1.25 + GunsTool.getGunDoubleTag(stack, "CustomZoom", 0); + float customSens = (float) tag.getInt("sensitivity"); + + if (!player.getMainHandItem().isEmpty() && mc.options.getCameraType() == CameraType.FIRST_PERSON) { + return original / Math.max((1 + (0.2 * (zoom - (0.3 * customSens)) * ClientEventHandler.zoomTime)), 0.1); + } + + return original; + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java index 98a8adbb6..e6cbb80e1 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java @@ -15,6 +15,7 @@ import com.atsuishio.superbwarfare.event.events.PreKillEvent; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage; +import com.atsuishio.superbwarfare.network.message.receive.DrawClientMessage; import com.atsuishio.superbwarfare.network.message.receive.PlayerGunKillMessage; import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; @@ -423,8 +424,7 @@ public class LivingEventHandler { } if (player.level() instanceof ServerLevel) { - // TODO draw client msg -// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new DrawClientMessage(true)); + PacketDistributor.sendToPlayer(serverPlayer, new DrawClientMessage(true)); } var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); diff --git a/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java b/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java index 5eb11b99d..eb38b2778 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/Monitor.java @@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.item; import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; +import com.atsuishio.superbwarfare.network.message.receive.ResetCameraTypeMessage; import com.atsuishio.superbwarfare.tools.EntityFindUtil; import com.atsuishio.superbwarfare.tools.FormatTool; import com.atsuishio.superbwarfare.tools.NBTTool; @@ -21,6 +22,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import javax.annotation.ParametersAreNonnullByDefault; @@ -47,8 +49,7 @@ public class Monitor extends Item { NBTTool.setBoolean(stack, LINKED, false); tag.putString(LINKED_DRONE, "none"); if (player instanceof ServerPlayer serverPlayer) { - // TODO reset camera type msg -// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ResetCameraTypeMessage(0)); + PacketDistributor.sendToPlayer(serverPlayer, new ResetCameraTypeMessage(0)); } NBTTool.saveTag(stack, tag); } 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 c11fb02af..ac188f7ac 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,19 +5,19 @@ import com.atsuishio.superbwarfare.capability.ModCapabilities; 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.ModRarity; -import com.atsuishio.superbwarfare.init.ModSounds; -import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.message.receive.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.*; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.game.ClientboundStopSoundPacket; import net.minecraft.resources.ResourceLocation; @@ -38,6 +38,7 @@ 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.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import org.joml.Vector3d; import software.bernie.geckolib.animatable.GeoItem; @@ -169,10 +170,9 @@ public class JavelinItem extends GunItem implements GeoItem, SpecialFireWeapon { if (player instanceof ServerPlayer serverPlayer) { SoundTool.playLocalSound(serverPlayer, ModSounds.JAVELIN_LOCKON.get(), 1, 1); } - // TODO vehicle -// 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); -// } + 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); + } } } else if (tag.getInt("GuideType") == 1) { @@ -250,38 +250,37 @@ public class JavelinItem extends GunItem implements GeoItem, SpecialFireWeapon { firePos.rotateY(-yRot * Mth.DEG_TO_RAD); if (player.level() instanceof ServerLevel serverLevel) { - // TODO launch -// JavelinMissileEntity missileEntity = new JavelinMissileEntity(player, level, -// (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), -// (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), -// (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0), -// NBTTool.getOrCreateTag(stack).getInt("GuideType"), -// new Vec3(NBTTool.getOrCreateTag(stack).getDouble("TargetPosX"), NBTTool.getOrCreateTag(stack).getDouble("TargetPosY"), NBTTool.getOrCreateTag(stack).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)); + JavelinMissileEntity missileEntity = new JavelinMissileEntity(player, level, + (float) GunsTool.getGunDoubleTag(stack, "Damage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0), + (float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0), + tag.getInt("GuideType"), + new Vec3(tag.getDouble("TargetPosX"), tag.getDouble("TargetPosY"), tag.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); + + PacketDistributor.sendToPlayer(serverPlayer, new ShootClientMessage(10)); } player.getCooldowns().addCooldown(stack.getItem(), 10); 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 e33b75b8b..36cd1df2e 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,6 +4,7 @@ import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.capability.ModCapabilities; 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; @@ -11,15 +12,21 @@ 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.message.receive.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; 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; 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.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -28,6 +35,7 @@ import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; import net.minecraft.world.level.Level; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; @@ -168,46 +176,45 @@ public class M79Item extends GunItem implements GeoItem, SpecialFireWeapon { double spread = GunsTool.getGunDoubleTag(stack, "Spread"); if (player.level() instanceof ServerLevel serverLevel) { - // TODO launch -// 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()); -// -// float velocity = (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0); -// int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack); -// if (perkLevel > 0) { -// gunGrenadeEntity.setExplosionRadius((float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0) * 0.5f); -// gunGrenadeEntity.setDamage((float) GunsTool.getGunDoubleTag(stack, "Damage", 0) * (1.1f + perkLevel * 0.1f)); -// velocity *= 1.2f; -// } -// -// gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); -// gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, velocity, -// (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)); + 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()); + + float velocity = (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0); + int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack); + if (perkLevel > 0) { + gunGrenadeEntity.setExplosionRadius((float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0) * 0.5f); + gunGrenadeEntity.setDamage((float) GunsTool.getGunDoubleTag(stack, "Damage", 0) * (1.1f + perkLevel * 0.1f)); + velocity *= 1.2f; + } + + gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); + gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, velocity, + (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); + + PacketDistributor.sendToPlayer(serverPlayer, new ShootClientMessage(10)); } player.getCooldowns().addCooldown(stack.getItem(), 2); 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 c18e61b75..6d3faee4c 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,6 +4,7 @@ import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.capability.ModCapabilities; 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; @@ -11,16 +12,22 @@ 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.message.receive.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; 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; 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.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -29,6 +36,7 @@ import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; import net.minecraft.world.level.Level; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; @@ -187,47 +195,46 @@ public class RpgItem extends GunItem implements GeoItem, SpecialFireWeapon { double spread = GunsTool.getGunDoubleTag(stack, "Spread"); if (player.level() instanceof ServerLevel serverLevel) { - // TODO launch -// RpgRocketEntity rocket = new RpgRocketEntity(player, level, -// (float) GunsTool.getGunDoubleTag(stack, "Damage", 0)); -// -// var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); -// if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { -// int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); -// rocket.setMonsterMultiplier(0.1f + 0.1f * perkLevel); -// } -// -// float velocity = (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0); -// -// if (PerkHelper.getPerkByType(stack, Perk.Type.AMMO) == ModPerks.MICRO_MISSILE.get()) { -// rocket.setNoGravity(true); -// -// int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack); -// if (perkLevel > 0) { -// rocket.setExplosionRadius(0.5f); -// rocket.setDamage((float) GunsTool.getGunDoubleTag(stack, "Damage", 0) * (1.1f + perkLevel * 0.1f)); -// velocity *= 1.2f; -// } -// } -// -// rocket.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); -// rocket.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, velocity, -// (float) (zoom ? 0.1 : spread)); -// level.addFreshEntity(rocket); -// -// 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)); + RpgRocketEntity rocket = new RpgRocketEntity(player, level, + (float) GunsTool.getGunDoubleTag(stack, "Damage", 0)); + + var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); + rocket.setMonsterMultiplier(0.1f + 0.1f * perkLevel); + } + + float velocity = (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0); + + if (PerkHelper.getPerkByType(stack, Perk.Type.AMMO) == ModPerks.MICRO_MISSILE.get()) { + rocket.setNoGravity(true); + + int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack); + if (perkLevel > 0) { + rocket.setExplosionRadius(0.5f); + rocket.setDamage((float) GunsTool.getGunDoubleTag(stack, "Damage", 0) * (1.1f + perkLevel * 0.1f)); + velocity *= 1.2f; + } + } + + rocket.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); + rocket.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, velocity, + (float) (zoom ? 0.1 : spread)); + level.addFreshEntity(rocket); + + 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); + + PacketDistributor.sendToPlayer(serverPlayer, new ShootClientMessage(10)); } if (GunsTool.getGunIntTag(stack, "Ammo", 0) == 1) { 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 89c148222..4ffc4c1be 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 @@ -4,21 +4,25 @@ import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.capability.ModCapabilities; 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.ModRarity; -import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.SpecialFireWeapon; +import com.atsuishio.superbwarfare.network.message.receive.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; 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; 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.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -27,6 +31,7 @@ import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; @@ -273,57 +278,59 @@ public class SecondaryCataclysm extends GunItem implements GeoItem, SpecialFireW boolean isChargedFire = zooming && hasEnoughEnergy; if (player.level() instanceof ServerLevel serverLevel) { - // TODO launch -// 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); -// -// float velocity = (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0); -// int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack); -// if (perkLevel > 0) { -// gunGrenadeEntity.setExplosionRadius((float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0) * 0.5f); -// gunGrenadeEntity.setDamage((float) GunsTool.getGunDoubleTag(stack, "Damage", 0) * (1.1f + perkLevel * 0.1f)); -// velocity *= 1.2f; -// } -// -// gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); -// gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (isChargedFire ? 4 : 1) * velocity, -// (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)); + 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); + + float velocity = (float) GunsTool.getGunDoubleTag(stack, "Velocity", 0); + int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack); + if (perkLevel > 0) { + gunGrenadeEntity.setExplosionRadius((float) GunsTool.getGunDoubleTag(stack, "ExplosionRadius", 0) * 0.5f); + gunGrenadeEntity.setDamage((float) GunsTool.getGunDoubleTag(stack, "Damage", 0) * (1.1f + perkLevel * 0.1f)); + velocity *= 1.2f; + } + + gunGrenadeEntity.setPos(player.getX(), player.getEyeY() - 0.1, player.getZ()); + gunGrenadeEntity.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, (isChargedFire ? 4 : 1) * velocity, + (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); + + var itemCap = stack.getCapability(Capabilities.EnergyStorage.ITEM); + if (itemCap != null) { + itemCap.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); + } + + PacketDistributor.sendToPlayer(serverPlayer, new ShootClientMessage(10)); } GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); 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 4b942e2d1..3cdc1ee91 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 @@ -11,6 +11,8 @@ 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.message.receive.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; @@ -30,6 +32,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.Rarity; import net.minecraft.world.level.Level; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; @@ -40,6 +43,8 @@ import software.bernie.geckolib.util.GeckoLibUtil; import javax.annotation.ParametersAreNonnullByDefault; import java.util.Optional; +import static com.atsuishio.superbwarfare.network.message.send.FireMessage.spawnBullet; + public class BocekItem extends GunItem implements GeoItem, SpecialFireWeapon { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); @@ -172,22 +177,20 @@ public class BocekItem extends GunItem implements GeoItem, SpecialFireWeapon { SoundTool.stopSound(serverPlayer, ModSounds.BOCEK_PULL_1P.getId(), SoundSource.PLAYERS); SoundTool.stopSound(serverPlayer, ModSounds.BOCEK_PULL_3P.getId(), SoundSource.PLAYERS); - // TODO shoot client msg -// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShootClientMessage(10)); + PacketDistributor.sendToPlayer(serverPlayer, new ShootClientMessage(10)); } if (GunsTool.getGunDoubleTag(stack, "Power") >= 6) { var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); if (cap != null && cap.zoom) { - // TODO FireMessage.spawnBullet -// spawnBullet(player); + 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); -// } + 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); 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 f3792ef12..f4ccab251 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 @@ -12,6 +12,7 @@ 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.message.receive.ShootClientMessage; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.GunsTool; @@ -32,6 +33,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; import net.minecraft.world.level.Level; import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; @@ -266,8 +268,7 @@ public class TaserItem extends GunItem implements GeoItem, SpecialFireWeapon { (float) (zoom ? 0.1 : spread)); level.addFreshEntity(taserBulletProjectile); - // TODO shoot client msg -// PacketDistributor.sendToPlayer(serverPlayer, new ShootClientMessage(10)); + PacketDistributor.sendToPlayer(serverPlayer, new ShootClientMessage(10)); } GunsTool.setGunIntTag(stack, "Ammo", GunsTool.getGunIntTag(stack, "Ammo", 0) - 1); diff --git a/src/main/java/com/atsuishio/superbwarfare/menu/EnergyMenu.java b/src/main/java/com/atsuishio/superbwarfare/menu/EnergyMenu.java index 6cb835d2f..6352302f9 100644 --- a/src/main/java/com/atsuishio/superbwarfare/menu/EnergyMenu.java +++ b/src/main/java/com/atsuishio/superbwarfare/menu/EnergyMenu.java @@ -2,16 +2,23 @@ package com.atsuishio.superbwarfare.menu; import com.atsuishio.superbwarfare.network.dataslot.ContainerEnergyData; import com.atsuishio.superbwarfare.network.dataslot.ContainerEnergyDataSlot; +import com.atsuishio.superbwarfare.network.message.receive.ContainerDataMessage; +import com.atsuishio.superbwarfare.network.message.send.RadarMenuCloseMessage; +import com.atsuishio.superbwarfare.network.message.send.RadarMenuOpenMessage; import com.google.common.collect.Lists; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerContainerEvent; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -//@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME) +@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME) public abstract class EnergyMenu extends AbstractContainerMenu { private final List containerEnergyDataSlots = Lists.newArrayList(); @@ -31,18 +38,16 @@ public abstract class EnergyMenu extends AbstractContainerMenu { @Override public void broadcastChanges() { - // TODO network -// List pairs = new ArrayList<>(); -// for (int i = 0; i < this.containerEnergyDataSlots.size(); ++i) { -// ContainerEnergyDataSlot dataSlot = this.containerEnergyDataSlots.get(i); -// if (dataSlot.checkAndClearUpdateFlag()) -// pairs.add(new ContainerDataMessage.Pair(i, dataSlot.get())); -// } -// -// if (!pairs.isEmpty()) { -// PacketDistributor.PacketTarget target = PacketDistributor.NMLIST.with(this.usingPlayers.stream().map(serverPlayer -> serverPlayer.connection.connection)::toList); -// ModUtils.PACKET_HANDLER.send(target, new ContainerDataMessage(this.containerId, pairs)); -// } + List pairs = new ArrayList<>(); + for (int i = 0; i < this.containerEnergyDataSlots.size(); ++i) { + ContainerEnergyDataSlot dataSlot = this.containerEnergyDataSlots.get(i); + if (dataSlot.checkAndClearUpdateFlag()) + pairs.add(new ContainerDataMessage.Pair(i, dataSlot.get())); + } + + if (!pairs.isEmpty()) { + this.usingPlayers.forEach(p -> PacketDistributor.sendToPlayer(p, new ContainerDataMessage(this.containerId, pairs))); + } super.broadcastChanges(); } @@ -52,24 +57,38 @@ public abstract class EnergyMenu extends AbstractContainerMenu { this.containerEnergyDataSlots.get(id).set(data); } + @SubscribeEvent + public static void onContainerOpened(PlayerContainerEvent.Open event) { + if (event.getContainer() instanceof EnergyMenu menu && event.getEntity() instanceof ServerPlayer serverPlayer) { + menu.usingPlayers.add(serverPlayer); -// @SubscribeEvent -// public static void onContainerOpened(PlayerContainerEvent.Open event) { -// if (event.getContainer() instanceof EnergyMenu menu && event.getEntity() instanceof ServerPlayer serverPlayer) { -// menu.usingPlayers.add(serverPlayer); -// -//// List toSync = new ArrayList<>(); -//// for (int i = 0; i < menu.containerEnergyDataSlots.size(); ++i) { -//// toSync.add(new ContainerDataMessage.Pair(i, menu.containerEnergyDataSlots.get(i).get())); -//// } -//// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ContainerDataMessage(menu.containerId, toSync)); -// } -// } -// -// @SubscribeEvent -// public static void onContainerClosed(PlayerContainerEvent.Close event) { -// if (event.getContainer() instanceof EnergyMenu menu && event.getEntity() instanceof ServerPlayer serverPlayer) { -// menu.usingPlayers.remove(serverPlayer); -// } -// } + List toSync = new ArrayList<>(); + for (int i = 0; i < menu.containerEnergyDataSlots.size(); ++i) { + toSync.add(new ContainerDataMessage.Pair(i, menu.containerEnergyDataSlots.get(i).get())); + } + PacketDistributor.sendToPlayer(serverPlayer, new ContainerDataMessage(menu.containerId, toSync)); + } + } + + @SubscribeEvent + public static void onContainerClosed(PlayerContainerEvent.Close event) { + if (event.getContainer() instanceof EnergyMenu menu && event.getEntity() instanceof ServerPlayer serverPlayer) { + menu.usingPlayers.remove(serverPlayer); + } + } + + + @SubscribeEvent + public static void onFuMO25Opened(PlayerContainerEvent.Open event) { + if (event.getContainer() instanceof FuMO25Menu fuMO25Menu && event.getEntity() instanceof ServerPlayer serverPlayer) { + fuMO25Menu.getSelfPos().ifPresent(pos -> PacketDistributor.sendToPlayer(serverPlayer, new RadarMenuOpenMessage(pos))); + } + } + + @SubscribeEvent + public static void onFuMO25Closed(PlayerContainerEvent.Close event) { + if (event.getContainer() instanceof FuMO25Menu && event.getEntity() instanceof ServerPlayer serverPlayer) { + PacketDistributor.sendToPlayer(serverPlayer, new RadarMenuCloseMessage(0)); + } + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/menu/FuMO25Menu.java b/src/main/java/com/atsuishio/superbwarfare/menu/FuMO25Menu.java index 8f8103b7e..e3a9b0d06 100644 --- a/src/main/java/com/atsuishio/superbwarfare/menu/FuMO25Menu.java +++ b/src/main/java/com/atsuishio/superbwarfare/menu/FuMO25Menu.java @@ -8,7 +8,6 @@ import com.atsuishio.superbwarfare.init.ModMenuTypes; import com.atsuishio.superbwarfare.network.dataslot.ContainerEnergyData; import com.atsuishio.superbwarfare.network.dataslot.SimpleEnergyData; import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.Container; import net.minecraft.world.SimpleContainer; import net.minecraft.world.entity.player.Inventory; @@ -16,15 +15,11 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.ContainerLevelAccess; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.event.entity.player.PlayerContainerEvent; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.Optional; -@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME) public class FuMO25Menu extends EnergyMenu { protected final Container container; @@ -200,23 +195,4 @@ public class FuMO25Menu extends EnergyMenu { return pStack.is(ModItems.FIRING_PARAMETERS.get()); } } - - @SubscribeEvent - public static void onContainerOpened(PlayerContainerEvent.Open event) { - if (event.getContainer() instanceof FuMO25Menu fuMO25Menu && event.getEntity() instanceof ServerPlayer serverPlayer) { - fuMO25Menu.getSelfPos().ifPresent(pos -> { - } - // TODO send packet -// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new RadarMenuOpenMessage(pos)) - ); - } - } - - @SubscribeEvent - public static void onContainerClosed(PlayerContainerEvent.Close event) { - if (event.getContainer() instanceof FuMO25Menu && event.getEntity() instanceof ServerPlayer serverPlayer) { - // TODO send packet -// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new RadarMenuCloseMessage(0)); - } - } } diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/CameraMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/CameraMixin.java new file mode 100644 index 000000000..9b7c8e9d5 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/CameraMixin.java @@ -0,0 +1,174 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.*; +import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.event.ClientEventHandler; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.NBTTool; +import com.mojang.math.Axis; +import net.minecraft.client.Camera; +import net.minecraft.client.CameraType; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import org.joml.Matrix4f; +import org.joml.Vector4f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Camera.class) +public abstract class CameraMixin { + + @Shadow(aliases = "Lnet/minecraft/client/Camera;setRotation(FF)V") + protected abstract void setRotation(float x, float y); + + @Shadow(aliases = "Lnet/minecraft/client/Camera;setPosition(DDD)V") + protected abstract void setPosition(double x, double y, double z); + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setRotation(FF)V", ordinal = 0), + method = "setup(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/world/entity/Entity;ZZF)V", + cancellable = true) + private void onSetup(BlockGetter level, Entity entity, boolean detached, boolean mirrored, float partialTicks, CallbackInfo info) { + Minecraft mc = Minecraft.getInstance(); + LocalPlayer player = mc.player; + if (player == null) return; + + ItemStack stack = player.getMainHandItem(); + var tag = NBTTool.getTag(stack); + + if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) { + DroneEntity drone = EntityFindUtil.findDrone(player.level(), tag.getString("LinkedDrone")); + if (drone != null) { + Matrix4f transform = superbWarfare$getDroneTransform(drone, partialTicks); + float x0 = 0f; + float y0 = 0.075f; + float z0 = 0.18f; + + Vector4f worldPosition = superbWarfare$transformPosition(transform, x0, y0, z0); + + setRotation(drone.getYaw(partialTicks), drone.getPitch(partialTicks)); + setPosition(worldPosition.x, worldPosition.y, worldPosition.z); + info.cancel(); + } + return; + } + + if ((player.getVehicle() != null && player.getVehicle() instanceof SpeedboatEntity boat && boat.getFirstPassenger() == player) && ClientEventHandler.zoomVehicle) { + setRotation((float) -VehicleEntity.getYRotFromVector(boat.getBarrelVec(partialTicks)), (float) -VehicleEntity.getXRotFromVector(boat.getBarrelVec(partialTicks))); + if (ClientEventHandler.zoomVehicle) { + setPosition(boat.driverZoomPos(partialTicks).x, boat.driverZoomPos(partialTicks).y, boat.driverZoomPos(partialTicks).z); + } else { + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ())); + } + info.cancel(); + return; + } + + if (player.getVehicle() instanceof Lav150Entity lav150 && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) { + if (lav150.getFirstPassenger() == player) { + setRotation((float) -VehicleEntity.getYRotFromVector(lav150.getBarrelVec(partialTicks)), (float) -VehicleEntity.getXRotFromVector(lav150.getBarrelVec(partialTicks))); + if (ClientEventHandler.zoomVehicle) { + setPosition(lav150.driverZoomPos(partialTicks).x, Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), lav150.driverZoomPos(partialTicks).z); + } else { + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ())); + } + info.cancel(); + } else { + setRotation(Mth.lerp(partialTicks, player.yHeadRotO, player.getYHeadRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot())); + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()) - 6 * player.getViewVector(partialTicks).x, Mth.lerp(partialTicks, player.yo + player.getEyeHeight() + 1, player.getEyeY() + 1) - 6 * player.getViewVector(partialTicks).y, Mth.lerp(partialTicks, player.zo, player.getZ()) - 6 * player.getViewVector(partialTicks).z); + info.cancel(); + } + return; + } + + if (player.getVehicle() instanceof Bmp2Entity bmp2 && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) { + if (bmp2.getFirstPassenger() == player) { + setRotation((float) -VehicleEntity.getYRotFromVector(bmp2.getBarrelVec(partialTicks)), (float) -VehicleEntity.getXRotFromVector(bmp2.getBarrelVec(partialTicks))); + if (ClientEventHandler.zoomVehicle) { + setPosition(bmp2.driverZoomPos(partialTicks).x, Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), bmp2.driverZoomPos(partialTicks).z); + } else { + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ())); + } + info.cancel(); + } else { + setRotation(Mth.lerp(partialTicks, player.yHeadRotO, player.getYHeadRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot())); + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()) - 6 * player.getViewVector(partialTicks).x, Mth.lerp(partialTicks, player.yo + player.getEyeHeight() + 1, player.getEyeY() + 1) - 6 * player.getViewVector(partialTicks).y, Mth.lerp(partialTicks, player.zo, player.getZ()) - 6 * player.getViewVector(partialTicks).z); + info.cancel(); + } + return; + } + + if (player.getVehicle() instanceof Yx100Entity yx100 && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) { + if (yx100.getFirstPassenger() == player) { + setRotation((float) -VehicleEntity.getYRotFromVector(yx100.getBarrelVec(partialTicks)), (float) -VehicleEntity.getXRotFromVector(yx100.getBarrelVec(partialTicks))); + if (ClientEventHandler.zoomVehicle) { + setPosition(yx100.driverZoomPos(partialTicks).x, Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), yx100.driverZoomPos(partialTicks).z); + } else { + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ())); + } + info.cancel(); + } else if (yx100.getNthEntity(1) == player) { + setRotation((float) -VehicleEntity.getYRotFromVector(yx100.getGunnerVector(partialTicks)), (float) -VehicleEntity.getXRotFromVector(yx100.getGunnerVector(partialTicks))); + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ())); + info.cancel(); + } + return; + } + + if (player.getVehicle() instanceof CannonEntity && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) { + setRotation(Mth.lerp(partialTicks, player.yRotO, player.getYRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot())); + setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ())); + info.cancel(); + } + } + + @Unique + private static Matrix4f superbWarfare$getDroneTransform(DroneEntity vehicle, float ticks) { + Matrix4f transform = new Matrix4f(); + transform.translate((float) Mth.lerp(ticks, vehicle.xo, vehicle.getX()), (float) Mth.lerp(ticks, vehicle.yo, vehicle.getY()), (float) Mth.lerp(ticks, vehicle.zo, vehicle.getZ())); + transform.rotate(Axis.YP.rotationDegrees(-vehicle.getYaw(ticks))); + transform.rotate(Axis.XP.rotationDegrees(vehicle.getBodyPitch(ticks))); + transform.rotate(Axis.ZP.rotationDegrees(vehicle.getRoll(ticks))); + return transform; + } + + @Unique + private static Vector4f superbWarfare$transformPosition(Matrix4f transform, float x, float y, float z) { + return transform.transform(new Vector4f(x, y, z, 1)); + } + + // TODO camera mixin +// @Inject(method = "setup", at = @At("TAIL")) +// public void superbWarfare$setup(BlockGetter area, Entity entity, boolean thirdPerson, boolean inverseView, float tickDelta, CallbackInfo ci) { +// if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK +// && entity instanceof Player player +// && player.getMainHandItem().is(ModTags.Items.GUN) +// && Math.max(ClientEventHandler.pullPos, ClientEventHandler.zoomPos) > 0 +// ) { +// move((float) -getMaxZoom(-2.9 * Math.max(ClientEventHandler.pullPos, ClientEventHandler.zoomPos)), 0, (float) (-ClientEventHandler.cameraLocation * Math.max(ClientEventHandler.pullPos, ClientEventHandler.zoomPos))); +// return; +// } +// +// if (!thirdPerson || !(entity.getVehicle() instanceof VehicleEntity vehicle)) return; +// +// var cameraPosition = vehicle.getThirdPersonCameraPosition(vehicle.getSeatIndex(entity)); +// if (cameraPosition != null) { +// move((float) -getMaxZoom(cameraPosition.distance()), (float) cameraPosition.y(), (float) cameraPosition.z()); +// } +// } + + @Shadow + protected abstract void move(float x, float y, float z); + +// @Shadow +// protected abstract double getMaxZoom(double desiredCameraDistance); +} \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/ClientPacketListenerMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/ClientPacketListenerMixin.java new file mode 100644 index 000000000..ed753dabf --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/ClientPacketListenerMixin.java @@ -0,0 +1,72 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.init.ModKeyMappings; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.PacketUtils; +import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; +import net.minecraft.world.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientPacketListener.class) +public abstract class ClientPacketListenerMixin { + + @Shadow + private ClientLevel level; + + /** + * 正确处理VehicleEntity的带顺序乘客 + */ + @Inject(method = "handleSetEntityPassengersPacket(Lnet/minecraft/network/protocol/game/ClientboundSetPassengersPacket;)V", at = @At("HEAD"), cancellable = true) + public void vehicleEntityUpdate(ClientboundSetPassengersPacket pPacket, CallbackInfo ci) { + var minecraft = Minecraft.getInstance(); + PacketUtils.ensureRunningOnSameThread(pPacket, (ClientPacketListener) (Object) this, minecraft); + + // 只处理VehicleEntity + Entity entity = this.level.getEntity(pPacket.getVehicle()); + if (!(entity instanceof VehicleEntity vehicle)) return; + ci.cancel(); + + var player = minecraft.player; + assert player != null; + boolean hasIndirectPassenger = entity.hasIndirectPassenger(player); + + entity.ejectPassengers(); + + // 获取排序后的Passengers + var passengers = pPacket.getPassengers(); + vehicle.entityIndexOverride = (e) -> { + for (int i = 0; i < passengers.length; i++) { + if (passengers[i] == e.getId()) { + return i; + } + } + return -1; + }; + + for (int i : passengers) { + if (i == -1) continue; + + Entity passenger = this.level.getEntity(i); + if (passenger != null) { + passenger.startRiding(entity, true); + + if (passenger == player || hasIndirectPassenger) { + Component component = Component.translatable("mount.onboard", ModKeyMappings.DISMOUNT.getTranslatedKeyMessage()); + minecraft.gui.setOverlayMessage(component, false); + minecraft.getNarrator().sayNow(component); + } + } + } + + vehicle.entityIndexOverride = null; + } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/ClientPlayerEntityMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/ClientPlayerEntityMixin.java new file mode 100644 index 000000000..b5c1c249d --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/ClientPlayerEntityMixin.java @@ -0,0 +1,29 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.mojang.authlib.GameProfile; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.player.LocalPlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** + * Code based on @Luke100000's ImmersiveAircraft + */ +@Mixin(LocalPlayer.class) +public class ClientPlayerEntityMixin extends AbstractClientPlayer { + + public ClientPlayerEntityMixin(ClientLevel world, GameProfile profile) { + super(world, profile); + } + + @Inject(method = "isCrouching()Z", at = @At("HEAD"), cancellable = true) + public void ia$isCrouching(CallbackInfoReturnable cir) { + if (getRootVehicle() instanceof VehicleEntity) { + cir.setReturnValue(false); + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/ClientboundSetPassengersPacketMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/ClientboundSetPassengersPacketMixin.java new file mode 100644 index 000000000..29c061d6b --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/ClientboundSetPassengersPacketMixin.java @@ -0,0 +1,37 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; +import net.minecraft.world.entity.Entity; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(ClientboundSetPassengersPacket.class) +public class ClientboundSetPassengersPacketMixin { + + @Mutable + @Shadow + @Final + private int[] passengers; + + @Inject(method = "(Lnet/minecraft/world/entity/Entity;)V", at = @At("RETURN")) + private void init(Entity entity, CallbackInfo ci) { + if (entity instanceof VehicleEntity vehicle) { + // 使用顺序乘客信息代替原乘客信息 + List list = vehicle.getOrderedPassengers(); + passengers = new int[list.size()]; + + for (int i = 0; i < list.size(); ++i) { + var passenger = list.get(i); + passengers[i] = passenger == null ? -1 : passenger.getId(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/GameRendererMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/GameRendererMixin.java new file mode 100644 index 000000000..da74ba8ba --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/GameRendererMixin.java @@ -0,0 +1,94 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.event.ClientEventHandler; +import com.atsuishio.superbwarfare.init.ModTags; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import net.minecraft.client.Camera; +import net.minecraft.client.CameraType; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import org.joml.Quaternionf; +import org.joml.Vector3f; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(GameRenderer.class) +public class GameRendererMixin { + + @Inject(method = "bobView(Lcom/mojang/blaze3d/vertex/PoseStack;F)V", at = @At("HEAD"), cancellable = true) + public void bobView(PoseStack p_109139_, float p_109140_, CallbackInfo ci) { + Minecraft mc = Minecraft.getInstance(); + Player player = mc.player; + if (player != null) { + ItemStack stack = player.getMainHandItem(); + if (stack.is(ModTags.Items.GUN) && Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) { + ci.cancel(); + } + } + } + + // From Immersive_Aircraft + @Shadow + @Final + private Camera mainCamera; + + @SuppressWarnings("ConstantValue") + @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setup(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/world/entity/Entity;ZZF)V")) + public void superbWarfare$renderWorld(DeltaTracker deltaTracker, CallbackInfo ci) { + Entity entity = mainCamera.getEntity(); + + if (entity != null && !mainCamera.isDetached() && entity.getRootVehicle() instanceof VehicleEntity vehicle) { + // rotate camera + var tickDelta = deltaTracker.getGameTimeDeltaPartialTick(true); + float a = vehicle.getTurretYaw(tickDelta); + + float r = (Mth.abs(a) - 90f) / 90f; + + float r2; + + if (Mth.abs(a) <= 90f) { + r2 = a / 90f; + } else { + if (a < 0) { + r2 = -(180f + a) / 90f; + } else { + r2 = (180f - a) / 90f; + } + } + + // TODO game render mixin matrices +// matrices.mulPose(Axis.ZP.rotationDegrees(-r * vehicle.getRoll(tickDelta) + r2 * vehicle.getViewXRot(tickDelta))); + + if (!ClientEventHandler.zoomVehicle) { + // fetch eye offset + float eye = entity.getEyeHeight(); + + // transform eye offset to match aircraft rotation + Vector3f offset = new Vector3f(0, -eye, 0); + Quaternionf quaternion = Axis.XP.rotationDegrees(0.0f); + quaternion.mul(Axis.YP.rotationDegrees(-vehicle.getViewYRot(tickDelta))); + quaternion.mul(Axis.XP.rotationDegrees(vehicle.getViewXRot(tickDelta))); + quaternion.mul(Axis.ZP.rotationDegrees(vehicle.getRoll(tickDelta))); + offset.rotate(quaternion); + + // apply camera offset +// matrices.mulPose(Axis.XP.rotationDegrees(mainCamera.getXRot())); +// matrices.mulPose(Axis.YP.rotationDegrees(mainCamera.getYRot() + 180.0f)); +// matrices.translate(offset.x(), offset.y() + eye, offset.z()); +// matrices.mulPose(Axis.YP.rotationDegrees(-mainCamera.getYRot() - 180.0f)); +// matrices.mulPose(Axis.XP.rotationDegrees(-mainCamera.getXRot())); + } + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/ItemInHandLayerMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/ItemInHandLayerMixin.java new file mode 100644 index 000000000..294441627 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/ItemInHandLayerMixin.java @@ -0,0 +1,32 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.init.ModTags; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.layers.ItemInHandLayer; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ItemInHandLayer.class) +public class ItemInHandLayerMixin { + + @SuppressWarnings({"ConstantConditions"}) + @Inject(method = "renderArmWithItem(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemDisplayContext;Lnet/minecraft/world/entity/HumanoidArm;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + at = @At(value = "HEAD"), cancellable = true) + private void renderArmWithItemHead(LivingEntity entity, ItemStack stack, ItemDisplayContext display, HumanoidArm arm, PoseStack poseStack, MultiBufferSource source, int light, CallbackInfo ci) { + if (entity.getType() == EntityType.PLAYER && arm == HumanoidArm.LEFT) { + ItemStack mainHand = entity.getMainHandItem(); + if (!mainHand.is(ModTags.Items.GUN)) return; + + ci.cancel(); + } + } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/KeyboardInputMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/KeyboardInputMixin.java new file mode 100644 index 000000000..c4c8c1654 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/KeyboardInputMixin.java @@ -0,0 +1,54 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModMobEffects; +import com.atsuishio.superbwarfare.tools.NBTTool; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.Input; +import net.minecraft.client.player.KeyboardInput; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(KeyboardInput.class) +public abstract class KeyboardInputMixin extends Input { + + // 按键修改mixin + @Inject(method = "tick", at = @At("RETURN")) + public void tick(boolean pIsSneaking, float pSneakingSpeedMultiplier, CallbackInfo ci) { + Minecraft mc = Minecraft.getInstance(); + Player player = mc.player; + if (player == null) return; + + ItemStack stack = player.getMainHandItem(); + var tag = NBTTool.getTag(stack); + + if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) { + this.up = false; + this.down = false; + this.left = false; + this.right = false; + this.shiftKeyDown = false; + this.forwardImpulse = 0; + this.leftImpulse = 0; + this.jumping = false; + } + + if (Minecraft.getInstance().player == null + || !Minecraft.getInstance().player.hasEffect(ModMobEffects.SHOCK) + || Minecraft.getInstance().player.isSpectator() + ) return; + + this.up = false; + this.down = false; + this.left = false; + this.right = false; + this.shiftKeyDown = false; + this.forwardImpulse = 0; + this.leftImpulse = 0; + this.jumping = false; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/KeymappingMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/KeymappingMixin.java new file mode 100644 index 000000000..8b5e10882 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/KeymappingMixin.java @@ -0,0 +1,52 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity; +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.world.entity.player.Player; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(KeyMapping.class) +public class KeymappingMixin { + + @Shadow + private InputConstants.Key key; + + @Shadow + private int clickCount; + + @Inject(method = "consumeClick()Z", at = @At("HEAD"), cancellable = true) + public void consumeClick(CallbackInfoReturnable cir) { + Player player = Minecraft.getInstance().player; + if (player == null || !(player.getVehicle() instanceof VehicleEntity vehicle)) return; + + for (int i = 0; i < 9; i++) { + if (Minecraft.getInstance().options.keyHotbarSlots[i].getKey() == key) { + if (vehicle.getMaxPassengers() > 1 + && Screen.hasShiftDown() + && i < vehicle.getMaxPassengers() + && vehicle.getNthEntity(i) == null + ) { + if (this.clickCount > 0) { + --this.clickCount; + } + cir.setReturnValue(false); + } + + if (vehicle instanceof WeaponVehicleEntity weaponVehicle && weaponVehicle.banHand(player)) { + if (this.clickCount > 0) { + --this.clickCount; + } + cir.setReturnValue(false); + } + } + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityRendererMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityRendererMixin.java new file mode 100644 index 000000000..6c24b98d3 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityRendererMixin.java @@ -0,0 +1,61 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.Ah6Entity; +import com.atsuishio.superbwarfare.entity.vehicle.SpeedboatEntity; +import com.atsuishio.superbwarfare.entity.vehicle.Tom6Entity; +import com.atsuishio.superbwarfare.entity.vehicle.WheelChairEntity; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.LivingEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// From Immersive_Aircraft +@Mixin(LivingEntityRenderer.class) +public class LivingEntityRendererMixin { + + @Inject(method = "setupRotations", at = @At("TAIL")) + public void render(T entity, PoseStack poseStack, float bob, float yBodyRot, float partialTick, float scale, CallbackInfo ci) { + if (entity.getRootVehicle() != entity && entity.getRootVehicle() instanceof VehicleEntity vehicle) { + if (vehicle instanceof Tom6Entity || vehicle instanceof WheelChairEntity || vehicle instanceof SpeedboatEntity) { + poseStack.mulPose(Axis.XP.rotationDegrees(-vehicle.getViewXRot(partialTick))); + poseStack.mulPose(Axis.ZP.rotationDegrees(-vehicle.getRoll(partialTick))); + } else if (vehicle instanceof Ah6Entity ah6Entity) { + if (entity == ah6Entity.getNthEntity(2)) { + poseStack.mulPose(Axis.XP.rotationDegrees(-ah6Entity.getRoll(partialTick))); + poseStack.mulPose(Axis.ZP.rotationDegrees(ah6Entity.getViewXRot(partialTick))); + } else if (entity == ah6Entity.getNthEntity(3)) { + poseStack.mulPose(Axis.XP.rotationDegrees(ah6Entity.getRoll(partialTick))); + poseStack.mulPose(Axis.ZP.rotationDegrees(-ah6Entity.getViewXRot(partialTick))); + } else { + poseStack.mulPose(Axis.XP.rotationDegrees(-ah6Entity.getViewXRot(partialTick))); + poseStack.mulPose(Axis.ZP.rotationDegrees(-ah6Entity.getRoll(partialTick))); + } + } else { + float a = Mth.wrapDegrees(Mth.lerp(partialTick, entity.yBodyRotO, entity.yBodyRot) - Mth.lerp(partialTick, vehicle.yRotO, vehicle.getYRot())); + + float r = (Mth.abs(a) - 90f) / 90f; + + float r2; + + if (Mth.abs(a) <= 90f) { + r2 = a / 90f; + } else { + if (a < 0) { + r2 = -(180f + a) / 90f; + } else { + r2 = (180f - a) / 90f; + } + } + + poseStack.mulPose(Axis.XP.rotationDegrees(r * vehicle.getViewXRot(partialTick) - r2 * vehicle.getRoll(partialTick))); + poseStack.mulPose(Axis.ZP.rotationDegrees(r * vehicle.getRoll(partialTick) + r2 * vehicle.getViewXRot(partialTick))); + } + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/MinecraftMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/MinecraftMixin.java new file mode 100644 index 000000000..c86395acd --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/MinecraftMixin.java @@ -0,0 +1,77 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity; +import com.atsuishio.superbwarfare.network.message.send.ChangeVehicleSeatMessage; +import com.atsuishio.superbwarfare.network.message.send.SwitchVehicleWeaponMessage; +import net.minecraft.client.Minecraft; +import net.minecraft.client.Options; +import net.minecraft.client.player.LocalPlayer; +import net.neoforged.neoforge.network.PacketDistributor; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import javax.annotation.Nullable; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + + @Shadow + @Nullable + public LocalPlayer player; + + @Shadow + @Final + public Options options; + + /** + * 在可切换座位的载具上,按下潜行键+数字键时切换座位 + * 在有武器的载具上,按下数字键时切换武器 + */ + @Inject(method = "handleKeybinds()V", at = @At("HEAD"), cancellable = true) + private void handleKeybinds(CallbackInfo ci) { + if (player == null || !(player.getVehicle() instanceof VehicleEntity vehicle)) return; + + var index = -1; + for (int i = 0; i < 9; ++i) { + if (options.keyHotbarSlots[i].isDown()) { + index = i; + break; + } + } + if (index == -1) return; + + // shift+数字键 座位更改 + if (vehicle.getMaxPassengers() > 1 + && options.keyShift.isDown() + && index < vehicle.getMaxPassengers() + && vehicle.getNthEntity(index) == null + ) { + ci.cancel(); + options.keyHotbarSlots[index].consumeClick(); + + PacketDistributor.sendToServer(new ChangeVehicleSeatMessage(index)); + vehicle.changeSeat(player, index); + + return; + } + + var seatIndex = vehicle.getSeatIndex(player); + + if (vehicle instanceof WeaponVehicleEntity weaponVehicle && weaponVehicle.banHand(player)) { + ci.cancel(); + options.keyHotbarSlots[index].consumeClick(); + + // 数字键 武器切换 + if (!options.keyShift.isDown() + && weaponVehicle.hasWeapon(seatIndex) + && weaponVehicle.getWeaponIndex(seatIndex) != index) { + PacketDistributor.sendToServer(new SwitchVehicleWeaponMessage(seatIndex, index, true)); + } + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/MouseHandlerMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/MouseHandlerMixin.java new file mode 100644 index 000000000..bbb3aaf19 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/MouseHandlerMixin.java @@ -0,0 +1,60 @@ +package com.atsuishio.superbwarfare.mixins; + +import net.minecraft.client.MouseHandler; +import org.spongepowered.asm.mixin.Mixin; + +/** + * Author: MrCrayfish + */ +@Mixin(MouseHandler.class) +public class MouseHandlerMixin { + + private static double x; + private static double y; + + // TODO what are these??? +// @ModifyVariable(method = "turnPlayer()V", at = @At(value = "STORE", opcode = Opcodes.DSTORE), ordinal = 5) +// private double modifyD2(double d) { +// Minecraft mc = Minecraft.getInstance(); +// Player player = mc.player; +// +// if (player == null) return d; +// if (mc.options.getCameraType() != CameraType.FIRST_PERSON) return d; +// +// if (player.getVehicle() instanceof VehicleEntity vehicle) { +// x = d; +// +// double i = 0; +// +// if (vehicle.getRoll() < 0) { +// i = 1; +// } else if (vehicle.getRoll() > 0) { +// i = -1; +// } +// +// if (Mth.abs(vehicle.getRoll()) > 90) { +// i *= (1 - (Mth.abs(vehicle.getRoll()) - 90) / 90); +// } +// +// return (1 - (Mth.abs(vehicle.getRoll()) / 90)) * d + ((Mth.abs(vehicle.getRoll()) / 90)) * y * i; +// } +// return d; +// } +// +// @ModifyVariable(method = "turnPlayer()V", at = @At(value = "STORE", opcode = Opcodes.DSTORE), ordinal = 6) +// private double modifyD3(double d) { +// Minecraft mc = Minecraft.getInstance(); +// Player player = mc.player; +// +// if (player == null) return d; +// if (mc.options.getCameraType() != CameraType.FIRST_PERSON) return d; +// +// if (player.getVehicle() instanceof VehicleEntity vehicle) { +// y = d; +// return (1 - (Mth.abs(vehicle.getRoll()) / 90)) * d + ((Mth.abs(vehicle.getRoll()) / 90)) * x * (vehicle.getRoll() < 0 ? -1 : 1); +// } +// +// return d; +// } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/PlayerMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/PlayerMixin.java new file mode 100644 index 000000000..bfecb0c37 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/PlayerMixin.java @@ -0,0 +1,38 @@ +package com.atsuishio.superbwarfare.mixins; + +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** + * Code based on @Luke100000's ImmersiveAircraft + */ +@Mixin(value = Player.class, priority = 1145) +public abstract class PlayerMixin extends Entity { + + public PlayerMixin(EntityType type, Level world) { + super(type, world); + } + + @Inject(method = "wantsToStopRiding", at = @At("HEAD"), cancellable = true) + void shouldDismountInjection(CallbackInfoReturnable cir) { + if (this.getRootVehicle() instanceof VehicleEntity) { + cir.setReturnValue(false); + } + } + + @Inject(method = "updatePlayerPose()V", at = @At("TAIL")) + void updatePostInjection(CallbackInfo ci) { + if (getRootVehicle() instanceof VehicleEntity) { + this.setPose(Pose.STANDING); + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/ClientPacketHandler.java b/src/main/java/com/atsuishio/superbwarfare/network/ClientPacketHandler.java index 6fc64687f..1eca487eb 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/ClientPacketHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/ClientPacketHandler.java @@ -1,64 +1,25 @@ package com.atsuishio.superbwarfare.network; -import com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay; -import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage; -import net.neoforged.neoforge.network.handling.IPayloadContext; +import com.atsuishio.superbwarfare.event.ClientEventHandler; +import net.minecraft.client.CameraType; +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.player.Player; + +import java.util.Objects; public class ClientPacketHandler { - public static void handleClientIndicatorMessage(ClientIndicatorMessage message, final IPayloadContext context) { - var type = message.messageType(); - switch (type) { - case 1 -> CrossHairOverlay.HEAD_INDICATOR = message.value(); - case 2 -> CrossHairOverlay.KILL_INDICATOR = message.value(); - case 3 -> CrossHairOverlay.VEHICLE_INDICATOR = message.value(); - default -> CrossHairOverlay.HIT_INDICATOR = message.value(); - } - } - -// public static void handleSimulationDistanceMessage(int distance, final IPayloadContext context) { + // public static void handleSimulationDistanceMessage(int distance, final IPayloadContext context) { // if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { // DroneUIOverlay.MAX_DISTANCE = distance * 16; // } // } // -// public static void handleContainerDataMessage(int containerId, List data, final IPayloadContext context) { -// if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { -// Minecraft mc = Minecraft.getInstance(); -// if (mc.player != null && mc.player.containerMenu.containerId == containerId) { -// data.forEach(p -> ((EnergyMenu) mc.player.containerMenu).setData(p.id, p.data)); -// } -// } -// } -// -// public static void handleRadarMenuOpen(RadarMenuOpenMessage message, final IPayloadContext context) { -// FuMO25ScreenHelper.resetEntities(); -// FuMO25ScreenHelper.pos = message.pos; -// } -// -// public static void handleRadarMenuClose() { -// FuMO25ScreenHelper.resetEntities(); -// FuMO25ScreenHelper.pos = null; -// } -// -// public static void handleResetCameraType(final IPayloadContext context) { -// if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { -// Minecraft minecraft = Minecraft.getInstance(); -// Player player = minecraft.player; -// if (player == null) return; -// -// Minecraft.getInstance().options.setCameraType(Objects.requireNonNullElse(ClientEventHandler.lastCameraType, CameraType.FIRST_PERSON)); -// } -// } -// -// public static void handleClientSyncMotion(ClientMotionSyncMessage message, final IPayloadContext context) { -// if (context.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { -// var level = Minecraft.getInstance().level; -// if (level == null) return; -// Entity entity = level.getEntity(message.id); -// if (entity != null) { -// entity.lerpMotion(message.x, message.y, message.z); -// } -// } -// } + public static void handleResetCameraType() { + Minecraft minecraft = Minecraft.getInstance(); + Player player = minecraft.player; + if (player == null) return; + + Minecraft.getInstance().options.setCameraType(Objects.requireNonNullElse(ClientEventHandler.lastCameraType, CameraType.FIRST_PERSON)); + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java b/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java index 633b503eb..715270a91 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/NetworkRegistry.java @@ -15,11 +15,43 @@ public class NetworkRegistry { registrar.playToClient(ClientIndicatorMessage.TYPE, ClientIndicatorMessage.STREAM_CODEC, ClientIndicatorMessage::handler); registrar.playToClient(PlayerGunKillMessage.TYPE, PlayerGunKillMessage.STREAM_CODEC, PlayerGunKillMessage::handler); registrar.playToClient(GunsDataMessage.TYPE, GunsDataMessage.STREAM_CODEC, GunsDataMessage::handler); + registrar.playToClient(ContainerDataMessage.TYPE, ContainerDataMessage.STREAM_CODEC, ContainerDataMessage::handler); + registrar.playToClient(ShootClientMessage.TYPE, ShootClientMessage.STREAM_CODEC, ShootClientMessage::handler); + registrar.playToClient(DrawClientMessage.TYPE, DrawClientMessage.STREAM_CODEC, DrawClientMessage::handler); + registrar.playToClient(ResetCameraTypeMessage.TYPE, ResetCameraTypeMessage.STREAM_CODEC, ResetCameraTypeMessage::handler); registrar.playToServer(LaserShootMessage.TYPE, LaserShootMessage.STREAM_CODEC, LaserShootMessage::handler); registrar.playToServer(BreathMessage.TYPE, BreathMessage.STREAM_CODEC, BreathMessage::handler); registrar.playToServer(ShootMessage.TYPE, ShootMessage.STREAM_CODEC, ShootMessage::handler); registrar.playToServer(DoubleJumpMessage.TYPE, DoubleJumpMessage.STREAM_CODEC, DoubleJumpMessage::handler); registrar.playToServer(VehicleMovementMessage.TYPE, VehicleMovementMessage.STREAM_CODEC, VehicleMovementMessage::handler); + registrar.playToServer(MeleeAttackMessage.TYPE, MeleeAttackMessage.STREAM_CODEC, MeleeAttackMessage::handler); + registrar.playToServer(LungeMineAttackMessage.TYPE, LungeMineAttackMessage.STREAM_CODEC, LungeMineAttackMessage::handler); + registrar.playToServer(VehicleFireMessage.TYPE, VehicleFireMessage.STREAM_CODEC, VehicleFireMessage::handler); + registrar.playToServer(AimVillagerMessage.TYPE, AimVillagerMessage.STREAM_CODEC, AimVillagerMessage::handler); + registrar.playToServer(RadarChangeModeMessage.TYPE, RadarChangeModeMessage.STREAM_CODEC, RadarChangeModeMessage::handler); + registrar.playToServer(RadarMenuCloseMessage.TYPE, RadarMenuCloseMessage.STREAM_CODEC, RadarMenuCloseMessage::handler); + registrar.playToServer(RadarMenuOpenMessage.TYPE, RadarMenuOpenMessage.STREAM_CODEC, RadarMenuOpenMessage::handler); + registrar.playToServer(RadarSetParametersMessage.TYPE, RadarSetParametersMessage.STREAM_CODEC, RadarSetParametersMessage::handler); + registrar.playToServer(RadarSetPosMessage.TYPE, RadarSetPosMessage.STREAM_CODEC, RadarSetPosMessage::handler); + registrar.playToServer(RadarSetTargetMessage.TYPE, RadarSetTargetMessage.STREAM_CODEC, RadarSetTargetMessage::handler); + registrar.playToServer(GunReforgeMessage.TYPE, GunReforgeMessage.STREAM_CODEC, GunReforgeMessage::handler); + registrar.playToServer(SetPerkLevelMessage.TYPE, SetPerkLevelMessage.STREAM_CODEC, SetPerkLevelMessage::handler); + registrar.playToServer(SwitchVehicleWeaponMessage.TYPE, SwitchVehicleWeaponMessage.STREAM_CODEC, SwitchVehicleWeaponMessage::handler); + registrar.playToServer(AdjustZoomFovMessage.TYPE, AdjustZoomFovMessage.STREAM_CODEC, AdjustZoomFovMessage::handler); + registrar.playToServer(SwitchScopeMessage.TYPE, SwitchScopeMessage.STREAM_CODEC, SwitchScopeMessage::handler); + registrar.playToServer(FireMessage.TYPE, FireMessage.STREAM_CODEC, FireMessage::handler); + registrar.playToServer(ReloadMessage.TYPE, ReloadMessage.STREAM_CODEC, ReloadMessage::handler); + registrar.playToServer(FireModeMessage.TYPE, FireModeMessage.STREAM_CODEC, FireModeMessage::handler); + registrar.playToServer(PlayerStopRidingMessage.TYPE, PlayerStopRidingMessage.STREAM_CODEC, PlayerStopRidingMessage::handler); + registrar.playToServer(ZoomMessage.TYPE, ZoomMessage.STREAM_CODEC, ZoomMessage::handler); + registrar.playToServer(DroneFireMessage.TYPE, DroneFireMessage.STREAM_CODEC, DroneFireMessage::handler); + registrar.playToServer(SetFiringParametersMessage.TYPE, SetFiringParametersMessage.STREAM_CODEC, SetFiringParametersMessage::handler); + registrar.playToServer(SensitivityMessage.TYPE, SensitivityMessage.STREAM_CODEC, SensitivityMessage::handler); + registrar.playToServer(EditMessage.TYPE, EditMessage.STREAM_CODEC, EditMessage::handler); + registrar.playToServer(EditModeMessage.TYPE, EditModeMessage.STREAM_CODEC, EditModeMessage::handler); + registrar.playToServer(InteractMessage.TYPE, InteractMessage.STREAM_CODEC, InteractMessage::handler); + registrar.playToServer(AdjustMortarAngleMessage.TYPE, AdjustMortarAngleMessage.STREAM_CODEC, AdjustMortarAngleMessage::handler); + registrar.playToServer(ChangeVehicleSeatMessage.TYPE, ChangeVehicleSeatMessage.STREAM_CODEC, ChangeVehicleSeatMessage::handler); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ClientIndicatorMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ClientIndicatorMessage.java index 3bffd6453..4863c23f1 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ClientIndicatorMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ClientIndicatorMessage.java @@ -1,7 +1,7 @@ package com.atsuishio.superbwarfare.network.message.receive; import com.atsuishio.superbwarfare.Mod; -import com.atsuishio.superbwarfare.network.ClientPacketHandler; +import com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay; import io.netty.buffer.ByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; @@ -21,7 +21,13 @@ public record ClientIndicatorMessage(int messageType, int value) implements Cust ); public static void handler(final ClientIndicatorMessage message, final IPayloadContext context) { - ClientPacketHandler.handleClientIndicatorMessage(message, context); + var type = message.messageType(); + switch (type) { + case 1 -> CrossHairOverlay.HEAD_INDICATOR = message.value(); + case 2 -> CrossHairOverlay.KILL_INDICATOR = message.value(); + case 3 -> CrossHairOverlay.VEHICLE_INDICATOR = message.value(); + default -> CrossHairOverlay.HIT_INDICATOR = message.value(); + } } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ContainerDataMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ContainerDataMessage.java new file mode 100644 index 000000000..a5959aadd --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ContainerDataMessage.java @@ -0,0 +1,47 @@ +package com.atsuishio.superbwarfare.network.message.receive; + +import com.atsuishio.superbwarfare.Mod; +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Code based on @GoryMoon's Chargers + */ +public record ContainerDataMessage(int containerId, List data) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("container_data")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, ContainerDataMessage::containerId, + StreamCodec.composite( + ByteBufCodecs.INT, Pair::id, + ByteBufCodecs.INT, Pair::data, + Pair::new + ).apply(ByteBufCodecs.list()), + ContainerDataMessage::data, + ContainerDataMessage::new + ); + + + public static void handler(ContainerDataMessage message, final IPayloadContext context) { + Minecraft mc = Minecraft.getInstance(); + if (mc.player != null && mc.player.containerMenu.containerId == message.containerId) { + message.data.forEach(p -> mc.player.containerMenu.setData(p.id, p.data)); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } + + public record Pair(int id, int data) { + } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/DrawClientMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/DrawClientMessage.java new file mode 100644 index 000000000..41793c8eb --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/DrawClientMessage.java @@ -0,0 +1,29 @@ +package com.atsuishio.superbwarfare.network.message.receive; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.event.ClientEventHandler; +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.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record DrawClientMessage(boolean draw) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("draw_client")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, + DrawClientMessage::draw, + DrawClientMessage::new + ); + + public static void handler(DrawClientMessage message, final IPayloadContext context) { + ClientEventHandler.handleDrawMessage(message.draw, context); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ResetCameraTypeMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ResetCameraTypeMessage.java new file mode 100644 index 000000000..7cd81d370 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ResetCameraTypeMessage.java @@ -0,0 +1,29 @@ +package com.atsuishio.superbwarfare.network.message.receive; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.network.ClientPacketHandler; +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.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record ResetCameraTypeMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("reset_camera_type")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + ResetCameraTypeMessage::msgType, + ResetCameraTypeMessage::new + ); + + public static void handler(ResetCameraTypeMessage message, final IPayloadContext context) { + ClientPacketHandler.handleResetCameraType(); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShakeClientMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShakeClientMessage.java index 6288f3f5f..baf33e2f0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShakeClientMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShakeClientMessage.java @@ -32,7 +32,7 @@ public record ShakeClientMessage( ); public static void handler(final ShakeClientMessage message, final IPayloadContext context) { - ClientEventHandler.handleShakeClient(message.time, message.radius, message.amplitude, message.x, message.y, message.z, context); + ClientEventHandler.handleShakeClient(message.time, message.radius, message.amplitude, message.x, message.y, message.z); } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShootClientMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShootClientMessage.java new file mode 100644 index 000000000..2796e08da --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/ShootClientMessage.java @@ -0,0 +1,29 @@ +package com.atsuishio.superbwarfare.network.message.receive; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.event.ClientEventHandler; +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.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record ShootClientMessage(double time) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("shoot_client")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.DOUBLE, + ShootClientMessage::time, + ShootClientMessage::new + ); + + public static void handler(ShootClientMessage message, final IPayloadContext context) { + ClientEventHandler.handleClientShoot(); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustMortarAngleMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustMortarAngleMessage.java new file mode 100644 index 000000000..1d7bb20a4 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustMortarAngleMessage.java @@ -0,0 +1,46 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.MortarEntity; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.tools.SoundTool; +import com.atsuishio.superbwarfare.tools.TraceTool; +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.util.Mth; +import net.minecraft.world.entity.Entity; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import static com.atsuishio.superbwarfare.entity.MortarEntity.PITCH; + +public record AdjustMortarAngleMessage(double scroll) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("adjust_mortar_angle")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.DOUBLE, + AdjustMortarAngleMessage::scroll, + AdjustMortarAngleMessage::new + ); + + public static void handler(AdjustMortarAngleMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + Entity looking = TraceTool.findLookingEntity(player, 6); + if (looking == null) return; + + if (looking instanceof MortarEntity mortar) { + mortar.getEntityData().set(PITCH, (float) Mth.clamp(mortar.getEntityData().get(PITCH) + 0.5 * message.scroll, -89, -20)); + } + + SoundTool.playLocalSound(player, ModSounds.ADJUST_FOV.get(), 1f, 0.7f); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustZoomFovMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustZoomFovMessage.java new file mode 100644 index 000000000..746e87250 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/AdjustZoomFovMessage.java @@ -0,0 +1,73 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.tools.FormatTool; +import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.SoundTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.network.chat.Component; +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.util.Mth; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record AdjustZoomFovMessage(double scroll) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("adjust_zoom_fov")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.DOUBLE, + AdjustZoomFovMessage::scroll, + AdjustZoomFovMessage::new + ); + + public static void handler(AdjustZoomFovMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + ItemStack stack = player.getMainHandItem(); + if (!stack.is(ModTags.Items.GUN)) return; + + if (stack.is(ModItems.MINIGUN.get())) { + double minRpm = 300; + double maxRpm = 2400; + + GunsTool.setGunIntTag(stack, "RPM", (int) Mth.clamp(GunsTool.getGunIntTag(stack, "RPM", 0) + 50 * message.scroll, minRpm, maxRpm)); + if (GunsTool.getGunIntTag(stack, "RPM", 0) == 1150) { + GunsTool.setGunIntTag(stack, "RPM", 1145); + } + + if (GunsTool.getGunIntTag(stack, "RPM", 0) == 1195) { + GunsTool.setGunIntTag(stack, "RPM", 1200); + } + + if (GunsTool.getGunIntTag(stack, "RPM", 0) == 1095) { + GunsTool.setGunIntTag(stack, "RPM", 1100); + } + player.displayClientMessage(Component.literal("RPM: " + FormatTool.format0D(GunsTool.getGunIntTag(stack, "RPM", 0))), true); + int rpm = GunsTool.getGunIntTag(stack, "RPM", 0); + if (rpm > minRpm && rpm < maxRpm) { + SoundTool.playLocalSound(player, ModSounds.ADJUST_FOV.get(), 1f, 0.7f); + } + } else { + double minZoom = GunsTool.getGunDoubleTag(stack, "MinZoom", 0) - 1.25; + double maxZoom = GunsTool.getGunDoubleTag(stack, "MaxZoom", 0) - 1.25; + double customZoom = GunsTool.getGunDoubleTag(stack, "CustomZoom", 0); + GunsTool.setGunDoubleTag(stack, "CustomZoom", Mth.clamp(customZoom + 0.5 * message.scroll, minZoom, maxZoom)); + if (GunsTool.getGunDoubleTag(stack, "CustomZoom", 0) > minZoom && + GunsTool.getGunDoubleTag(stack, "CustomZoom", 0) < maxZoom) { + SoundTool.playLocalSound(player, ModSounds.ADJUST_FOV.get(), 1f, 0.7f); + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/AimVillagerMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/AimVillagerMessage.java new file mode 100644 index 000000000..53d5f05ef --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/AimVillagerMessage.java @@ -0,0 +1,41 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +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.world.entity.Entity; +import net.minecraft.world.entity.ai.gossip.GossipType; +import net.minecraft.world.entity.npc.AbstractVillager; +import net.minecraft.world.entity.npc.Villager; +import net.minecraft.world.entity.schedule.Activity; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record AimVillagerMessage(int villagerId) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("aim_villager")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + AimVillagerMessage::villagerId, + AimVillagerMessage::new + ); + + public static void handler(AimVillagerMessage message, final IPayloadContext context) { + var sender = context.player(); + + Entity entity = sender.level().getEntity(message.villagerId); + if (entity instanceof AbstractVillager abstractVillager) { + if (entity instanceof Villager villager) { + villager.getGossips().add(sender.getUUID(), GossipType.MINOR_NEGATIVE, 10); + } + abstractVillager.getBrain().setActiveActivityIfPossible(Activity.PANIC); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/BreathMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/BreathMessage.java index 37a9254e8..08e50788c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/send/BreathMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/BreathMessage.java @@ -10,12 +10,12 @@ import net.minecraft.server.level.ServerPlayer; import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; -public record BreathMessage(boolean messageType) implements CustomPacketPayload { +public record BreathMessage(boolean msgType) implements CustomPacketPayload { public static final Type TYPE = new Type<>(Mod.loc("breath")); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.BOOL, - BreathMessage::messageType, + BreathMessage::msgType, BreathMessage::new ); @@ -25,7 +25,7 @@ public record BreathMessage(boolean messageType) implements CustomPacketPayload var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); if (cap == null) return; - if (message.messageType + if (message.msgType && !cap.breathExhaustion && cap.zoom && player.getPersistentData().getDouble("NoBreath") == 0 @@ -34,7 +34,7 @@ public record BreathMessage(boolean messageType) implements CustomPacketPayload cap.syncPlayerVariables(player); } - if (!message.messageType) { + if (!message.msgType) { cap.breath = false; cap.syncPlayerVariables(player); } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/ChangeVehicleSeatMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ChangeVehicleSeatMessage.java new file mode 100644 index 000000000..9b029a75d --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ChangeVehicleSeatMessage.java @@ -0,0 +1,35 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +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.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record ChangeVehicleSeatMessage(int index) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("change_vehicle_seat")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + ChangeVehicleSeatMessage::index, + ChangeVehicleSeatMessage::new + ); + + public static void handler(ChangeVehicleSeatMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + if (!(player.getVehicle() instanceof VehicleEntity vehicle)) { + return; + } + + vehicle.changeSeat(player, message.index); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/DroneFireMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/DroneFireMessage.java new file mode 100644 index 000000000..5aaff1339 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/DroneFireMessage.java @@ -0,0 +1,85 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.NBTTool; +import com.atsuishio.superbwarfare.tools.SeekTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record DroneFireMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("drone_fire")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + DroneFireMessage::msgType, + DroneFireMessage::new + ); + + public static void handler(DroneFireMessage message, final IPayloadContext context) { + Player player = context.player(); + ItemStack stack = player.getMainHandItem(); + var tag = NBTTool.getTag(stack); + + if (stack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using") && tag.getBoolean("Linked")) { + DroneEntity drone = EntityFindUtil.findDrone(player.level(), tag.getString("LinkedDrone")); + if (drone == null) return; + + if (!player.getOffhandItem().is(ModItems.FIRING_PARAMETERS.get())) { + drone.fire = true; + } else { + boolean lookAtEntity = false; + + Entity lookingEntity = SeekTool.seekLivingEntity(drone, drone.level(), 512, 2); + + BlockHitResult result = drone.level().clip(new ClipContext(drone.getEyePosition(), drone.getEyePosition().add(drone.getViewVector(1).scale(512)), + ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, drone)); + Vec3 hitPos = result.getLocation(); + + if (lookingEntity != null) { + lookAtEntity = true; + } + + ItemStack offStack = player.getOffhandItem(); + var offTag = NBTTool.getTag(offStack); + if (lookAtEntity) { + offTag.putDouble("TargetX", lookingEntity.getX()); + offTag.putDouble("TargetY", lookingEntity.getY()); + offTag.putDouble("TargetZ", lookingEntity.getZ()); + } else { + offTag.putDouble("TargetX", hitPos.x()); + offTag.putDouble("TargetY", hitPos.y()); + offTag.putDouble("TargetZ", hitPos.z()); + } + NBTTool.saveTag(offStack, offTag); + + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") + .withStyle(ChatFormatting.GRAY) + .append(Component.literal("[" + + offTag.getInt("TargetX") + + "," + offTag.getInt("TargetY") + + "," + offTag.getInt("TargetZ") + + "]")), true); + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/EditMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/EditMessage.java new file mode 100644 index 000000000..5debb08c0 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/EditMessage.java @@ -0,0 +1,82 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.tools.NBTTool; +import com.atsuishio.superbwarfare.tools.SoundTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +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; + +public record EditMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("edit")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + EditMessage::msgType, + EditMessage::new + ); + + public static void handler(EditMessage message, final IPayloadContext context) { + pressAction(context.player(), message.msgType); + } + + public static void pressAction(Player player, int type) { + if (player == null) return; + + ItemStack stack = player.getMainHandItem(); + if (!stack.is(ModTags.Items.GUN)) return; + + var rootTag = NBTTool.getTag(stack); + CompoundTag tag = rootTag.getCompound("Attachments"); + switch (type) { + case 0 -> { + int att = tag.getInt("Scope"); + att++; + att %= 4; + tag.putInt("Scope", att); + } + case 1 -> { + int att = tag.getInt("Barrel"); + att++; + att %= 3; + tag.putInt("Barrel", att); + } + case 2 -> { + int att = tag.getInt("Magazine"); + att++; + att %= 3; + tag.putInt("Magazine", att); + } + case 3 -> { + int att = tag.getInt("Stock"); + att++; + att %= 3; + tag.putInt("Stock", att); + } + case 4 -> { + int att = tag.getInt("Grip"); + att++; + att %= 4; + tag.putInt("Grip", att); + } + } + rootTag.put("Attachments", tag); + NBTTool.saveTag(stack, rootTag); + SoundTool.playLocalSound(player, ModSounds.EDIT.get(), 1f, 1f); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} + + diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/EditModeMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/EditModeMessage.java new file mode 100644 index 000000000..1149baca6 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/EditModeMessage.java @@ -0,0 +1,51 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.capability.ModCapabilities; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.item.gun.GunItem; +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.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record EditModeMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("edit_mode")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + EditModeMessage::msgType, + EditModeMessage::new + ); + + public static void handler(EditModeMessage message, final IPayloadContext context) { + pressAction(context.player(), message.msgType); + } + + public static void pressAction(Player player, int type) { + if (player == null) return; + if (type != 0) return; + + ItemStack mainHandItem = player.getMainHandItem(); + if (!(mainHandItem.getItem() instanceof GunItem gunItem)) return; + var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); + + if (gunItem.isCustomizable(mainHandItem) && cap != null) { + if (!cap.edit) { + SoundTool.playLocalSound(player, ModSounds.EDIT_MODE.get(), 1f, 1f); + } + cap.edit = !cap.edit; + cap.syncPlayerVariables(player); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireMessage.java new file mode 100644 index 000000000..c13f90d0d --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireMessage.java @@ -0,0 +1,215 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.capability.ModCapabilities; +import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import com.atsuishio.superbwarfare.event.GunEventHandler; +import com.atsuishio.superbwarfare.init.ModPerks; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.item.gun.SpecialFireWeapon; +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.NBTTool; +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; + +public record FireMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("fire")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + FireMessage::msgType, + FireMessage::new + ); + + + public static void handler(FireMessage message, final IPayloadContext context) { + pressAction(context.player(), message.msgType); + } + + 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); + + var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); + if (type == 0) { + var tag = NBTTool.getTag(stack); + if (tag.getDouble("prepare") == 0 && GunsTool.getGunBooleanTag(stack, "Reloading") && GunsTool.getGunIntTag(stack, "Ammo", 0) > 0) { + tag.putDouble("force_stop", 1); + NBTTool.saveTag(stack, tag); + } + + if (cap != null) { + cap.edit = false; + } + + // 按下开火 + if (!(stack.getItem() instanceof SpecialFireWeapon specialFireWeapon)) { + if (cap != null) cap.syncPlayerVariables(player); + return; + } + specialFireWeapon.fireOnPress(player); + + if (cap != null) { + cap.holdFire = true; + cap.syncPlayerVariables(player); + } + } else if (type == 1) { + if (cap != null) { + cap.bowPullHold = false; + cap.holdFire = false; + cap.syncPlayerVariables(player); + } + + // 松开开火 + if (stack.getItem() instanceof SpecialFireWeapon specialFireWeapon) { + specialFireWeapon.fireOnRelease(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) + && GunsTool.getGunIntTag(stack, "BoltActionTick") == 0 + && !(NBTTool.getBoolean(stack, "is_normal_reloading", false) + || NBTTool.getBoolean(stack, "is_empty_reloading", false)) + && !GunsTool.getGunBooleanTag(stack, "Reloading") + && !GunsTool.getGunBooleanTag(stack, "Charging")) { + if (!player.getCooldowns().isOnCooldown(stack.getItem()) && GunsTool.getGunBooleanTag(stack, "NeedBoltAction", false)) { + GunsTool.setGunIntTag(stack, "BoltActionTick", GunsTool.getGunIntTag(stack, "BoltActionTime", 0) + 1); + GunEventHandler.playGunBoltSounds(player); + } + } + } + + public static double perkDamage(ItemStack stack) { + var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); + if (perk instanceof AmmoPerk ammoPerk) { + return ammoPerk.damageRate; + } + return 1; + } + + public static double perkSpeed(ItemStack stack) { + var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); + if (perk instanceof AmmoPerk ammoPerk) { + return ammoPerk.speedRate; + } + return 1; + } + + public static void spawnBullet(Player player) { + ItemStack stack = player.getMainHandItem(); + if (player.level().isClientSide()) return; + + var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); + float headshot = (float) GunsTool.getGunDoubleTag(stack, "Headshot", 0); + float velocity = 2 * (float) GunsTool.getGunDoubleTag(stack, "Power", 6) * (float) perkSpeed(stack); + float bypassArmorRate = (float) GunsTool.getGunDoubleTag(stack, "BypassesArmor", 0); + double damage; + + var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); + boolean zoom = cap != null && cap.zoom; + + float spread; + if (zoom) { + spread = 0.01f; + damage = 0.08333333 * GunsTool.getGunDoubleTag(stack, "Damage", 0) * + GunsTool.getGunDoubleTag(stack, "Power", 6) * perkDamage(stack); + } else { + spread = perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 0.5f : 2.5f; + damage = (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? 0.08333333 : 0.008333333) * + GunsTool.getGunDoubleTag(stack, "Damage", 0) * + GunsTool.getGunDoubleTag(stack, "Power", 6) * perkDamage(stack); + } + + ProjectileEntity projectile = new ProjectileEntity(player.level()) + .shooter(player) + .headShot(headshot) + .zoom(zoom); + + if (perk instanceof AmmoPerk ammoPerk) { + int level = PerkHelper.getItemPerkLevel(perk, stack); + + 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 = PerkHelper.getItemPerkLevel(perk, stack); + 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 = PerkHelper.getItemPerkLevel(perk, stack); + projectile.jhpBullet(level); + } else if (perk == ModPerks.HE_BULLET.get()) { + int level = PerkHelper.getItemPerkLevel(perk, stack); + projectile.heBullet(level); + } else if (perk == ModPerks.INCENDIARY_BULLET.get()) { + int level = PerkHelper.getItemPerkLevel(perk, stack); + projectile.fireBullet(level, !zoom); + } + + var dmgPerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); + if (dmgPerk == ModPerks.MONSTER_HUNTER.get()) { + int perkLevel = PerkHelper.getItemPerkLevel(dmgPerk, stack); + 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/FireModeMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireModeMessage.java new file mode 100644 index 000000000..f7e62d3bf --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FireModeMessage.java @@ -0,0 +1,127 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.item.gun.GunItem; +import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.NBTTool; +import com.atsuishio.superbwarfare.tools.SoundTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.nbt.CompoundTag; +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.capabilities.Capabilities; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record FireModeMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("fire_mode")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + FireModeMessage::msgType, + FireModeMessage::new + ); + + public static void handler(FireModeMessage message, final IPayloadContext context) { + changeFireMode(context.player()); + } + + public static void changeFireMode(Player player) { + ItemStack stack = player.getMainHandItem(); + if (stack.getItem() instanceof GunItem gunItem) { + CompoundTag tag = NBTTool.getTag(stack); + int fireMode = tag.getInt("FireMode"); + + int mode = gunItem.getAvailableFireModes(); + mode &= 0b111; + + if (fireMode == 0) { + if ((mode & 2) != 0) { + GunsTool.setGunIntTag(stack, "FireMode", 1); + playChangeModeSound(player); + return; + } + if ((mode & 4) != 0) { + GunsTool.setGunIntTag(stack, "FireMode", 2); + playChangeModeSound(player); + return; + } + } + + if (fireMode == 1) { + if ((mode & 4) != 0) { + GunsTool.setGunIntTag(stack, "FireMode", 2); + playChangeModeSound(player); + return; + } + if ((mode & 1) != 0) { + GunsTool.setGunIntTag(stack, "FireMode", 0); + playChangeModeSound(player); + return; + } + } + + if (fireMode == 2) { + if ((mode & 1) != 0) { + GunsTool.setGunIntTag(stack, "FireMode", 0); + playChangeModeSound(player); + return; + } + if ((mode & 2) != 0) { + GunsTool.setGunIntTag(stack, "FireMode", 1); + playChangeModeSound(player); + return; + } + } + + if (stack.getItem() == ModItems.SENTINEL.get() + && !player.isSpectator() + && !(player.getCooldowns().isOnCooldown(stack.getItem())) + && GunsTool.getGunIntTag(stack, "ReloadTime") == 0 + && !GunsTool.getGunBooleanTag(stack, "Charging")) { + + for (var cell : player.getInventory().items) { + if (cell.is(ModItems.CELL.get())) { + var cap = cell.getCapability(Capabilities.EnergyStorage.ITEM); + if (cap != null && cap.getEnergyStored() > 0) { + GunsTool.setGunBooleanTag(stack, "StartCharge", true); + } + } + } + } + + if (stack.getItem() == ModItems.JAVELIN.get()) { + tag.putBoolean("TopMode", !tag.getBoolean("TopMode")); + NBTTool.saveTag(stack, tag); + if (player instanceof ServerPlayer serverPlayer) { + SoundTool.playLocalSound(serverPlayer, ModSounds.CANNON_ZOOM_OUT.get()); + } + } + + if (stack.getItem() == ModItems.TRACHELIUM.get() && !GunsTool.getGunBooleanTag(stack, "NeedBoltAction", false)) { + tag.putBoolean("DA", !tag.getBoolean("DA")); + NBTTool.saveTag(stack, tag); + if (!tag.getBoolean("canImmediatelyShoot")) { + GunsTool.setGunBooleanTag(stack, "NeedBoltAction", true); + } + } + } + } + + private static void playChangeModeSound(Player player) { + if (player instanceof ServerPlayer serverPlayer) { + SoundTool.playLocalSound(serverPlayer, ModSounds.FIRE_RATE.get()); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/GunReforgeMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/GunReforgeMessage.java new file mode 100644 index 000000000..e73282ba2 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/GunReforgeMessage.java @@ -0,0 +1,39 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.menu.ReforgingTableMenu; +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.inventory.AbstractContainerMenu; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record GunReforgeMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("gun_reforge")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + GunReforgeMessage::msgType, + GunReforgeMessage::new + ); + + public static void handler(GunReforgeMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + AbstractContainerMenu abstractcontainermenu = player.containerMenu; + if (abstractcontainermenu instanceof ReforgingTableMenu menu) { + if (!menu.stillValid(player)) { + return; + } + menu.generateResult(); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/InteractMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/InteractMessage.java new file mode 100644 index 000000000..0de9530d0 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/InteractMessage.java @@ -0,0 +1,87 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.NBTTool; +import com.atsuishio.superbwarfare.tools.TraceTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BellBlock; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record InteractMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("interact")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + InteractMessage::msgType, + InteractMessage::new + ); + + public static void handler(InteractMessage message, final IPayloadContext context) { + handleInteract(context.player(), message.msgType); + } + + public static void handleInteract(Player player, int type) { + Level level = player.level(); + + ItemStack stack = player.getMainHandItem(); + if (stack.is(ModTags.Items.GUN)) { + double blockRange = player.blockInteractionRange(); + double entityRange = player.blockInteractionRange(); + + Vec3 looking = Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getLookAngle().scale(blockRange)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos()); + BlockPos blockPos = BlockPos.containing(looking.x(), looking.y(), looking.z()); + level.getBlockState(blockPos).useItemOn(player.getMainHandItem(), player.level(), player, InteractionHand.MAIN_HAND, BlockHitResult.miss(new Vec3(blockPos.getX(), blockPos.getY(), blockPos.getZ()), Direction.UP, blockPos)); + + if ((level.getBlockState(BlockPos.containing(looking.x(), looking.y(), looking.z()))).getBlock() instanceof BellBlock bell) { + bell.attemptToRing(level, blockPos, player.getDirection().getOpposite()); + } + + Entity lookingEntity = TraceTool.findLookingEntity(player, entityRange); + if (lookingEntity == null) return; + + player.interactOn(lookingEntity, InteractionHand.MAIN_HAND); + } else if (stack.is(ModItems.MONITOR.get()) + && NBTTool.getBoolean(stack, "Using", false) + && NBTTool.getBoolean(stack, "Linked", false) + && !player.getCooldowns().isOnCooldown(stack.getItem()) + ) { + var tag = NBTTool.getTag(stack); + DroneEntity drone = EntityFindUtil.findDrone(player.level(), tag.getString("LinkedDrone")); + + if (drone != null) { + Vec3 looking = Vec3.atLowerCornerOf(player.level().clip(new ClipContext(drone.getEyePosition(), drone.getEyePosition().add(drone.getLookAngle().scale(2)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos()); + BlockPos blockPos = BlockPos.containing(looking.x(), looking.y(), looking.z()); + player.level().getBlockState(blockPos).useItemOn(player.getMainHandItem(), player.level(), player, InteractionHand.MAIN_HAND, BlockHitResult.miss(new Vec3(blockPos.getX(), blockPos.getY(), blockPos.getZ()), Direction.UP, blockPos)); + + Entity lookingEntity = TraceTool.findLookingEntity(drone, 2); + if (lookingEntity == null) return; + + player.attack(lookingEntity); + player.getCooldowns().addCooldown(stack.getItem(), 13); + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/LungeMineAttackMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/LungeMineAttackMessage.java new file mode 100644 index 000000000..8a1c761db --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/LungeMineAttackMessage.java @@ -0,0 +1,92 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.config.server.ExplosionConfig; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.init.ModDamageTypes; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.tools.CustomExplosion; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.ParticleTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.event.EventHooks; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public record LungeMineAttackMessage(int msgType, UUID uuid, Vec3 hitPos) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("lunge_mine_melee_attack")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + LungeMineAttackMessage::msgType, + UUIDUtil.STREAM_CODEC, + LungeMineAttackMessage::uuid, + StreamCodec.composite( + ByteBufCodecs.DOUBLE, Vec3::x, + ByteBufCodecs.DOUBLE, Vec3::y, + ByteBufCodecs.DOUBLE, Vec3::z, + Vec3::new + ), + LungeMineAttackMessage::hitPos, + LungeMineAttackMessage::new + ); + + public static void handler(LungeMineAttackMessage message, final IPayloadContext context) { + Player player = context.player(); + ItemStack stack = player.getMainHandItem(); + + if (stack.is(ModItems.LUNGE_MINE.get())) { + if (message.msgType == 0) { + if (!player.isCreative()) { + stack.shrink(1); + } + Entity lookingEntity = EntityFindUtil.findEntity(player.level(), String.valueOf(message.uuid)); + if (lookingEntity != null) { + lookingEntity.hurt(ModDamageTypes.causeLungeMineDamage(player.level().registryAccess(), player, player), lookingEntity instanceof VehicleEntity ? 600 : 150); + causeLungeMineExplode(player.level(), player, lookingEntity); + } + } else if (message.msgType == 1) { + if (!player.isCreative()) { + stack.shrink(1); + } + CustomExplosion explosion = new CustomExplosion(player.level(), null, + ModDamageTypes.causeProjectileBoomDamage(player.level().registryAccess(), player, player), 60, + message.hitPos.x, message.hitPos.y, message.hitPos.z, 4f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1.25f); + explosion.explode(); + EventHooks.onExplosionStart(player.level(), explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnMediumExplosionParticles(player.level(), message.hitPos); + + } + player.swing(InteractionHand.MAIN_HAND); + } + } + + public static void causeLungeMineExplode(Level pLevel, Entity entity, Entity pLivingEntity) { + CustomExplosion explosion = new CustomExplosion(pLevel, pLivingEntity, + ModDamageTypes.causeProjectileBoomDamage(pLevel.registryAccess(), pLivingEntity, entity), 60, + pLivingEntity.getX(), pLivingEntity.getEyeY(), pLivingEntity.getZ(), 4f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1.25f); + explosion.explode(); + EventHooks.onExplosionStart(pLevel, explosion); + explosion.finalizeExplosion(false); + ParticleTool.spawnMediumExplosionParticles(pLevel, pLivingEntity.position()); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/MeleeAttackMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/MeleeAttackMessage.java new file mode 100644 index 000000000..f0076f86b --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/MeleeAttackMessage.java @@ -0,0 +1,38 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public record MeleeAttackMessage(UUID uuid) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("melee_attack")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + UUIDUtil.STREAM_CODEC, + MeleeAttackMessage::uuid, + MeleeAttackMessage::new + ); + + public static void handler(MeleeAttackMessage message, final IPayloadContext context) { + Player player = context.player(); + + Entity lookingEntity = EntityFindUtil.findEntity(player.level(), String.valueOf(message.uuid)); + if (lookingEntity != null) { + player.attack(lookingEntity); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/PlayerStopRidingMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/PlayerStopRidingMessage.java new file mode 100644 index 000000000..418148b79 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/PlayerStopRidingMessage.java @@ -0,0 +1,35 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +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.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record PlayerStopRidingMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("player_stop_riding")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + PlayerStopRidingMessage::msgType, + PlayerStopRidingMessage::new + ); + + public static void handler(PlayerStopRidingMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + var vehicle = player.getVehicle(); + if (!(vehicle instanceof VehicleEntity)) return; + + player.stopRiding(); + player.setJumping(false); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarChangeModeMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarChangeModeMessage.java new file mode 100644 index 000000000..cad08c804 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarChangeModeMessage.java @@ -0,0 +1,40 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.menu.FuMO25Menu; +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.inventory.AbstractContainerMenu; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record RadarChangeModeMessage(byte mode) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("radar_change_mode")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BYTE, + RadarChangeModeMessage::mode, + RadarChangeModeMessage::new + ); + + public static void handler(RadarChangeModeMessage message, final IPayloadContext context) { + byte mode = message.mode; + if (mode < 1 || mode > 4) return; + + ServerPlayer player = (ServerPlayer) context.player(); + + AbstractContainerMenu menu = player.containerMenu; + if (menu instanceof FuMO25Menu fuMO25Menu) { + if (!player.containerMenu.stillValid(player)) return; + fuMO25Menu.setFuncTypeAndTime(mode); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuCloseMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuCloseMessage.java new file mode 100644 index 000000000..ee7317762 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuCloseMessage.java @@ -0,0 +1,30 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.client.screens.FuMO25ScreenHelper; +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.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record RadarMenuCloseMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("radar_menu_close")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + RadarMenuCloseMessage::msgType, + RadarMenuCloseMessage::new + ); + + public static void handler(RadarMenuCloseMessage message, final IPayloadContext context) { + FuMO25ScreenHelper.resetEntities(); + FuMO25ScreenHelper.pos = null; + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuOpenMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuOpenMessage.java new file mode 100644 index 000000000..42420740c --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarMenuOpenMessage.java @@ -0,0 +1,30 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.client.screens.FuMO25ScreenHelper; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record RadarMenuOpenMessage(BlockPos pos) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("radar_menu_open")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + RadarMenuOpenMessage::pos, + RadarMenuOpenMessage::new + ); + + public static void handler(RadarMenuOpenMessage message, final IPayloadContext context) { + FuMO25ScreenHelper.resetEntities(); + FuMO25ScreenHelper.pos = null; + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetParametersMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetParametersMessage.java new file mode 100644 index 000000000..9be49dcb1 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetParametersMessage.java @@ -0,0 +1,39 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.menu.FuMO25Menu; +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.inventory.AbstractContainerMenu; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record RadarSetParametersMessage(int mode) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("radar_set_parameters")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + RadarSetParametersMessage::mode, + RadarSetParametersMessage::new + ); + + public static void handler(RadarSetParametersMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + AbstractContainerMenu menu = player.containerMenu; + if (menu instanceof FuMO25Menu fuMO25Menu) { + if (!player.containerMenu.stillValid(player)) { + return; + } + fuMO25Menu.setPosToParameters(); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetPosMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetPosMessage.java new file mode 100644 index 000000000..33f3cd99a --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetPosMessage.java @@ -0,0 +1,38 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.menu.FuMO25Menu; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record RadarSetPosMessage(BlockPos pos) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("radar_set_pos")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + RadarSetPosMessage::pos, + RadarSetPosMessage::new + ); + + + public static void handler(RadarSetPosMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + AbstractContainerMenu menu = player.containerMenu; + if (menu instanceof FuMO25Menu fuMO25Menu) { + if (!player.containerMenu.stillValid(player)) return; + fuMO25Menu.setPos(message.pos.getX(), message.pos.getY(), message.pos.getZ()); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetTargetMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetTargetMessage.java new file mode 100644 index 000000000..8fc6a2eaf --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/RadarSetTargetMessage.java @@ -0,0 +1,49 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.vehicle.LaserTowerEntity; +import com.atsuishio.superbwarfare.menu.FuMO25Menu; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; +import java.util.stream.StreamSupport; + +public record RadarSetTargetMessage(UUID target) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("radar_set_target")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + UUIDUtil.STREAM_CODEC, + RadarSetTargetMessage::target, + RadarSetTargetMessage::new + ); + + public static void handler(RadarSetTargetMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + AbstractContainerMenu menu = player.containerMenu; + if (menu instanceof FuMO25Menu fuMO25Menu) { + if (!player.containerMenu.stillValid(player)) { + return; + } + fuMO25Menu.getSelfPos().ifPresent(pos -> { + var entities = StreamSupport.stream(EntityFindUtil.getEntities(player.level()).getAll().spliterator(), false) + .filter(e -> e instanceof LaserTowerEntity towerEntity && towerEntity.getOwner() == player && towerEntity.distanceTo(player) <= 16) + .toList(); + entities.forEach(e -> e.getEntityData().set(LaserTowerEntity.TARGET_UUID, message.target.toString())); + }); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/ReloadMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ReloadMessage.java new file mode 100644 index 000000000..5c1462e90 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ReloadMessage.java @@ -0,0 +1,105 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.capability.ModCapabilities; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.item.gun.GunItem; +import com.atsuishio.superbwarfare.tools.GunsTool; +import com.atsuishio.superbwarfare.tools.NBTTool; +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.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record ReloadMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("reload")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + ReloadMessage::msgType, + ReloadMessage::new + ); + + public static void handler(ReloadMessage message, final IPayloadContext context) { + pressAction(context.player(), message.msgType); + } + + public static void pressAction(Player player, int type) { + if (type != 0) return; + var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); + if (cap != null) { + cap.edit = false; + cap.syncPlayerVariables(player); + } + + ItemStack stack = player.getMainHandItem(); + if (!player.isSpectator() + && stack.getItem() instanceof GunItem gunItem + && !GunsTool.getGunBooleanTag(stack, "Charging") + && GunsTool.getGunIntTag(stack, "ReloadTime") == 0 + && GunsTool.getGunIntTag(stack, "BoltActionTick") == 0 + && !GunsTool.getGunBooleanTag(stack, "Reloading") + ) { + boolean canSingleReload = gunItem.isIterativeReload(stack); + boolean canReload = gunItem.isMagazineReload(stack) && !gunItem.isClipReload(stack); + boolean clipLoad = GunsTool.getGunIntTag(stack, "Ammo", 0) == 0 && gunItem.isClipReload(stack); + + // 检查备弹 + boolean hasCreativeAmmoBox = player.getInventory().hasAnyMatching(item -> item.is(ModItems.CREATIVE_AMMO_BOX.get())); + + if (!hasCreativeAmmoBox && cap != null) { + if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && cap.shotgunAmmo == 0) { + return; + } else if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && cap.sniperAmmo == 0) { + return; + } else if ((stack.is(ModTags.Items.USE_HANDGUN_AMMO) || stack.is(ModTags.Items.SMG)) && cap.handgunAmmo == 0) { + return; + } else if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && cap.rifleAmmo == 0) { + return; + } else if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && cap.heavyAmmo == 0) { + return; + } else if (stack.getItem() == ModItems.TASER.get() && GunsTool.getGunIntTag(stack, "MaxAmmo") == 0) { + return; + } else if (stack.is(ModTags.Items.LAUNCHER) && GunsTool.getGunIntTag(stack, "MaxAmmo") == 0) { + return; + } + } + + if (canReload || clipLoad) { + int magazine = GunsTool.getGunIntTag(stack, "Magazine", 0); + + if (gunItem.isOpenBolt(stack)) { + if (gunItem.hasBulletInBarrel(stack)) { + if (GunsTool.getGunIntTag(stack, "Ammo", 0) < magazine + GunsTool.getGunIntTag(stack, "CustomMagazine", 0) + 1) { + GunsTool.setGunBooleanTag(stack, "StartReload", true); + } + } else { + if (GunsTool.getGunIntTag(stack, "Ammo", 0) < magazine + GunsTool.getGunIntTag(stack, "CustomMagazine", 0)) { + GunsTool.setGunBooleanTag(stack, "StartReload", true); + } + } + } else if (GunsTool.getGunIntTag(stack, "Ammo", 0) < magazine + GunsTool.getGunIntTag(stack, "CustomMagazine", 0)) { + GunsTool.setGunBooleanTag(stack, "StartReload", true); + } + return; + } + + if (canSingleReload + && GunsTool.getGunIntTag(stack, "Ammo", 0) + < GunsTool.getGunIntTag(stack, "Magazine", 0) + + GunsTool.getGunIntTag(stack, "CustomMagazine", 0)) { + NBTTool.setBoolean(stack, "start_single_reload", true); + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SensitivityMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SensitivityMessage.java new file mode 100644 index 000000000..99eac0846 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SensitivityMessage.java @@ -0,0 +1,45 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.tools.NBTTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record SensitivityMessage(boolean isAdd) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("sensitivity")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, + SensitivityMessage::isAdd, + SensitivityMessage::new + ); + + public static void handler(SensitivityMessage message, final IPayloadContext context) { + var player = context.player(); + + ItemStack stack = player.getMainHandItem(); + if (!stack.is(ModTags.Items.GUN)) return; + + var tag = NBTTool.getTag(stack); + if (message.isAdd) { + tag.putInt("sensitivity", Math.min(10, tag.getInt("sensitivity") + 1)); + } else { + tag.putInt("sensitivity", Math.max(-10, tag.getInt("sensitivity") - 1)); + } + NBTTool.saveTag(stack, tag); + player.displayClientMessage(Component.translatable("tips.superbwarfare.sensitivity", tag.getInt("sensitivity")), true); + + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java new file mode 100644 index 000000000..c49e42800 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetFiringParametersMessage.java @@ -0,0 +1,69 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.tools.NBTTool; +import com.atsuishio.superbwarfare.tools.TraceTool; +import io.netty.buffer.ByteBuf; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record SetFiringParametersMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("set_firing_parameters")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + SetFiringParametersMessage::msgType, + SetFiringParametersMessage::new + ); + + public static void handler(SetFiringParametersMessage message, final IPayloadContext context) { + Player player = context.player(); + ItemStack stack = player.getOffhandItem(); + boolean lookAtEntity = false; + Entity lookingEntity = TraceTool.findLookingEntity(player, 520); + + 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(); + + if (lookingEntity != null) { + lookAtEntity = true; + } + + var tag = NBTTool.getTag(stack); + if (lookAtEntity) { + tag.putDouble("TargetX", lookingEntity.getX()); + tag.putDouble("TargetY", lookingEntity.getY()); + tag.putDouble("TargetZ", lookingEntity.getZ()); + } else { + tag.putDouble("TargetX", hitPos.x()); + tag.putDouble("TargetY", hitPos.y()); + tag.putDouble("TargetZ", hitPos.z()); + } + NBTTool.saveTag(stack, tag); + + player.displayClientMessage(Component.translatable("tips.superbwarfare.mortar.target_pos") + .withStyle(ChatFormatting.GRAY) + .append(Component.literal("[" + tag.getInt("TargetX") + + "," + tag.getInt("TargetY") + + "," + tag.getInt("TargetZ") + + "]")), true); + + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetPerkLevelMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetPerkLevelMessage.java new file mode 100644 index 000000000..1fb443496 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SetPerkLevelMessage.java @@ -0,0 +1,40 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.menu.ReforgingTableMenu; +import com.atsuishio.superbwarfare.perk.Perk; +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.inventory.AbstractContainerMenu; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record SetPerkLevelMessage(int msgType, boolean add) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("set_perk_level")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + SetPerkLevelMessage::msgType, + ByteBufCodecs.BOOL, + SetPerkLevelMessage::add, + SetPerkLevelMessage::new + ); + + public static void handler(SetPerkLevelMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + AbstractContainerMenu abstractcontainermenu = player.containerMenu; + + if (abstractcontainermenu instanceof ReforgingTableMenu menu) { + if (!menu.stillValid(player)) return; + menu.setPerkLevel(Perk.Type.values()[message.msgType], message.add, player.getAbilities().instabuild); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchScopeMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchScopeMessage.java new file mode 100644 index 000000000..95fdf63d6 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchScopeMessage.java @@ -0,0 +1,37 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.tools.NBTTool; +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.item.ItemStack; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record SwitchScopeMessage(double scroll) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("switch_scope")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.DOUBLE, + SwitchScopeMessage::scroll, + SwitchScopeMessage::new + ); + + public static void handler(SwitchScopeMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + ItemStack stack = player.getMainHandItem(); + if (!stack.is(ModTags.Items.GUN)) return; + + NBTTool.setBoolean(stack, "ScopeAlt", NBTTool.getBoolean(stack, "ScopeAlt", false)); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchVehicleWeaponMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchVehicleWeaponMessage.java new file mode 100644 index 000000000..ee9b3f26c --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/SwitchVehicleWeaponMessage.java @@ -0,0 +1,40 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity; +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.util.Mth; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record SwitchVehicleWeaponMessage(int index, double value, boolean isScroll) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("switch_vehicle_weapon")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + SwitchVehicleWeaponMessage::index, + ByteBufCodecs.DOUBLE, + SwitchVehicleWeaponMessage::value, + ByteBufCodecs.BOOL, + SwitchVehicleWeaponMessage::isScroll, + SwitchVehicleWeaponMessage::new + ); + + public static void handler(SwitchVehicleWeaponMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + if (player.getVehicle() instanceof WeaponVehicleEntity weaponVehicle && weaponVehicle.isDriver(player)) { + var value = message.isScroll ? (Mth.clamp(message.value > 0 ? Mth.ceil(message.value) : Mth.floor(message.value), -1, 1)) : message.value; + weaponVehicle.changeWeapon(message.index, (int) value, message.isScroll); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/VehicleFireMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/VehicleFireMessage.java new file mode 100644 index 000000000..0db4a670c --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/VehicleFireMessage.java @@ -0,0 +1,32 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity; +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.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record VehicleFireMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("vehicle_fire")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + VehicleFireMessage::msgType, + VehicleFireMessage::new + ); + + public static void handler(VehicleFireMessage message, final IPayloadContext context) { + var player = context.player(); + if (player.getVehicle() instanceof ArmedVehicleEntity iVehicle) { + iVehicle.vehicleShoot(player, message.msgType); + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/ZoomMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ZoomMessage.java new file mode 100644 index 000000000..66c844461 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/ZoomMessage.java @@ -0,0 +1,82 @@ +package com.atsuishio.superbwarfare.network.message.send; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.capability.ModCapabilities; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.tools.NBTTool; +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.network.protocol.game.ClientboundStopSoundPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundSource; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +public record ZoomMessage(int msgType) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(Mod.loc("zoom")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + ZoomMessage::msgType, + ZoomMessage::new + ); + + public static void handler(ZoomMessage message, final IPayloadContext context) { + ServerPlayer player = (ServerPlayer) context.player(); + + var vehicle = player.getVehicle(); + // 缩放音效播放条件: 载具是武器载具,且该位置有可用武器 + var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE); + + if (message.msgType == 0) { + if (cap != null) { + cap.zoom = true; + cap.edit = false; + cap.syncPlayerVariables(player); + } + + if (player.isPassenger() + && vehicle instanceof WeaponVehicleEntity weaponEntity + && vehicle instanceof VehicleEntity vehicleEntity + && weaponEntity.hasWeapon(vehicleEntity.getSeatIndex(player)) + ) SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_IN.get(), 2, 1); + + } else if (message.msgType == 1) { + if (cap != null) { + cap.zoom = false; + cap.breath = false; + cap.syncPlayerVariables(player); + } + + if (player.isPassenger() + && vehicle instanceof WeaponVehicleEntity weaponEntity + && vehicle instanceof VehicleEntity vehicleEntity + && weaponEntity.hasWeapon(vehicleEntity.getSeatIndex(player)) + ) SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_OUT.get(), 2, 1); + + + if (player.getMainHandItem().getItem() == ModItems.JAVELIN.get()) { + var handItem = player.getMainHandItem(); + var tag = NBTTool.getTag(handItem); + tag.putBoolean("Seeking", false); + tag.putInt("SeekTime", 0); + tag.putString("TargetEntity", "none"); + NBTTool.saveTag(handItem, tag); + + var clientboundstopsoundpacket = new ClientboundStopSoundPacket(Mod.loc("javelin_lock"), SoundSource.PLAYERS); + player.connection.send(clientboundstopsoundpacket); + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/resources/mixins.superbwarfare.json b/src/main/resources/mixins.superbwarfare.json index 0927ecaf3..57f2e1ad8 100644 --- a/src/main/resources/mixins.superbwarfare.json +++ b/src/main/resources/mixins.superbwarfare.json @@ -4,9 +4,22 @@ "compatibilityLevel": "JAVA_21", "refmap": "mixins.superbwarfare.refmap.json", "mixins": [ - "LivingEntityMixin" + "ClientboundSetPassengersPacketMixin", + "LivingEntityMixin", + "PlayerMixin" + ], + "client": [ + "CameraMixin", + "ClientPacketListenerMixin", + "ClientPlayerEntityMixin", + "GameRendererMixin", + "ItemInHandLayerMixin", + "KeyboardInputMixin", + "KeymappingMixin", + "LivingEntityRendererMixin", + "MinecraftMixin", + "MouseHandlerMixin" ], - "client": [], "minVersion": "0.8", "injectors": { "defaultRequire": 1