From fd38e9511895aa81a808d5d024197865d239a76c Mon Sep 17 00:00:00 2001
From: ccetl <109693935+ccetl@users.noreply.github.com>
Date: Sat, 4 Jan 2025 17:02:11 +0100
Subject: [PATCH] feat(ElytraFly): fixes and options (#5178)
- moved common code to the module
- instant start now works as expected
- instant stop now works as expected
- added a not in fluid option that will stop the flight when you're in fluids
- static now stops all your movement when you don't press any movement key
- added an option to completely remove durability usage while elytra flying
---
.../movement/elytrafly/ModuleElytraFly.kt | 97 ++++++++++++++++--
.../movement/elytrafly/modes/ElytraFlyMode.kt | 32 ++++++
.../elytrafly/modes/ElytraFlyModeStatic.kt | 50 ++++++++++
.../elytrafly/modes/ElytraFlyModeVanilla.kt | 39 ++++++++
.../movement/elytrafly/modes/ElytraStatic.kt | 98 -------------------
.../movement/elytrafly/modes/ElytraVanilla.kt | 87 ----------------
6 files changed, 208 insertions(+), 195 deletions(-)
create mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyMode.kt
create mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeStatic.kt
create mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeVanilla.kt
delete mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraStatic.kt
delete mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraVanilla.kt
diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/ModuleElytraFly.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/ModuleElytraFly.kt
index 75efcb8ae40..5f82d02b8ec 100644
--- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/ModuleElytraFly.kt
+++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/ModuleElytraFly.kt
@@ -19,32 +19,109 @@
package net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly
import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable
+import net.ccbluex.liquidbounce.event.tickHandler
import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.ClientModule
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes.ElytraStatic
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes.ElytraVanilla
+import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes.ElytraFlyModeStatic
+import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes.ElytraFlyModeVanilla
+import net.ccbluex.liquidbounce.utils.entity.set
+import net.minecraft.entity.EquipmentSlot
+import net.minecraft.entity.effect.StatusEffects
+import net.minecraft.item.Items
+import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket
/**
* ElytraFly module
*
- * Makes you fly faster on Elytra.
+ * Makes elytra flying easier to control.
*/
-
object ModuleElytraFly : ClientModule("ElytraFly", Category.MOVEMENT) {
- val instant by boolean("Instant", true)
- val instantStop by boolean("InstantStop", false)
+ private val instantStart by boolean("InstantStart", false)
+ private val instantStop by boolean("InstantStop", true)
+
object Speed : ToggleableConfigurable(this, "Speed", true) {
val vertical by float("Vertical", 0.5f, 0.1f..2f)
- val horizontal by float("Horizontal", 1f, 0.1f..2f)
+ val horizontal by float("Horizontal", 1f, 0.1f..5f)
}
init {
tree(Speed)
}
- internal val modes = choices("Mode", ElytraVanilla, arrayOf(
- ElytraStatic,
- ElytraVanilla
+ private val notInFluid by boolean("NotInFluid", false)
+
+ /**
+ * Spams elytra starting so that we switch between falling and gliding all the time and so don't use any elytra
+ * durability.
+ */
+ private val durabilityExploit by boolean("DurabilityExploit", false)
+
+ internal val modes = choices("Mode", ElytraFlyModeStatic, arrayOf(
+ ElytraFlyModeStatic,
+ ElytraFlyModeVanilla
))
+
+ private var needsToRestart = false
+
+ override fun enable() {
+ needsToRestart = false
+ }
+
+ override fun disable() {
+ needsToRestart = true
+ }
+
+ // checks and start logic
+ @Suppress("unused")
+ private val tickHandler = tickHandler {
+ if (shouldNotOperate()) {
+ needsToRestart = false
+ return@tickHandler
+ }
+
+ val stop = mc.options.sneakKey.isPressed && instantStop && player.isOnGround || notInFluid && player.isInFluid
+ if (stop && player.isGliding) {
+ player.stopGliding()
+ network.sendPacket(ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.START_FALL_FLYING))
+ needsToRestart = false
+ return@tickHandler
+ }
+
+ if (player.isGliding) {
+ // we're already flying, yay
+ if (Speed.enabled) {
+ modes.activeChoice.onTick()
+ }
+
+ if (durabilityExploit) {
+ network.sendPacket(ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.START_FALL_FLYING))
+ needsToRestart = true
+ }
+ } else if (player.input.playerInput.jump && player.velocity.y != 0.0 && instantStart || needsToRestart) {
+ // If the player has an elytra and wants to fly instead
+
+ // Jump must be off due to abnormal speed boosts
+ player.input.set(jump = false)
+ player.startGliding()
+ network.sendPacket(ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.START_FALL_FLYING))
+ }
+ }
+
+ fun shouldNotOperate(): Boolean {
+ if (player.vehicle != null) {
+ return true
+ }
+
+ if (player.abilities.creativeMode || player.hasStatusEffect(StatusEffects.LEVITATION)) {
+ return true
+ }
+
+ // Find the chest slot
+ val chestSlot = player.getEquippedStack(EquipmentSlot.CHEST)
+
+ // If the player doesn't have an elytra in the chest slot or is in fluids
+ return chestSlot.item != Items.ELYTRA || chestSlot.willBreakNextUse()
+ }
+
}
diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyMode.kt
new file mode 100644
index 00000000000..bd2cdfac38b
--- /dev/null
+++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyMode.kt
@@ -0,0 +1,32 @@
+/*
+ * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
+ *
+ * Copyright (c) 2015 - 2025 CCBlueX
+ *
+ * LiquidBounce is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LiquidBounce is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LiquidBounce. If not, see .
+ */
+package net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes
+
+import net.ccbluex.liquidbounce.config.types.Choice
+import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
+import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly
+
+abstract class ElytraFlyMode(name: String) : Choice(name) {
+
+ override val parent: ChoiceConfigurable
+ get() = ModuleElytraFly.modes
+
+ open fun onTick() {}
+
+}
diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeStatic.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeStatic.kt
new file mode 100644
index 00000000000..c01a18d233e
--- /dev/null
+++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeStatic.kt
@@ -0,0 +1,50 @@
+/*
+ * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
+ *
+ * Copyright (c) 2015 - 2025 CCBlueX
+ *
+ * LiquidBounce is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LiquidBounce is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LiquidBounce. If not, see .
+ */
+package net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes
+
+import net.ccbluex.liquidbounce.event.events.PlayerMoveEvent
+import net.ccbluex.liquidbounce.event.handler
+import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly
+import net.ccbluex.liquidbounce.utils.entity.moving
+import net.ccbluex.liquidbounce.utils.entity.strafe
+
+internal object ElytraFlyModeStatic : ElytraFlyMode("Static") {
+
+ @Suppress("unused")
+ private val networkMovementTickHandler = handler { event ->
+ if (ModuleElytraFly.shouldNotOperate() || !player.isGliding) {
+ return@handler
+ }
+
+ val speed = ModuleElytraFly.Speed.enabled
+ if (speed && player.moving) {
+ event.movement.strafe(speed = ModuleElytraFly.Speed.horizontal.toDouble())
+ } else {
+ event.movement.x = 0.0
+ event.movement.z = 0.0
+ }
+
+ event.movement.y = when {
+ mc.options.jumpKey.isPressed && speed -> ModuleElytraFly.Speed.vertical.toDouble()
+ mc.options.sneakKey.isPressed && speed -> -ModuleElytraFly.Speed.vertical.toDouble()
+ else -> 0.0
+ }
+ }
+
+}
diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeVanilla.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeVanilla.kt
new file mode 100644
index 00000000000..84942de0a6a
--- /dev/null
+++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraFlyModeVanilla.kt
@@ -0,0 +1,39 @@
+/*
+ * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
+ *
+ * Copyright (c) 2015 - 2025 CCBlueX
+ *
+ * LiquidBounce is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LiquidBounce is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LiquidBounce. If not, see .
+ */
+package net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes
+
+import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly
+import net.ccbluex.liquidbounce.utils.entity.moving
+import net.ccbluex.liquidbounce.utils.entity.strafe
+
+internal object ElytraFlyModeVanilla : ElytraFlyMode("Vanilla") {
+
+ override fun onTick() {
+ if (player.moving) {
+ player.strafe(speed = ModuleElytraFly.Speed.horizontal.toDouble())
+ }
+
+ player.velocity.y = when {
+ mc.options.jumpKey.isPressed -> ModuleElytraFly.Speed.vertical.toDouble()
+ mc.options.sneakKey.isPressed -> -ModuleElytraFly.Speed.vertical.toDouble()
+ else -> return
+ }
+ }
+
+}
diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraStatic.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraStatic.kt
deleted file mode 100644
index 77bde910ac8..00000000000
--- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraStatic.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
- *
- * Copyright (c) 2015 - 2025 CCBlueX
- *
- * LiquidBounce is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * LiquidBounce is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with LiquidBounce. If not, see .
- */
-package net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes
-
-import net.ccbluex.liquidbounce.config.types.Choice
-import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
-import net.ccbluex.liquidbounce.event.tickHandler
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly.instant
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly.instantStop
-import net.ccbluex.liquidbounce.utils.entity.moving
-import net.ccbluex.liquidbounce.utils.entity.set
-import net.ccbluex.liquidbounce.utils.entity.strafe
-import net.minecraft.entity.EquipmentSlot
-import net.minecraft.item.Items
-
-internal object ElytraStatic : Choice("Static") {
- override val parent: ChoiceConfigurable<*>
- get() = ModuleElytraFly.modes
-
- val repeatable = tickHandler {
-
- if (player.vehicle != null) {
- return@tickHandler
- }
-
- // Find the chest slot
- val chestSlot = player.getEquippedStack(EquipmentSlot.CHEST)
-
- if (player.abilities.creativeMode) {
- return@tickHandler
- }
-
- // If the player doesn't have an elytra in the chest slot
- if (chestSlot.item != Items.ELYTRA) {
- return@tickHandler
- }
-
- if (mc.options.sneakKey.isPressed && instantStop) {
- player.stopGliding()
- return@tickHandler
- }
- fun isAnyMovementKeyPressed(): Boolean {
- return mc.options.forwardKey.isPressed || mc.options.backKey.isPressed
- || mc.options.leftKey.isPressed || mc.options.rightKey.isPressed
- || mc.options.jumpKey.isPressed || mc.options.sneakKey.isPressed
- }
-
- // If player is flying
- if (player.isGliding && isAnyMovementKeyPressed()) {
- if (ModuleElytraFly.Speed.enabled) {
- if (player.moving) {
- player.strafe(speed = ModuleElytraFly.Speed.horizontal.toDouble())
- }
- player.velocity.y = when {
- mc.options.jumpKey.isPressed -> ModuleElytraFly.Speed.vertical.toDouble()
- mc.options.sneakKey.isPressed -> -ModuleElytraFly.Speed.vertical.toDouble()
- else -> return@tickHandler
- }
- }
- // If the player has an elytra and wants to fly instead
- } else if (chestSlot.item == Items.ELYTRA && player.input.playerInput.jump) {
- if (instant) {
- // Jump must be off due to abnormal speed boosts
- player.input.set(
- jump = false
- )
- }
- }
-
- // If no movement key is pressed, set speed to zero
- if (!mc.options.forwardKey.isPressed && !mc.options.backKey.isPressed
- && !mc.options.leftKey.isPressed && !mc.options.rightKey.isPressed) {
- player.strafe(speed = 0.0)
- player.velocity.y = 0.0
- }
- }
-
-
-
-
-}
diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraVanilla.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraVanilla.kt
deleted file mode 100644
index 4645b79da1b..00000000000
--- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/elytrafly/modes/ElytraVanilla.kt
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
- *
- * Copyright (c) 2015 - 2025 CCBlueX
- *
- * LiquidBounce is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * LiquidBounce is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with LiquidBounce. If not, see .
- */
-package net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.modes
-
-import net.ccbluex.liquidbounce.config.types.Choice
-import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
-import net.ccbluex.liquidbounce.event.tickHandler
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly.instant
-import net.ccbluex.liquidbounce.features.module.modules.movement.elytrafly.ModuleElytraFly.instantStop
-import net.ccbluex.liquidbounce.utils.entity.moving
-import net.ccbluex.liquidbounce.utils.entity.set
-import net.ccbluex.liquidbounce.utils.entity.strafe
-import net.minecraft.entity.EquipmentSlot
-import net.minecraft.item.Items
-
-internal object ElytraVanilla : Choice("Vanilla") {
-
-
- override val parent: ChoiceConfigurable
- get() = ModuleElytraFly.modes
-
-
- val repeatable = tickHandler {
-
- if (player.vehicle != null) {
- return@tickHandler
- }
-
- // Find the chest slot
- val chestSlot = player.getEquippedStack(EquipmentSlot.CHEST)
-
- if (player.abilities.creativeMode) {
- return@tickHandler
- }
-
- // If the player doesn't have an elytra in the chest slot
- if (chestSlot.item != Items.ELYTRA) {
- return@tickHandler
- }
-
- if (mc.options.sneakKey.isPressed && instantStop) {
- player.stopGliding()
- return@tickHandler
- }
-
- // If player is flying
- if (player.isGliding) {
- if (ModuleElytraFly.Speed.enabled) {
- if (player.moving) {
- player.strafe(speed = ModuleElytraFly.Speed.horizontal.toDouble())
- }
- player.velocity.y = when {
- mc.options.jumpKey.isPressed -> ModuleElytraFly.Speed.vertical.toDouble()
- mc.options.sneakKey.isPressed -> -ModuleElytraFly.Speed.vertical.toDouble()
- else -> return@tickHandler
- }
- }
- // If the player has an elytra and wants to fly instead
- } else if (chestSlot.item == Items.ELYTRA && player.input.playerInput.jump) {
- if (instant) {
- // Jump must be off due to abnormal speed boosts
- player.input.set(
- jump = false
- )
- }
- }
- }
-
-
-}