package com.atsuishio.superbwarfare.event; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.client.ClickHandler; import com.atsuishio.superbwarfare.config.client.DisplayConfig; import com.atsuishio.superbwarfare.entity.DroneEntity; import com.atsuishio.superbwarfare.entity.ICannonEntity; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.ModVariables; import com.atsuishio.superbwarfare.network.message.LaserShootMessage; import com.atsuishio.superbwarfare.network.message.ShootMessage; import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.PerkHelper; import com.atsuishio.superbwarfare.tools.*; import net.minecraft.client.CameraType; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ClipContext; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.RenderGuiOverlayEvent; import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.client.event.RenderPlayerEvent; import net.minecraftforge.client.event.ViewportEvent; import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.registries.ForgeRegistries; import org.lwjgl.glfw.GLFW; import software.bernie.geckolib.core.animatable.model.CoreGeoBone; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT) public class ClientEventHandler { public static double zoomTime = 0; public static double zoomPos = 0; public static double zoomPosZ = 0; public static double swayTime = 0; public static double swayX = 0; public static double swayY = 0; public static double moveXTime = 0; public static double moveYTime = 0; public static double movePosX = 0; public static double movePosY = 0; public static double moveRotZ = 0; public static double movePosHorizon = 0; public static double velocityY = 0; public static double[] turnRot = {0, 0, 0}; public static double[] cameraRot = {0, 0, 0}; public static double fireRecoilTime = 0; public static double firePosTimer = 0; public static double fireRotTimer = 0; public static double firePos = 0; public static double firePosZ = 0; public static double fireRot = 0; public static double recoilTime = 0; public static double recoilHorizon = 0; public static double recoilY = 0; public static double droneRotX = 0; public static double droneRotZ = 0; public static double droneFov = 1; public static double droneFovLerp = 1; public static double breathTime = 0; public static double fov = 0; public static double pullTimer = 0; public static double bowTimer = 0; public static double handTimer = 0; public static double pullPos = 0; public static double bowPos = 0; public static double handPos = 0; public static double gunSpread = 0; public static double fireSpread = 0; public static double cantFireTime = 0; public static double lookDistance = 0; public static double cameraLocation = 0.6; public static double drawTime = 1; public static int shellIndex = 0; public static double[] shellIndexTime = {0, 0, 0, 0, 0, 0}; public static double[] randomShell = {0, 0, 0}; public static double customZoom = 0; public static MillisTimer clientTimer = new MillisTimer(); public static boolean holdFire = false; public static boolean zoom = false; public static int burstFireSize = 0; public static int customRpm = 0; public static double chamberRot = 0; public static double actionMove = 0; public static int miniGunRot = 0; public static double revolverPreTime = 0; public static double revolverWheelPreTime = 0; public static double shakeTime = 0; public static double shakeRadius = 0; public static double shakeAmplitude = 0; public static double[] shakePos = {0, 0, 0}; public static double shakeType = 0; @SubscribeEvent public static void handleWeaponTurn(RenderHandEvent event) { LocalPlayer player = Minecraft.getInstance().player; if (player == null) { return; } float xRotOffset = Mth.lerp(event.getPartialTick(), player.xBobO, player.xBob); float yRotOffset = Mth.lerp(event.getPartialTick(), player.yBobO, player.yBob); float xRot = player.getViewXRot(event.getPartialTick()) - xRotOffset; float yRot = player.getViewYRot(event.getPartialTick()) - yRotOffset; turnRot[0] = Mth.clamp(0.05 * xRot, -5, 5) * (1 - 0.75 * zoomTime); turnRot[1] = Mth.clamp(0.05 * yRot, -10, 10) * (1 - 0.75 * zoomTime) + 1.5f * (Mth.DEG_TO_RAD * recoilHorizon) * (0.5 + 0.4 * fireSpread); turnRot[2] = Mth.clamp(0.1 * yRot, -10, 10) * (1 - zoomTime); } private static boolean notInGame() { Minecraft mc = Minecraft.getInstance(); if (mc.player == null) return true; if (mc.getOverlay() != null) return true; if (mc.screen != null) return true; if (!mc.mouseHandler.isMouseGrabbed()) return true; return !mc.isWindowActive(); } private static boolean revolverPre() { Player player = Minecraft.getInstance().player; if (player == null) return false; ItemStack stack = player.getMainHandItem(); if (!stack.is(ModTags.Items.REVOLVER)) { return true; } else if (stack.is(ModTags.Items.REVOLVER) && (stack.getOrCreateTag().getBoolean("DA") || stack.getOrCreateTag().getBoolean("canImmediatelyShoot"))) { return true; } else { return revolverPreTime >= 1; } } private static boolean isMoving() { Player player = Minecraft.getInstance().player; return Minecraft.getInstance().options.keyLeft.isDown() || Minecraft.getInstance().options.keyRight.isDown() || Minecraft.getInstance().options.keyUp.isDown() || Minecraft.getInstance().options.keyDown.isDown() || (player != null && player.isSprinting()); } @SubscribeEvent public static void handleClientTick(TickEvent.ClientTickEvent event) { LocalPlayer player = Minecraft.getInstance().player; if (player == null) { return; } ItemStack stack = player.getMainHandItem(); if (stack.getItem() == ModItems.MINIGUN.get()) { if (holdFire || zoom) { miniGunRot = Math.min(miniGunRot + 5, 21); float rpm = 1; if (player.getMainHandItem().is(ModItems.MINIGUN.get())) { rpm = (float) player.getMainHandItem().getOrCreateTag().getInt("rpm") / 3600; } player.playSound(ModSounds.MINIGUN_ROT.get(), 1, 0.7f + rpm); } } if (miniGunRot > 0) { miniGunRot -= 1; } if (notInGame() && !ClickHandler.switchZoom) { zoom = false; } beamShoot(player, stack); } @SubscribeEvent public static void handleWeaponFire(TickEvent.RenderTickEvent event) { ClientLevel level = Minecraft.getInstance().level; Player player = Minecraft.getInstance().player; if (player == null) return; if (level == null) return; ItemStack stack = player.getMainHandItem(); var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); int mode = GunsTool.getGunIntTag(stack, "FireMode"); // 精准度 float times = (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); double basicDev = stack.getOrCreateTag().getDouble("spread"); double walk = isMoving() ? 0.3 * basicDev : 0; double sprint = player.isSprinting() ? 0.25 * basicDev : 0; double crouching = player.isCrouching() ? -0.15 * basicDev : 0; double prone = PlayerEventHandler.isProne(player) ? -0.3 * basicDev : 0; double jump = player.onGround() ? 0 * basicDev : 0.35 * basicDev; double ride = player.onGround() ? -0.25 * basicDev : 0; double zoomSpread; if (stack.is(ModTags.Items.SNIPER_RIFLE)) { zoomSpread = 1 - (0.995 * zoomTime); } else if (stack.is(ModTags.Items.SHOTGUN)) { if (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug) { zoomSpread = 1 - (0.85 * zoomTime); } else { zoomSpread = 1 - (0.25 * zoomTime); } } else if (stack.is(ModItems.MINIGUN.get())) { zoomSpread = 1 - (0.25 * zoomTime); } else { zoomSpread = 1 - (0.9 * zoomTime); } double spread = stack.is(ModTags.Items.SHOTGUN) || stack.is(ModItems.MINIGUN.get()) ? 1.2 * zoomSpread * (basicDev + 0.2 * (walk + sprint + crouching + prone + jump + ride) + fireSpread) : zoomSpread * (0.7 * basicDev + walk + sprint + crouching + prone + jump + ride + 0.8 * fireSpread); gunSpread = Mth.lerp(0.14 * times, gunSpread, spread); // 开火部分 double weight = stack.getOrCreateTag().getDouble("weight") + stack.getOrCreateTag().getDouble("CustomWeight"); double speed = 1 - (0.04 * weight); if (player.getPersistentData().getDouble("noRun") == 0 && player.isSprinting() && !zoom) { cantFireTime = Mth.clamp(cantFireTime + 3 * times, 0, 24); } else { cantFireTime = Mth.clamp(cantFireTime - 6 * speed * times, 0, 40); } int rpm = (int) (stack.getOrCreateTag().getDouble("rpm") + customRpm); if (rpm == 0) { rpm = 600; } if (GunsTool.getPerkIntTag(stack, "DesperadoTimePost") > 0) { int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.DESPERADO.get(), stack); rpm *= (int) (1.25 + 0.05 * perkLevel); } double rps = (double) rpm / 60; // cooldown in ms int cooldown = (int) (1000 / rps); //左轮类 if (clientTimer.getProgress() == 0 && stack.is(ModTags.Items.REVOLVER) && ((holdFire && !stack.getOrCreateTag().getBoolean("DA")) || (stack.getOrCreateTag().getInt("bolt_action_anim") < 7 && stack.getOrCreateTag().getInt("bolt_action_anim") > 2) || stack.getOrCreateTag().getBoolean("canImmediatelyShoot"))) { revolverPreTime = Mth.clamp(revolverPreTime + 0.3 * times, 0, 1); revolverWheelPreTime = Mth.clamp(revolverWheelPreTime + 0.32 * times, 0, revolverPreTime > 0.7 ? 1 : 0.55); } else if (!stack.getOrCreateTag().getBoolean("DA") && !stack.getOrCreateTag().getBoolean("canImmediatelyShoot")) { revolverPreTime = Mth.clamp(revolverPreTime - 1.2 * times, 0, 1); } if ((holdFire || burstFireSize > 0) && (player.getMainHandItem().is(ModTags.Items.NORMAL_GUN) && cantFireTime == 0 && drawTime < 0.01 && !notInGame() && !player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).edit && (!(stack.getOrCreateTag().getBoolean("is_normal_reloading") || stack.getOrCreateTag().getBoolean("is_empty_reloading")) && !stack.getOrCreateTag().getBoolean("reloading") && !stack.getOrCreateTag().getBoolean("charging") && stack.getOrCreateTag().getInt("ammo") > 0 && !player.getCooldowns().isOnCooldown(stack.getItem()) && !stack.getOrCreateTag().getBoolean("need_bolt_action") && revolverPre() ) || (stack.is(ModItems.MINIGUN.get()) && !player.isSprinting() && stack.getOrCreateTag().getDouble("overheat") == 0 && !player.getCooldowns().isOnCooldown(stack.getItem()) && miniGunRot >= 20 && ((player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables())).rifleAmmo > 0 || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) ))) { if (mode == 0) { if (clientTimer.getProgress() == 0) { clientTimer.start(); shootClient(player); } } else { if (!clientTimer.started()) { clientTimer.start(); // 首发瞬间发射 clientTimer.setProgress((cooldown + 1)); } if (clientTimer.getProgress() >= cooldown) { shootClient(player); clientTimer.setProgress((clientTimer.getProgress() - cooldown)); } } if (notInGame()) { clientTimer.stop(); } } else { if (mode != 0) { clientTimer.stop(); } fireSpread = 0; } gunPartMove(times); if (mode == 0 && clientTimer.getProgress() >= cooldown) { clientTimer.stop(); } if (stack.getItem() == ModItems.DEVOTION.get() && (stack.getOrCreateTag().getBoolean("is_normal_reloading") || stack.getOrCreateTag().getBoolean("is_empty_reloading"))) { customRpm = 0; } } public static void beamShoot(Player player, ItemStack stack) { if (stack.is(ModItems.BEAM_TEST.get()) && stack.getOrCreateTag().getBoolean("LaserFiring")) { Entity lookingEntity = TraceTool.laserfindLookingEntity(player, 512); if (player.isCrouching()) { Entity seekingEntity = SeekTool.seekLivingEntity(player, player.level(), 64, 32); if (seekingEntity != null && seekingEntity.isAlive()) { player.lookAt(EntityAnchorArgument.Anchor.EYES, seekingEntity.getEyePosition()); } } if (lookingEntity == null) { return; } boolean canAttack = lookingEntity != player && !(lookingEntity instanceof Player player_ && (player_.isCreative() || player_.isSpectator())) && (!player.isAlliedTo(lookingEntity) || lookingEntity.getTeam() == null || lookingEntity.getTeam().getName().equals("TDM")); if (canAttack) { ModUtils.PACKET_HANDLER.sendToServer(new LaserShootMessage(stack.getOrCreateTag().getInt("FireTick") >= 14 ? 45 : 1, lookingEntity.getUUID())); } } } public static void shootClient(Player player) { ItemStack stack = player.getMainHandItem(); if (stack.is(ModTags.Items.NORMAL_GUN)) { if (stack.getOrCreateTag().getInt("ammo") > 0) { int mode = GunsTool.getGunIntTag(stack, "FireMode"); if (mode != 2) { holdFire = false; } if (mode == 1) { if (stack.getOrCreateTag().getInt("ammo") == 1) { burstFireSize = 1; } if (burstFireSize == 1) { cantFireTime = 40; } burstFireSize--; } if (stack.is(ModItems.DEVOTION.get())) { int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.TURBO_CHARGER.get(), stack); customRpm = Math.min(customRpm + 15 + ((perkLevel > 0 ? 5 : 0) + 3 * perkLevel), 500); } if (stack.getItem() == ModItems.SENTINEL.get()) { chamberRot = 1; } if (stack.getItem() == ModItems.NTW_20.get()) { actionMove = 1; } revolverPreTime = 0; revolverWheelPreTime = 0; playGunClientSounds(player); handleClientShoot(); } } else if (stack.is(ModItems.MINIGUN.get())) { var tag = stack.getOrCreateTag(); if ((player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables())).rifleAmmo > 0 || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) { var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat"))); player.playSound(ModSounds.MINIGUN_FIRE_1P.get(), 1f, pitch); if (perk == ModPerks.BEAST_BULLET.get()) { player.playSound(ModSounds.HENG.get(), 1f, 1f); } double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos()))); ModUtils.queueClientWork((int) (1 + 1.5 * shooterHeight), () -> player.playSound(ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1)); } handleClientShoot(); } } public static void gunPartMove(float times) { chamberRot = Mth.lerp(0.07 * times, chamberRot, 0); actionMove = Mth.lerp(0.2 * times, actionMove, 0); } public static void handleClientShoot() { Player player = Minecraft.getInstance().player; if (player == null) return; CompoundTag tag = player.getMainHandItem().getOrCreateTag(); if (!player.getMainHandItem().is(ModTags.Items.GUN)) return; ModUtils.PACKET_HANDLER.sendToServer(new ShootMessage(gunSpread)); fireRecoilTime = 10; float gunRecoilY = (float) tag.getDouble("recoil_y") * 10; recoilY = (float) (2 * Math.random() - 1) * gunRecoilY; if (shellIndex < 5) { shellIndex++; } shellIndexTime[shellIndex] = 0.001; randomShell[0] = (1 + 0.2 * (Math.random() - 0.5)); randomShell[1] = (0.2 + (Math.random() - 0.5)); randomShell[2] = (0.7 + (Math.random() - 0.5)); } public static void handleShakeClient(double time, double radius, double amplitude, double x, double y, double z, Supplier ctx) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { Player player = Minecraft.getInstance().player; if (player == null) return; shakeTime = time; shakeRadius = radius; shakeAmplitude = amplitude * Mth.DEG_TO_RAD; shakePos[0] = x; shakePos[1] = y; shakePos[2] = z; shakeType = 2 * (Math.random() - 0.5); } } public static void playGunClientSounds(Player player) { ItemStack stack = player.getMainHandItem(); if (!stack.is(ModTags.Items.GUN)) { return; } String origin = stack.getItem().getDescriptionId(); String name = origin.substring(origin.lastIndexOf(".") + 1); if (stack.getItem() == ModItems.SENTINEL.get()) { AtomicBoolean charged = new AtomicBoolean(false); stack.getCapability(ForgeCapabilities.ENERGY).ifPresent( e -> charged.set(e.getEnergyStored() > 0) ); if (charged.get()) { SoundEvent sound1p = ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation(ModUtils.MODID, "sentinel_charge_fire_1p")); if (sound1p != null) { player.playSound(sound1p, 1f, 1); } return; } } var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); if (perk == ModPerks.BEAST_BULLET.get()) { player.playSound(ModSounds.HENG.get(), 1f, 1f); } int barrelType = GunsTool.getAttachmentType(stack, GunsTool.AttachmentType.BARREL); SoundEvent sound1p = ForgeRegistries.SOUND_EVENTS.getValue(ModUtils.loc(name + (barrelType == 2 ? "_fire_1p_s" : "_fire_1p"))); if (sound1p != null) { player.playSound(sound1p, 1f, 1); } double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos()))); ModUtils.queueClientWork((int) (1 + 1.5 * shooterHeight), () -> { if (stack.is(ModTags.Items.HAS_SHELL_EFFECT)) { if (stack.is(ModTags.Items.SHOTGUN)) { player.playSound(ModSounds.SHELL_CASING_SHOTGUN.get(), (float) Math.max(0.75 - 0.12 * shooterHeight, 0), 1); } else if (stack.is(ModTags.Items.SNIPER_RIFLE)) { player.playSound(ModSounds.SHELL_CASING_50CAL.get(), (float) Math.max(1 - 0.15 * shooterHeight, 0), 1); } else { player.playSound(ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1); } } }); } @SubscribeEvent public static void handleWeaponBreathSway(TickEvent.RenderTickEvent event) { Player player = Minecraft.getInstance().player; if (player == null) return; if (!player.getMainHandItem().is(ModTags.Items.GUN)) return; if (player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity) return; float pose; float times = 2 * (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); if (player.isCrouching() && player.getBbHeight() >= 1 && !PlayerEventHandler.isProne(player)) { pose = 0.85f; } else if (PlayerEventHandler.isProne(player)) { pose = GunsTool.getAttachmentType(player.getMainHandItem(), GunsTool.AttachmentType.GRIP) == 3 ? 0 : 0.25f; } else { pose = 1; } int stockType = GunsTool.getAttachmentType(player.getMainHandItem(), GunsTool.AttachmentType.STOCK); double sway = switch (stockType) { case 1 -> 1; case 2 -> 0.55; default -> 0.8; }; double cusWeight = player.getMainHandItem().getOrCreateTag().getDouble("CustomWeight"); if (!player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).breath && player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).zoom) { float newPitch = (float) (player.getXRot() - 0.01f * Mth.sin((float) (0.03 * player.tickCount)) * pose * Mth.nextDouble(RandomSource.create(), 0.1, 1) * times * sway * (1 - 0.03 * cusWeight)); player.setXRot(newPitch); player.xRotO = player.getXRot(); float newYaw = (float) (player.getYRot() - 0.005f * Mth.cos((float) (0.025 * (player.tickCount + 2 * Math.PI))) * pose * Mth.nextDouble(RandomSource.create(), 0.05, 1.25) * times * sway * (1 - 0.03 * cusWeight)); player.setYRot(newYaw); player.yRotO = player.getYRot(); } } @SubscribeEvent public static void computeCameraAngles(ViewportEvent.ComputeCameraAngles event) { ClientLevel level = Minecraft.getInstance().level; Entity entity = event.getCamera().getEntity(); handlePlayerCamera(event); if (level != null && entity instanceof LivingEntity living && living.getMainHandItem().is(ModItems.MONITOR.get()) && living.getMainHandItem().getOrCreateTag().getBoolean("Using") && living.getMainHandItem().getOrCreateTag().getBoolean("Linked")) { handleDroneCamera(event, living); } else { var effect = Minecraft.getInstance().gameRenderer.currentEffect(); if (effect != null && effect.getName().equals(ModUtils.MODID + ":shaders/post/scan_pincushion.json")) { Minecraft.getInstance().gameRenderer.shutdownEffect(); } } if (level != null && entity instanceof LivingEntity living && living.getMainHandItem().is(ModTags.Items.GUN)) { handleWeaponSway(living); handleWeaponMove(living); handleWeaponZoom(living); handlePlayerBreath(living); handleWeaponFire(event, living); handleWeaponShell(); handleGunRecoil(); handleShockCamera(event, living); handleBowPullAnimation(living); handleWeaponDraw(living); } float times = Minecraft.getInstance().getDeltaFrameTime(); LocalPlayer player = Minecraft.getInstance().player; float yaw = event.getYaw(); float pitch = event.getPitch(); float roll = event.getRoll(); float shakeRadiusAmplitude; shakeTime = Mth.lerp(0.25 * times, shakeTime, 0); if (player != null && shakeTime > 0) { shakeRadiusAmplitude = (float) Mth.clamp(1 - player.position().distanceTo(new Vec3(shakePos[0], shakePos[1], shakePos[2])) / shakeRadius, 0, 1); if (shakeType > 0) { event.setYaw((float) (yaw + (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * 0.75 * shakeType))); event.setPitch((float) (pitch - (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * shakeType))); event.setRoll((float) (roll - (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude))); } else { event.setYaw((float) (yaw - (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * 0.75 * shakeType))); event.setPitch((float) (pitch + (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude * shakeType))); event.setRoll((float) (roll + (shakeTime * Math.sin(0.5 * Math.PI * shakeTime) * shakeAmplitude * shakeRadiusAmplitude))); } } } public static void droneBodyAngle(float RotX, float RotZ) { LocalPlayer player = Minecraft.getInstance().player; if (player != null) { droneRotX = RotX; droneRotZ = RotZ; } } private static void handleDroneCamera(ViewportEvent.ComputeCameraAngles event, LivingEntity entity) { ItemStack stack = entity.getMainHandItem(); double pitch = event.getPitch(); double roll = event.getRoll(); DroneEntity drone = EntityFindUtil.findDrone(entity.level(), stack.getOrCreateTag().getString("LinkedDrone")); if (drone != null) { event.setPitch((float) (pitch - Mth.RAD_TO_DEG * droneRotZ)); event.setRoll((float) (roll - Mth.RAD_TO_DEG * droneRotX)); } if (drone != null && stack.getOrCreateTag().getBoolean("Using")) { if (Minecraft.getInstance().gameRenderer.currentEffect() == null) { Minecraft.getInstance().gameRenderer.loadEffect(ModUtils.loc("shaders/post/scan_pincushion.json")); } } } @SubscribeEvent public static void onRenderHand(RenderHandEvent event) { Player player = Minecraft.getInstance().player; if (player == null) return; InteractionHand leftHand = Minecraft.getInstance().options.mainHand().get() == HumanoidArm.RIGHT ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; InteractionHand rightHand = Minecraft.getInstance().options.mainHand().get() == HumanoidArm.RIGHT ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND; ItemStack rightHandItem = player.getItemInHand(rightHand); if (event.getHand() == leftHand) { if (rightHandItem.is(ModTags.Items.GUN)) { event.setCanceled(true); } } if (event.getHand() == rightHand) { if (rightHandItem.is(ModTags.Items.GUN) && drawTime > 0.15) { event.setCanceled(true); } } ItemStack stack = player.getMainHandItem(); if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked")) { if (EntityFindUtil.findDrone(player.level(), stack.getOrCreateTag().getString("LinkedDrone")) != null) { event.setCanceled(true); } } if (player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity) { event.setCanceled(true); } } private static void handleWeaponSway(LivingEntity entity) { if (entity.getMainHandItem().is(ModTags.Items.GUN) && entity instanceof Player player) { float times = 2 * (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); double pose; if (player.isShiftKeyDown() && player.getBbHeight() >= 1 && PlayerEventHandler.isProne(player)) { pose = 0.85; } else if (PlayerEventHandler.isProne(player)) { pose = GunsTool.getAttachmentType(player.getMainHandItem(), GunsTool.AttachmentType.GRIP) == 3 ? 0 : 0.25f; } else { pose = 1; } swayTime += 0.05 * times; swayX = pose * -0.008 * Math.sin(swayTime) * (1 - 0.95 * zoomTime); swayY = pose * 0.125 * Math.sin(swayTime - 1.585) * (1 - 0.95 * zoomTime) - 3 * moveRotZ; } } private static void handleWeaponMove(LivingEntity entity) { if (entity.getMainHandItem().is(ModTags.Items.GUN)) { float times = 3.7f * (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); double moveSpeed = (float) Mth.clamp(entity.getDeltaMovement().horizontalDistanceSqr(), 0, 0.02); double onGround; if (entity.onGround()) { if (entity.isSprinting()) { onGround = 1.35; } else { onGround = 2.0; } } else { onGround = 0.001; } if (!entity.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).edit) { if (Minecraft.getInstance().options.keyUp.isDown() && firePosTimer == 0) { moveRotZ = Mth.lerp(0.2f * times, moveRotZ, 0.14) * (1 - zoomTime); } else { moveRotZ = Mth.lerp(0.2f * times, moveRotZ, 0) * (1 - zoomTime); } } if (isMoving() && firePosTimer == 0) { if (moveYTime < 1.25) { moveYTime += 1.2 * onGround * times * moveSpeed; } else { moveYTime = 0.25; } if (moveXTime < 2) { moveXTime += 1.2 * onGround * times * moveSpeed; } else { moveXTime = 0; } movePosX = 0.2 * Math.sin(1 * Math.PI * moveXTime) * (1 - 0.95 * zoomTime); movePosY = -0.135 * Math.sin(2 * Math.PI * (moveYTime - 0.25)) * (1 - 0.95 * zoomTime); } else { moveXTime = Math.max(moveXTime - 0.5 * times, 0); moveYTime = Math.max(moveYTime - 0.5 * times, 0.25); movePosX = Mth.lerp(0.1f * times, movePosX, 0); movePosY = Mth.lerp(0.1f * times, movePosY, 0); } if (Minecraft.getInstance().options.keyRight.isDown()) { movePosHorizon = Mth.lerp(0.05f * times, movePosHorizon, 0.04) * (1 - zoomTime); } else if (Minecraft.getInstance().options.keyLeft.isDown()) { movePosHorizon = Mth.lerp(0.05f * times, movePosHorizon, -0.04) * (1 - zoomTime); } else { movePosHorizon = Mth.lerp(0.1f * times, movePosHorizon, 0); } double velocity = entity.getDeltaMovement().y() + 0.078; if (-0.8 < velocity && velocity < 0.8) { velocityY = Mth.lerp(0.5f * times, velocityY, velocity) * (1 - 0.8 * zoomTime); } } } private static void handleWeaponZoom(LivingEntity entity) { if (!(entity instanceof Player player)) return; ItemStack stack = player.getMainHandItem(); float times = 5 * Minecraft.getInstance().getDeltaFrameTime(); double weight = stack.getOrCreateTag().getDouble("weight") + stack.getOrCreateTag().getDouble("CustomWeight"); double speed = 1.5 - (0.07 * weight); if (zoom && !notInGame() && drawTime < 0.01 && !player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).edit) { if (Minecraft.getInstance().player != null) { Minecraft.getInstance().player.getPersistentData().putDouble("noRun", 5); } if (cantFireTime <= 10) { zoomTime = Mth.clamp(zoomTime + 0.03 * speed * times, 0, 1); } } else { zoomTime = Mth.clamp(zoomTime - 0.04 * speed * times, 0, 1); } zoomPos = 0.5 * Math.cos(Math.PI * Math.pow(Math.pow(zoomTime, 2) - 1, 2)) + 0.5; zoomPosZ = -Math.pow(2 * zoomTime - 1, 2) + 1; } private static void handleWeaponFire(ViewportEvent.ComputeCameraAngles event, LivingEntity entity) { float times = 2f * Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.48f); float yaw = event.getYaw(); float pitch = event.getPitch(); float roll = event.getRoll(); ItemStack stack = entity.getMainHandItem(); double amplitude = 15000 * stack.getOrCreateTag().getDouble("recoil_y") * stack.getOrCreateTag().getDouble("recoil_x"); if (fireRecoilTime > 0) { firePosTimer = 0.001; fireRotTimer = 0.001; fireRecoilTime -= 7 * times; fireSpread += 0.1 * times; firePosZ += (0.8 * firePosZ + 0.25) * (4 * Math.random() + 0.85) * times; recoilTime = 0.01; } fireSpread = Mth.clamp(fireSpread - 0.1 * (Math.pow(fireSpread, 2) * times), 0, 2); firePosZ = Mth.clamp(firePosZ - 1.2 * (Math.pow(firePosZ, 2) * times), 0, 1.5); if (0 < firePosTimer) { firePosTimer += 0.35 * (1.1 - firePosTimer) * times; } if (0 < firePosTimer && firePosTimer < 0.454) { firePos = (-18.34) * Math.pow(firePosTimer, 2) + 8.58 * firePosTimer; } if (0.454 <= firePosTimer && firePosTimer < 1) { firePos = 4.34 * Math.pow(firePosTimer, 2) - 6.5 * firePosTimer + 2.167; } if (0 < fireRotTimer && fireRotTimer < 1.732) { fireRotTimer += 0.18 * (1.9 - fireRotTimer) * times; } double rpm = 1; if (entity.getMainHandItem().is(ModItems.MINIGUN.get())) { rpm = (double) entity.getMainHandItem().getOrCreateTag().getInt("rpm") / 1800; } float[] shake = {0, 0}; shake[0] = (float) (1.3 * amplitude * (1 / 6.3 * (fireRotTimer - 0.5)) * Math.sin(6.3 * (fireRotTimer - 0.5)) * (3 - Math.pow(fireRotTimer, 2)) + 1 * Mth.clamp(0.3 - fireRotTimer, 0, 1) * (2 * Math.random() - 1)); shake[1] = (float) (4.2 * amplitude * (1 / 6.3 * (fireRotTimer - 0.5)) * Math.sin(6.3 * (fireRotTimer - 0.5)) * (3 - Math.pow(fireRotTimer, 2)) + 3 * Mth.clamp(0.5 - fireRotTimer, 0, 0.5) * (2 * Math.random() - 1)); if (0 < fireRotTimer && fireRotTimer < 1.732) { fireRot = 1 / 6.3 * (fireRotTimer - 0.5) * Math.sin(6.3 * (fireRotTimer - 0.5)) * (3 - Math.pow(fireRotTimer, 2)); if (recoilY > 0) { event.setYaw((float) (yaw - shake[0] * rpm)); event.setPitch((float) (pitch + shake[0] * rpm)); event.setRoll((float) (roll + shake[1] * rpm)); } else if (recoilY <= 0) { event.setYaw((float) (yaw + shake[0] * rpm)); event.setPitch((float) (pitch - shake[0] * rpm)); event.setRoll((float) (roll - shake[1] * rpm)); } } if (firePosTimer >= 1) { firePosTimer = 0; } if (fireRotTimer >= 1.732) { fireRotTimer = 0; fireRot = 0; } } private static void handleWeaponShell() { Player player = Minecraft.getInstance().player; if (player == null) return; float times = (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); if (shellIndex >= 5) { shellIndex = 0; shellIndexTime[0] = 0.001; } for (int i = 0; i < 5; i++) { if (shellIndexTime[i] > 0) { shellIndexTime[i] = Math.min(shellIndexTime[i] + 8 * times, 50); } if (shellIndexTime[i] == 50) { shellIndexTime[i] = 0; } } } private static void handleGunRecoil() { Player player = Minecraft.getInstance().player; if (player == null) return; if (!player.getMainHandItem().is(ModTags.Items.GUN)) return; CompoundTag tag = player.getMainHandItem().getOrCreateTag(); float times = (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 1.6); int barrelType = GunsTool.getAttachmentType(player.getMainHandItem(), GunsTool.AttachmentType.BARREL); int gripType = GunsTool.getAttachmentType(player.getMainHandItem(), GunsTool.AttachmentType.GRIP); double recoil = switch (barrelType) { case 1 -> 1.5; case 2 -> 2.2; default -> 2.4; }; double gripRecoilX = switch (gripType) { case 1 -> 1.25; case 2 -> 0.25; default -> 1.5; }; double gripRecoilY = switch (gripType) { case 1 -> 0.7; case 2 -> 1.75; default -> 2.0; }; if (!player.getMainHandItem().is(ModTags.Items.CAN_CUSTOM_GUN)) { recoil = 1.6; gripRecoilX = 0.75; gripRecoilY = 1.25; } double cusWeight = player.getMainHandItem().getOrCreateTag().getDouble("CustomWeight"); double rpm = 1; if (player.getMainHandItem().is(ModItems.MINIGUN.get())) { rpm = (double) player.getMainHandItem().getOrCreateTag().getInt("rpm") / 1800; } float gunRecoilX = (float) tag.getDouble("recoil_x") * 60; recoilHorizon = Mth.lerp(0.2 * times, recoilHorizon, 0) + recoilY; recoilY = 0; // 计算后坐力 float pose = 1; if (player.isShiftKeyDown() && player.getBbHeight() >= 1 && !PlayerEventHandler.isProne(player)) { pose = 0.7f; } else if (PlayerEventHandler.isProne(player)) { if (GunsTool.getAttachmentType(player.getMainHandItem(), GunsTool.AttachmentType.GRIP) == 3) { pose = 0.1f; } else { pose = 0.5f; } } // 水平后座 float newYaw = player.getYRot() - (float) (0.6 * recoilHorizon * pose * times * (0.5 + fireSpread) * recoil * (1 - 0.06 * cusWeight) * gripRecoilX * rpm); player.setYRot(newYaw); player.yRotO = player.getYRot(); double sinRes = 0; // 竖直后座 if (0 < recoilTime && recoilTime < 0.5) { float newPitch = (float) (player.getXRot() - 0.02f * gunRecoilX * times * recoil * (1 - 0.06 * cusWeight) * gripRecoilY * rpm); player.setXRot(newPitch); player.xRotO = player.getXRot(); } if (0 < recoilTime && recoilTime < 2) { recoilTime = recoilTime + 0.3 * times; sinRes = Math.sin(Math.PI * recoilTime); } if (2 <= recoilTime && recoilTime < 2.5) { recoilTime = recoilTime + 0.17 * times; sinRes = 0.4 * Math.sin(2 * Math.PI * recoilTime); } if (0 < recoilTime && recoilTime < 2.5) { float newPitch = player.getXRot() - (float) (1.5 * pose * gunRecoilX * (sinRes + Mth.clamp(0.5 - recoilTime, 0, 0.5)) * times * (0.5 + fireSpread) * recoil * (1 - 0.06 * cusWeight) * gripRecoilY * rpm); player.setXRot(newPitch); player.xRotO = player.getXRot(); } if (recoilTime >= 2.5) recoilTime = 0; } private static void handlePlayerBreath(LivingEntity entity) { float times = (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); boolean breath = (entity.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables())).breath; breathTime = Mth.lerp(0.2f * times, breathTime, breath ? 1 : 0); } private static void handleShockCamera(ViewportEvent.ComputeCameraAngles event, LivingEntity entity) { if (entity.hasEffect(ModMobEffects.SHOCK.get()) && Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) { event.setYaw(Minecraft.getInstance().gameRenderer.getMainCamera().getYRot() + (float) Mth.nextDouble(RandomSource.create(), -3, 3)); event.setPitch(Minecraft.getInstance().gameRenderer.getMainCamera().getXRot() + (float) Mth.nextDouble(RandomSource.create(), -3, 3)); event.setRoll((float) Mth.nextDouble(RandomSource.create(), 8, 12)); } } public static void shake(double boneRotX, double boneRotY, double boneRotZ) { LocalPlayer player = Minecraft.getInstance().player; if (player != null) { cameraRot[0] = -boneRotX; cameraRot[1] = -boneRotY; cameraRot[2] = -boneRotZ; } } private static void handlePlayerCamera(ViewportEvent.ComputeCameraAngles event) { double yaw = event.getYaw(); double pitch = event.getPitch(); double roll = event.getRoll(); float times = (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); LocalPlayer player = Minecraft.getInstance().player; if (GLFW.glfwGetKey(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_RIGHT) == GLFW.GLFW_PRESS) { cameraLocation = Mth.clamp(cameraLocation - 0.05 * Minecraft.getInstance().getDeltaFrameTime(), -0.6, 0.6); } if (GLFW.glfwGetKey(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_LEFT) == GLFW.GLFW_PRESS) { cameraLocation = Mth.clamp(cameraLocation + 0.05 * Minecraft.getInstance().getDeltaFrameTime(), -0.6, 0.6); } if (player == null) return; double range; Entity lookingEntity = SeekTool.seekEntity(player, player.level(), 520, 5); if (lookingEntity != null) { range = Math.max(player.distanceTo(lookingEntity), 0.01); } else { range = Math.max(player.position().distanceTo((Vec3.atLowerCornerOf(player.level().clip( new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getLookAngle().scale(520)), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos()))), 0.01); } lookDistance = Mth.lerp(0.2f * times, lookDistance, range); double angle = 0; if (lookDistance != 0 && cameraLocation != 0) { angle = Math.atan(Mth.abs((float) cameraLocation) / (lookDistance + 2.9)) * Mth.RAD_TO_DEG; } if (player.getMainHandItem().is(ModTags.Items.GUN)) { event.setPitch((float) (pitch + cameraRot[0] + (DisplayConfig.CAMERA_ROTATE.get() ? 0.2 : 0) * turnRot[0] + 3 * velocityY)); if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK) { event.setYaw((float) (yaw + cameraRot[1] + (DisplayConfig.CAMERA_ROTATE.get() ? 0.8 : 0) * turnRot[1] - (cameraLocation > 0 ? 1 : -1) * angle * zoomPos)); } else { event.setYaw((float) (yaw + cameraRot[1] + (DisplayConfig.CAMERA_ROTATE.get() ? 0.8 : 0) * turnRot[1])); } event.setRoll((float) (roll + cameraRot[2] + (DisplayConfig.CAMERA_ROTATE.get() ? 0.35 : 0) * turnRot[2])); } } private static void handleBowPullAnimation(LivingEntity entity) { float times = 4 * (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 0.8); if ((entity.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables())).bowPull) { pullTimer = Math.min(pullTimer + 0.024 * times, 1.4); bowTimer = Math.min(bowTimer + 0.018 * times, 1); handTimer = Math.min(handTimer + 0.018 * times, 1); handPos = 0.5 * Math.cos(Math.PI * Math.pow(Math.pow(handTimer, 2) - 1, 2)) + 0.5; } else { pullTimer = Math.max(pullTimer - 0.015 * times, 0); bowTimer = Math.max(bowTimer - 1 * times, 0); handTimer = Math.max(handTimer - 0.04 * times, 0); if (handTimer > 0 && handTimer < 0.5) { handPos = 0.5 * Math.cos(Math.PI * Math.pow(Math.pow(handTimer, 2) - 1, 2)) + 0.5; } } pullPos = 0.5 * Math.cos(Math.PI * Math.pow(Math.pow(Mth.clamp(pullTimer, 0, 1), 2) - 1, 2)) + 0.5; bowPos = 0.5 * Math.cos(Math.PI * Math.pow(Math.pow(bowTimer, 2) - 1, 2)) + 0.5; } @SubscribeEvent public static void onFovUpdate(ViewportEvent.ComputeFov event) { Minecraft mc = Minecraft.getInstance(); float times = (float) Math.min(Minecraft.getInstance().getDeltaFrameTime(), 1.6); Player player = mc.player; if (player == null) { return; } ItemStack stack = player.getMainHandItem(); if (player.isPassenger() && player.getVehicle() instanceof ICannonEntity && zoom) { event.setFOV(event.getFOV() / 5); return; } if (stack.is(ModTags.Items.GUN)) { if (!event.usedConfiguredFov()) { return; } double p; if (stack.is(ModItems.BOCEK.get())) { p = (pullPos + 0.25) * zoomTime; } else { p = zoomPos; } customZoom = Mth.lerp(0.6 * times, customZoom, stack.getOrCreateTag().getDouble("CustomZoom")); double zoomFov = 1.25 + customZoom; if (mc.options.getCameraType().isFirstPerson()) { event.setFOV(event.getFOV() / (1.0 + p * (zoomFov - 1)) * (1 - 0.4 * breathTime)); } else if (mc.options.getCameraType() == CameraType.THIRD_PERSON_BACK) event.setFOV(event.getFOV() / (1.0 + p * 0.01) * (1 - 0.4 * breathTime)); fov = event.getFOV(); if (zoom && !notInGame() && drawTime < 0.01 && !player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables()).edit) { int level = PerkHelper.getItemPerkLevel(ModPerks.INTELLIGENT_CHIP.get(), stack); if (level > 0) { Entity seekingEntity = SeekTool.seekLivingEntity(player, player.level(), 32 + 8 * (level - 1), 25 / zoomFov); if (seekingEntity != null && seekingEntity.isAlive()) { player.lookAt(EntityAnchorArgument.Anchor.EYES, seekingEntity.getEyePosition()); } } } return; } if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked")) { droneFovLerp = Mth.lerp(0.1 * Minecraft.getInstance().getDeltaFrameTime(), droneFovLerp, droneFov); event.setFOV(event.getFOV() / droneFovLerp); } } @SubscribeEvent public static void setPlayerInvisible(RenderPlayerEvent.Pre event) { var otherPlayer = event.getEntity(); if (otherPlayer.getVehicle() instanceof ICannonEntity) { event.setCanceled(true); } } @SubscribeEvent public static void handleRenderCrossHair(RenderGuiOverlayEvent.Pre event) { if (event.getOverlay() != VanillaGuiOverlay.CROSSHAIR.type()) { return; } Minecraft mc = Minecraft.getInstance(); if (mc.player == null) { return; } if (!mc.options.getCameraType().isFirstPerson()) { return; } if (mc.player.getMainHandItem().is(ModTags.Items.GUN) || (mc.player.getVehicle() != null && mc.player.getVehicle() instanceof ICannonEntity)) { event.setCanceled(true); } ItemStack stack = mc.player.getMainHandItem(); if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked")) { event.setCanceled(true); } } public static void handleDrawMessage(boolean draw, Supplier ctx) { if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { drawTime = 1; for (int i = 0; i < 5; i++) { shellIndexTime[i] = 0; } zoom = false; holdFire = false; ClickHandler.switchZoom = false; } } private static void handleWeaponDraw(LivingEntity entity) { float times = Minecraft.getInstance().getDeltaFrameTime(); ItemStack stack = entity.getMainHandItem(); double weight = stack.getOrCreateTag().getDouble("weight") + stack.getOrCreateTag().getDouble("CustomWeight"); double speed = 3.2 - (0.13 * weight); drawTime = Math.max(drawTime - Math.max(0.2 * speed * times * drawTime, 0.0008), 0); } public static void handleShells(float x, float y, CoreGeoBone... shells) { for (int i = 0; i < shells.length; i++) { if (i >= 5) break; shells[i].setPosX((float) (-x * shellIndexTime[i] * ((150 - shellIndexTime[i]) / 150))); shells[i].setPosY((float) (y * randomShell[0] * shellIndexTime[i] - 0.025 * Math.pow(shellIndexTime[i], 2))); shells[i].setRotX((float) (randomShell[1] * shellIndexTime[i])); shells[i].setRotY((float) (randomShell[2] * shellIndexTime[i])); } } }