Skip to content

Commit 79c6347

Browse files
authored
feat: Auto Wind Charge (#6770)
1 parent a5a4b11 commit 79c6347

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

src/main/kotlin/net/ccbluex/liquidbounce/features/module/ModuleManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ object ModuleManager : EventListener, Iterable<ClientModule> by modules {
325325
ModuleAutoBreak,
326326
ModuleAutoFish,
327327
ModuleAutoRespawn,
328+
ModuleAutoWindCharge,
328329
ModuleOffhand,
329330
ModuleAutoShop,
330331
ModuleAutoWalk,
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
3+
*
4+
* Copyright (c) 2015 - 2025 CCBlueX
5+
*
6+
* LiquidBounce is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* LiquidBounce is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package net.ccbluex.liquidbounce.features.module.modules.player
20+
21+
import net.ccbluex.liquidbounce.config.types.nesting.ToggleableConfigurable
22+
import net.ccbluex.liquidbounce.event.tickHandler
23+
import net.ccbluex.liquidbounce.features.module.Category
24+
import net.ccbluex.liquidbounce.features.module.ClientModule
25+
import net.ccbluex.liquidbounce.features.module.modules.player.ModuleAutoWindCharge.Rotate.rotations
26+
import net.ccbluex.liquidbounce.utils.aiming.RotationManager
27+
import net.ccbluex.liquidbounce.utils.aiming.RotationsConfigurable
28+
import net.ccbluex.liquidbounce.utils.aiming.data.Rotation
29+
import net.ccbluex.liquidbounce.utils.combat.CombatManager
30+
import net.ccbluex.liquidbounce.utils.entity.FallingPlayer
31+
import net.ccbluex.liquidbounce.utils.entity.getMovementDirectionOfInput
32+
import net.ccbluex.liquidbounce.utils.input.isPressed
33+
import net.ccbluex.liquidbounce.utils.inventory.Slots
34+
import net.ccbluex.liquidbounce.utils.inventory.useHotbarSlotOrOffhand
35+
import net.ccbluex.liquidbounce.utils.kotlin.Priority
36+
import net.ccbluex.liquidbounce.utils.movement.DirectionalInput
37+
import net.minecraft.client.util.InputUtil
38+
import net.minecraft.item.Items
39+
40+
/**
41+
* Uses wind charges to boost yourself up when holding jump.
42+
*/
43+
object ModuleAutoWindCharge : ClientModule("AutoWindCharge", Category.PLAYER) {
44+
45+
private object Rotate : ToggleableConfigurable(this, "Rotate", true) {
46+
val rotations = tree(RotationsConfigurable(this))
47+
}
48+
49+
private object HorizontalBoost : ToggleableConfigurable(this, "HorizontalBoost", true) {
50+
val pitch by float("Pitch", 70f, 0f..90f)
51+
val boostKey by key("Key", InputUtil.GLFW_KEY_LEFT_CONTROL)
52+
}
53+
54+
init {
55+
treeAll(HorizontalBoost, Rotate)
56+
}
57+
58+
private val combatPauseTime by int("CombatPauseTime", 0, 0..40, "ticks")
59+
private val slotResetDelay by intRange("SlotResetDelay", 0..0, 0..40, "ticks")
60+
61+
/**
62+
* 7 ticks is the perfect time to use a wind charge before hitting the ground,
63+
* and drastically boosts us higher.
64+
*/
65+
const val PREDICTION_TICKS = 7
66+
67+
@Suppress("unused")
68+
private val autoWindChargeHandler = tickHandler {
69+
if (player.isGliding || player.isSwimming || player.isInFluid || !mc.options.jumpKey.isPressed) {
70+
return@tickHandler
71+
}
72+
73+
val collision = FallingPlayer
74+
.fromPlayer(player)
75+
.findCollision(PREDICTION_TICKS) ?: return@tickHandler
76+
77+
val itemSlot = Slots.OffhandWithHotbar.findSlot(Items.WIND_CHARGE) ?: return@tickHandler
78+
79+
val isHorizontalBoost = HorizontalBoost.enabled && HorizontalBoost.boostKey.isPressed
80+
val directionYaw = getMovementDirectionOfInput(player.yaw,
81+
DirectionalInput(player.input)) - 180f
82+
val directionPitch = when {
83+
isHorizontalBoost -> HorizontalBoost.pitch
84+
else -> 90f
85+
}
86+
87+
var rotation = Rotation(directionYaw, 80f)
88+
89+
if (Rotate.enabled) {
90+
fun isRotationSufficient(): Boolean {
91+
return RotationManager.serverRotation.angleTo(rotation) <= 1.0f
92+
}
93+
94+
waitConditional(20) {
95+
CombatManager.pauseCombatForAtLeast(combatPauseTime)
96+
RotationManager.setRotationTarget(
97+
rotations.toRotationTarget(rotation),
98+
Priority.IMPORTANT_FOR_USAGE_3,
99+
this@ModuleAutoWindCharge
100+
)
101+
102+
isRotationSufficient()
103+
}
104+
105+
if (!isRotationSufficient()) {
106+
return@tickHandler
107+
}
108+
}
109+
110+
val (yaw, pitch) = rotation.normalize()
111+
useHotbarSlotOrOffhand(itemSlot, slotResetDelay.random(), yaw, pitch)
112+
}
113+
114+
}

src/main/resources/resources/liquidbounce/lang/en_us.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,5 +730,6 @@
730730
"liquidbounce.module.noEntityInteract.description": "Prevents you from interacting with entities.",
731731
"liquidbounce.module.autoPearl.description": "Aims and throws a pearl at an enemies pearl trajectory.",
732732
"liquidbounce.module.replenish.description": "Automatically refills your hotbar with items from your inventory when the count drops to a certain threshold.",
733-
"liquidbounce.module.anchor.description": "Pulls you into safe holes for crystal PvP."
733+
"liquidbounce.module.anchor.description": "Pulls you into safe holes for crystal PvP.",
734+
"liquidbounce.module.autoWindCharge.description": "Automatically boosts you using wind charges when holding jump."
734735
}

0 commit comments

Comments
 (0)