Skip to content

Commit

Permalink
feat(ElytraFly): fixes and options (#5178)
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
ccetl authored Jan 4, 2025
1 parent 0968c1d commit fd38e95
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 195 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}

}
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<ElytraFlyMode>
get() = ModuleElytraFly.modes

open fun onTick() {}

}
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<PlayerMoveEvent> { 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
}
}

}
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/
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
}
}

}

This file was deleted.

Loading

0 comments on commit fd38e95

Please sign in to comment.