-
-
Notifications
You must be signed in to change notification settings - Fork 535
Add ElytraFly Boost mode #6172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: nextgen
Are you sure you want to change the base?
Add ElytraFly Boost mode #6172
Changes from 5 commits
3435210
366c3a3
ac1e5e1
46a8fc6
64a0238
2f63ee7
fd10a00
af53234
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,218 @@ | ||||||||||
/* | ||||||||||
* 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.withStrafe | ||||||||||
import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention | ||||||||||
import net.ccbluex.liquidbounce.utils.math.withY | ||||||||||
import net.minecraft.entity.effect.StatusEffects | ||||||||||
import net.minecraft.util.math.Vec3d | ||||||||||
import kotlin.math.abs | ||||||||||
import kotlin.math.max | ||||||||||
import kotlin.math.min | ||||||||||
|
||||||||||
/** | ||||||||||
* ElytraFly boost mode | ||||||||||
* | ||||||||||
* Allows to fly with elytra without fireworks by simulating natural flight mechanics | ||||||||||
*/ | ||||||||||
internal object ElytraFlyModeBoost : ElytraFlyMode("Boost") { | ||||||||||
|
||||||||||
private val boostSpeed by float("Speed", 0.9f, 0.5f..2.0f) | ||||||||||
private val acceleration by float("Acceleration", 0.01f, 0.005f..0.05f) | ||||||||||
private val autoBoost by boolean("AutoBoost", true) | ||||||||||
private val diveMechanics by boolean("DiveMechanics", true) | ||||||||||
private val smartGround by boolean("SmartGroundBehavior", true) | ||||||||||
private val groundDistance by float("GroundDistance", 3.0f, 1.5f..7.0f) | ||||||||||
private val verticalControl by float("VerticalControl", 0.8f, 0.2f..1.0f) | ||||||||||
|
||||||||||
private var currentAcceleration = 0.0f | ||||||||||
private var currentDiveSpeed = 0.0f | ||||||||||
|
||||||||||
private val diveAcceleration by float("DiveAcceleration", 0.05f, 0.01f..0.1f) | ||||||||||
private val diveEfficiency by float("DiveEfficiency", 0.8f, 0.4f..1.5f) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. other variables settings should be above other variables |
||||||||||
|
||||||||||
override fun enable() { | ||||||||||
resetState() | ||||||||||
} | ||||||||||
|
||||||||||
override fun disable() { | ||||||||||
resetState() | ||||||||||
} | ||||||||||
|
||||||||||
private fun resetState() { | ||||||||||
currentAcceleration = 0.0f | ||||||||||
currentDiveSpeed = 0.0f | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
} | ||||||||||
|
||||||||||
private fun isNearGround(): Boolean = | ||||||||||
smartGround && world.getBlockCollisions( | ||||||||||
player, | ||||||||||
player.boundingBox.offset(0.0, -groundDistance.toDouble(), 0.0) | ||||||||||
).iterator().hasNext() | ||||||||||
|
||||||||||
override fun onTick() { | ||||||||||
if (!player.isGliding) { | ||||||||||
resetState() | ||||||||||
return | ||||||||||
} | ||||||||||
|
||||||||||
val isNearGround = isNearGround() | ||||||||||
val divePullUpBoost = handleDiving() | ||||||||||
|
||||||||||
val shouldBoost = mc.options.jumpKey.isPressed || | ||||||||||
(autoBoost && player.pitch < -10f && !isNearGround) || | ||||||||||
divePullUpBoost > 0 | ||||||||||
|
||||||||||
handleAcceleration(shouldBoost) | ||||||||||
|
||||||||||
if (player.moving) { | ||||||||||
player.velocity = player.velocity.withStrafe( | ||||||||||
speed = calculateEffectiveSpeed(isNearGround) | ||||||||||
) | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
private fun handleDiving(): Float { | ||||||||||
if (!diveMechanics) { | ||||||||||
currentDiveSpeed = max(0f, currentDiveSpeed - 0.01f) | ||||||||||
return 0f | ||||||||||
} | ||||||||||
|
||||||||||
val oldDiveSpeed = currentDiveSpeed | ||||||||||
|
||||||||||
if (player.pitch > 15f) { | ||||||||||
val diveFactor = min(player.pitch / 90f, 1f) | ||||||||||
currentDiveSpeed = min( | ||||||||||
currentDiveSpeed + diveAcceleration * diveFactor, | ||||||||||
1.2f // Maximum dive speed multiplier | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use constants |
||||||||||
) | ||||||||||
return 0f | ||||||||||
} else { | ||||||||||
currentDiveSpeed = max(0f, currentDiveSpeed - 0.01f) | ||||||||||
|
||||||||||
if (player.pitch < 0 && oldDiveSpeed > 0) { | ||||||||||
return oldDiveSpeed * (-player.pitch / 90f) * diveEfficiency | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
return 0f | ||||||||||
} | ||||||||||
|
||||||||||
private fun handleAcceleration(shouldBoost: Boolean) { | ||||||||||
if (shouldBoost && currentAcceleration < boostSpeed) { | ||||||||||
val accelerationFactor = 1f - currentAcceleration / boostSpeed | ||||||||||
currentAcceleration += acceleration * accelerationFactor | ||||||||||
currentAcceleration = min(currentAcceleration, boostSpeed) | ||||||||||
} else if (!shouldBoost && currentAcceleration > 0) { | ||||||||||
currentAcceleration *= 0.98f - acceleration | ||||||||||
if (currentAcceleration < 0.01f) { | ||||||||||
currentAcceleration = 0f | ||||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
private fun calculateEffectiveSpeed(isNearGround: Boolean): Double { | ||||||||||
val baseSpeed = ModuleElytraFly.Speed.horizontal.toDouble() | ||||||||||
var finalModifier = 1.0 | ||||||||||
|
||||||||||
// Apply pitch-based reduction | ||||||||||
if (player.pitch < 0) { | ||||||||||
finalModifier *= 1.0 - (abs(player.pitch / 90.0) * 0.3) | ||||||||||
} | ||||||||||
|
||||||||||
// Apply dive speed boost | ||||||||||
if (currentDiveSpeed > 0) { | ||||||||||
finalModifier *= 1.0 + currentDiveSpeed | ||||||||||
} | ||||||||||
|
||||||||||
// Apply ground proximity penalty | ||||||||||
if (isNearGround) { | ||||||||||
finalModifier *= 0.8 | ||||||||||
} | ||||||||||
|
||||||||||
// Apply speed potion effect | ||||||||||
player.getStatusEffect(StatusEffects.SPEED)?.let { effect -> | ||||||||||
finalModifier *= 1.0 + (effect.amplifier + 1) * 0.1 | ||||||||||
} | ||||||||||
|
||||||||||
return baseSpeed * finalModifier | ||||||||||
} | ||||||||||
|
||||||||||
private fun calculateDivePullUpBoost(): Double { | ||||||||||
return if (player.pitch < 0 && currentDiveSpeed > 0) { | ||||||||||
(-player.pitch / 90f) * diveEfficiency * currentDiveSpeed * 0.1 | ||||||||||
} else { | ||||||||||
0.0 | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
@Suppress("unused") | ||||||||||
private val moveHandler = handler<PlayerMoveEvent>(priority = EventPriorityConvention.MODEL_STATE) { event -> | ||||||||||
if (ModuleElytraFly.shouldNotOperate() || !player.isGliding) { | ||||||||||
return@handler | ||||||||||
} | ||||||||||
|
||||||||||
val divePullUpBoost = calculateDivePullUpBoost() | ||||||||||
val nearGround = isNearGround() | ||||||||||
|
||||||||||
if (currentAcceleration > 0 || currentDiveSpeed > 0) { | ||||||||||
val lookVec = player.getRotationVector() | ||||||||||
|
||||||||||
val boostFactor = currentAcceleration.toDouble() + | ||||||||||
(if (player.pitch > 0) currentDiveSpeed.toDouble() else divePullUpBoost * 2.0) | ||||||||||
|
||||||||||
val adjustedLookVec = if (nearGround) { | ||||||||||
Vec3d(lookVec.x * 1.3, lookVec.y * 0.3, lookVec.z * 1.3).normalize() | ||||||||||
} else { | ||||||||||
lookVec | ||||||||||
} | ||||||||||
|
||||||||||
val boostVec = adjustedLookVec.multiply(boostFactor) | ||||||||||
event.movement = event.movement.add(boostVec) | ||||||||||
} | ||||||||||
|
||||||||||
val horizontalSpeed = Math.sqrt( | ||||||||||
event.movement.x * event.movement.x + event.movement.z * event.movement.z | ||||||||||
) | ||||||||||
|
||||||||||
val naturalLift = horizontalSpeed * 0.005 | ||||||||||
|
||||||||||
event.movement = when { | ||||||||||
mc.options.jumpKey.isPressed && mc.options.sneakKey.isPressed -> { | ||||||||||
event.movement.withY(event.movement.y - 0.008 + naturalLift + divePullUpBoost) | ||||||||||
} | ||||||||||
mc.options.jumpKey.isPressed -> { | ||||||||||
val upSpeed = (ModuleElytraFly.Speed.vertical.toDouble() * verticalControl) + divePullUpBoost | ||||||||||
event.movement.withY(event.movement.y + upSpeed) | ||||||||||
} | ||||||||||
mc.options.sneakKey.isPressed -> { | ||||||||||
val downSpeed = ModuleElytraFly.Speed.vertical.toDouble() * verticalControl | ||||||||||
event.movement.withY(event.movement.y - downSpeed) | ||||||||||
} | ||||||||||
else -> { | ||||||||||
event.movement.withY(event.movement.y - 0.008 + naturalLift + divePullUpBoost) | ||||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -141,3 +141,5 @@ fun Vec3d.preferOver(other: Vec3d): Vec3d { | |
val z = if (this.z == 0.0) other.z else this.z | ||
return Vec3d(x, y, z) | ||
} | ||
|
||
fun Vec3d.withY(y: Double): Vec3d = Vec3d(this.x, y, this.z) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I should have studied the code more closely. I probably missed something. |
Uh oh!
There was an error while loading. Please reload this page.