package com.atsuishio.superbwarfare.event; import com.atsuishio.superbwarfare.config.common.GameplayConfig; import com.atsuishio.superbwarfare.config.server.MiscConfig; import com.atsuishio.superbwarfare.init.ModAttachments; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.init.ModTags; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.tools.*; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.Mth; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.event.AnvilUpdateEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.tick.PlayerTickEvent; @EventBusSubscriber public class PlayerEventHandler { @SubscribeEvent public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { Player player = event.getEntity(); ItemStack mainStack = player.getMainHandItem(); var tag = NBTTool.getTag(mainStack); if (mainStack.is(ModItems.MONITOR.get()) && tag.getBoolean("Using")) { tag.putBoolean("Using", false); NBTTool.saveTag(mainStack, tag); } for (ItemStack stack : player.getInventory().items) { if (stack.getItem() instanceof GunItem) { var data = GunData.from(stack); tag = data.tag(); tag.putBoolean("draw", true); data.save(); } } } @SubscribeEvent public static void onPlayerRespawned(PlayerEvent.PlayerRespawnEvent event) { Player player = event.getEntity(); var cap = player.getData(ModAttachments.PLAYER_VARIABLE).watch(); cap.zoom = false; cap.tacticalSprintExhaustion = false; cap.tacticalSprintTime = 600; player.setData(ModAttachments.PLAYER_VARIABLE, cap); cap.sync(player); handleRespawnReload(player); handleRespawnAutoArmor(player); for (ItemStack stack : player.getInventory().items) { if (stack.is(ModTags.Items.GUN)) { var data = GunData.from(stack); final var tag = data.tag(); tag.putBoolean("draw", true); data.save(); } } } @SubscribeEvent public static void onPlayerTick(PlayerTickEvent.Post event) { Player player = event.getEntity(); ItemStack stack = player.getMainHandItem(); var variable = player.getData(ModAttachments.PLAYER_VARIABLE).watch(); if (stack.is(ModTags.Items.GUN)) { handlePlayerSprint(player); handleSpecialWeaponAmmo(player); handleBocekPulling(player); } handleGround(player); handleSimulationDistance(player); handleTacticalSprint(player); handleBreath(player); variable.sync(player); } private static void handleBreath(Player player) { var cap = player.getData(ModAttachments.PLAYER_VARIABLE).watch(); if (cap.breath) { cap.breathTime = Mth.clamp(cap.breathTime - 1, 0, 100); } else { cap.breathTime = Mth.clamp(cap.breathTime + 1, 0, 100); } if (cap.breathTime == 0) { cap.breathExhaustion = true; cap.breath = false; } if (cap.breathTime == 100) { cap.breathExhaustion = false; } player.setData(ModAttachments.PLAYER_VARIABLE, cap); } private static void handleTacticalSprint(Player player) { var cap = player.getData(ModAttachments.PLAYER_VARIABLE).watch(); ItemStack stack = player.getMainHandItem(); int sprintCost; if (stack.is(ModTags.Items.GUN)) { var data = GunData.from(stack); sprintCost = (int) (5 + 0.2 * data.weight()); } else { sprintCost = 5; } if (!player.isSprinting()) { cap.tacticalSprint = false; player.getPersistentData().putBoolean("canTacticalSprint", true); } if (player.isSprinting() && !cap.tacticalSprintExhaustion && player.getPersistentData().getBoolean("canTacticalSprint") ) { cap.tacticalSprint = true; player.getPersistentData().putBoolean("canTacticalSprint", false); } if (cap.tacticalSprint) { cap.tacticalSprintTime = Mth.clamp(cap.tacticalSprintTime - sprintCost, 0, 1000); if (MiscConfig.ALLOW_TACTICAL_SPRINT.get()) { player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 2, 0, false, false)); } } else { cap.tacticalSprintTime = Mth.clamp(cap.tacticalSprintTime + 7, 0, 1000); } if (cap.tacticalSprintTime == 0) { cap.tacticalSprintExhaustion = true; cap.tacticalSprint = false; } if (cap.tacticalSprintTime == 1000) { cap.tacticalSprintExhaustion = false; player.getPersistentData().putBoolean("canTacticalSprint", true); } player.setData(ModAttachments.PLAYER_VARIABLE, cap); } /** * 判断玩家是否在奔跑 */ private static void handlePlayerSprint(Player player) { var cap = player.getData(ModAttachments.PLAYER_VARIABLE); if (cap.holdFire) { player.getPersistentData().putDouble("noRun", 10); } if (player.isShiftKeyDown() || player.isPassenger() || player.isInWater() || cap.zoom ) player.getPersistentData().putDouble("noRun", 3); if (player.getPersistentData().getDouble("noRun") > 0) { player.getPersistentData().putDouble("noRun", (player.getPersistentData().getDouble("noRun") - 1)); } if (cap.zoom || cap.holdFire) { player.setSprinting(false); } } private static void handleGround(Player player) { var cap = player.getData(ModAttachments.PLAYER_VARIABLE); if (player.onGround()) { cap.playerDoubleJump = false; player.setData(ModAttachments.PLAYER_VARIABLE, cap); } } private static void handleSpecialWeaponAmmo(Player player) { ItemStack stack = player.getMainHandItem(); var data = GunData.from(stack); var tag = data.tag(); if ((stack.is(ModItems.RPG.get()) || stack.is(ModItems.BOCEK.get())) && data.ammo() == 1) { tag.remove("IsEmpty"); } } private static void handleBocekPulling(Player player) { ItemStack stack = player.getMainHandItem(); var cap = player.getData(ModAttachments.PLAYER_VARIABLE).watch(); var data = GunData.from(stack); final var tag = data.tag(); if (cap.bowPullHold) { if (stack.getItem() == ModItems.BOCEK.get() && GunsTool.getGunIntTag(tag, "MaxAmmo") > 0 && !player.getCooldowns().isOnCooldown(stack.getItem()) && GunsTool.getGunDoubleTag(tag, "Power") < 12 ) { GunsTool.setGunDoubleTag(tag, "Power", GunsTool.getGunDoubleTag(tag, "Power") + 1); cap.bowPull = true; cap.tacticalSprint = false; player.setData(ModAttachments.PLAYER_VARIABLE, cap); player.setSprinting(false); } if (GunsTool.getGunDoubleTag(tag, "Power") == 1) { if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) { SoundTool.playLocalSound(serverPlayer, ModSounds.BOCEK_PULL_1P.get(), 2f, 1f); player.level().playSound(null, player.blockPosition(), ModSounds.BOCEK_PULL_3P.get(), SoundSource.PLAYERS, 0.5f, 1); } } } else { if (stack.getItem() == ModItems.BOCEK.get()) { GunsTool.setGunDoubleTag(tag, "Power", 0); } cap.bowPull = false; player.setData(ModAttachments.PLAYER_VARIABLE, cap); } if (GunsTool.getGunDoubleTag(tag, "Power") > 0) { cap.tacticalSprint = false; player.setData(ModAttachments.PLAYER_VARIABLE, cap); player.setSprinting(false); } cap.sync(player); data.save(); } private static void handleSimulationDistance(Player player) { if (player.level() instanceof ServerLevel serverLevel && player instanceof ServerPlayer serverPlayer) { // TODO send simulation distance to client // var distanceManager = serverLevel.getChunkSource().chunkMap.getDistanceManager(); // var playerTicketManager = distanceManager.playerTicketManager; // int maxDistance = playerTicketManager.viewDistance; // // ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new SimulationDistanceMessage(maxDistance)); } } private static void handleRespawnReload(Player player) { if (!GameplayConfig.RESPAWN_RELOAD.get()) return; for (ItemStack stack : player.getInventory().items) { if (stack.is(ModTags.Items.GUN)) { var data = GunData.from(stack); var tag = data.tag(); if (!InventoryTool.hasCreativeAmmoBox(player)) { var cap = player.getData(ModAttachments.PLAYER_VARIABLE); if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && cap.shotgunAmmo > 0) { GunsTool.reload(player, stack, data, AmmoType.SHOTGUN); } if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && cap.sniperAmmo > 0) { GunsTool.reload(player, stack, data, AmmoType.SNIPER); } if (stack.is(ModTags.Items.USE_HANDGUN_AMMO) && cap.handgunAmmo > 0) { GunsTool.reload(player, stack, data, AmmoType.HANDGUN); } if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && cap.rifleAmmo > 0) { GunsTool.reload(player, stack, data, AmmoType.RIFLE); } if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && cap.heavyAmmo > 0) { GunsTool.reload(player, stack, data, AmmoType.HEAVY); } if (stack.getItem() == ModItems.TASER.get() && GunsTool.getGunIntTag(tag, "MaxAmmo") > 0 && data.ammo() == 0) { data.setAmmo(1); player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.TASER_ELECTRODE.get(), 1, player.inventoryMenu.getCraftSlots()); } if (stack.getItem() == ModItems.M_79.get() && GunsTool.getGunIntTag(tag, "MaxAmmo") > 0 && data.ammo() == 0) { data.setAmmo(1); player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.GRENADE_40MM.get(), 1, player.inventoryMenu.getCraftSlots()); } if (stack.getItem() == ModItems.RPG.get() && GunsTool.getGunIntTag(tag, "MaxAmmo") > 0 && data.ammo() == 0) { data.setAmmo(1); player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.ROCKET.get(), 1, player.inventoryMenu.getCraftSlots()); } if (stack.getItem() == ModItems.JAVELIN.get() && GunsTool.getGunIntTag(tag, "MaxAmmo") > 0 && data.ammo() == 0) { data.setAmmo(1); player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.JAVELIN_MISSILE.get(), 1, player.inventoryMenu.getCraftSlots()); } } else { data.setAmmo(data.magazine()); } GunsTool.setGunBooleanTag(tag, "HoldOpen", false); data.save(); } } } private static void handleRespawnAutoArmor(Player player) { if (!GameplayConfig.RESPAWN_AUTO_ARMOR.get()) return; ItemStack armor = player.getItemBySlot(EquipmentSlot.CHEST); if (armor == ItemStack.EMPTY) return; var tag = NBTTool.getTag(armor); double armorPlate = tag.getDouble("ArmorPlate"); int armorLevel = 1; if (armor.is(ModTags.Items.MILITARY_ARMOR)) { armorLevel = 2; } else if (armor.is(ModTags.Items.MILITARY_ARMOR_HEAVY)) { armorLevel = 3; } if (armorPlate >= armorLevel * 15) return; for (var stack : player.getInventory().items) { if (stack.is(ModItems.ARMOR_PLATE.get())) { var stackTag = NBTTool.getTag(stack); if (stackTag.getBoolean("Infinite")) { tag.putDouble("ArmorPlate", armorLevel * 15); if (player instanceof ServerPlayer serverPlayer) { serverPlayer.level().playSound(null, serverPlayer.getOnPos(), SoundEvents.ARMOR_EQUIP_IRON.value(), SoundSource.PLAYERS, 0.5f, 1); } } else { for (int index0 = 0; index0 < Math.ceil(((armorLevel * 15) - armorPlate) / 15); index0++) { stack.finishUsingItem(player.level(), player); } } } } } @SubscribeEvent public static void onAnvilUpdate(AnvilUpdateEvent event) { ItemStack left = event.getLeft(); ItemStack right = event.getRight(); if (left.is(ModTags.Items.GUN) && right.getItem() == ModItems.SHORTCUT_PACK.get()) { ItemStack output = left.copy(); var data = GunData.from(output); data.setUpgradePoint(data.upgradePoint() + 1); data.save(); event.setOutput(output); event.setCost(10); event.setMaterialCost(1); } } }