Skip to content

Commit

Permalink
feat(TickBase): call mode (#4931)
Browse files Browse the repository at this point in the history
Call Mode:
- Game: make full game ticks to skip time
- Player: old mode which only updated the position

Future Mode: Supports early break out support e.g when KillAura is not ready anymore

Tag is now based on the selected mode
  • Loading branch information
1zun4 authored Dec 16, 2024
1 parent 9f85297 commit 25b3555
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 12 deletions.
4 changes: 3 additions & 1 deletion src/main/kotlin/net/ccbluex/liquidbounce/event/Sequence.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ open class Sequence<T : Event>(val owner: EventListener, val handler: Suspendabl

internal fun tick() {
if (++this.elapsedTicks >= this.totalTicks()) {
this.continuation?.resume(Unit)
val continuation = this.continuation ?: return
this.continuation = null
continuation.resume(Unit)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.ClientModule
import net.ccbluex.liquidbounce.features.module.modules.combat.killaura.ModuleKillAura
import net.ccbluex.liquidbounce.features.module.modules.player.ModuleBlink
import net.ccbluex.liquidbounce.features.module.modules.render.ModuleDebug
import net.ccbluex.liquidbounce.render.drawLineStrip
import net.ccbluex.liquidbounce.render.engine.Color4b
import net.ccbluex.liquidbounce.render.renderEnvironmentForWorld
Expand All @@ -46,6 +47,8 @@ import kotlin.math.min
internal object ModuleTickBase : ClientModule("TickBase", Category.COMBAT) {

private val mode by enumChoice("Mode", TickBaseMode.PAST)
.apply { tagBy(this) }
private val call by enumChoice("Call", TickBaseCall.GAME)

/**
* The range defines where we want to tickbase into. The first value is the minimum range, which we can
Expand All @@ -55,9 +58,10 @@ internal object ModuleTickBase : ClientModule("TickBase", Category.COMBAT) {

private val balanceRecoveryIncrement by float("BalanceRecoverIncrement", 1f, 0f..2f)
private val balanceMaxValue by int("BalanceMaxValue", 20, 0..200)
private val maxTicksAtATime by int("MaxTicksAtATime", 4, 1..20, "ticks").apply { tagBy(this) }
private val maxTicksAtATime by int("MaxTicksAtATime", 4, 1..20, "ticks")
private val pauseOnFlag by boolean("PauseOfFlag", true)
private val pauseAfterTick by int("PauseAfterTick", 0, 0..100, "ticks")
private val pause by int("Pause", 0, 0..20, "ticks")
private val cooldown by int("Cooldown", 0, 0..100, "ticks")
private val forceGround by boolean("ForceGround", false)
private val lineColor by color("Line", Color4b.WHITE)
.doNotIncludeAlways()
Expand All @@ -71,14 +75,14 @@ internal object ModuleTickBase : ClientModule("TickBase", Category.COMBAT) {
private val tickBuffer = mutableListOf<TickData>()

@Suppress("unused")
private val playerTickHandler = handler<PlayerTickEvent> {
private val playerTickHandler = handler<PlayerTickEvent> { event ->
// We do not want this module to conflict with blink
if (player.vehicle != null || ModuleBlink.running) {
return@handler
}

if (ticksToSkip-- > 0) {
it.cancelEvent()
event.cancelEvent()
}
}

Expand Down Expand Up @@ -121,30 +125,49 @@ internal object ModuleTickBase : ClientModule("TickBase", Category.COMBAT) {
}

// We do not want to tickbase if killaura is not ready to attack
if (requiresKillAura && !(ModuleKillAura.running &&
ModuleKillAura.clickScheduler.isClickOnNextTick(bestTick))) {
val breakRequirement = {
requiresKillAura && !(ModuleKillAura.running &&
ModuleKillAura.clickScheduler.isClickOnNextTick(bestTick))
}

if (breakRequirement()) {
return@tickHandler
}

when (mode) {
TickBaseMode.PAST -> {
ticksToSkip = bestTick + pauseAfterTick
ticksToSkip = bestTick + pause
waitTicks(ticksToSkip)
repeat(bestTick) {
player.tick()
call.tick()
tickBalance -= 1
}

ModuleDebug.debugParameter(this, "Recommended Skip", bestTick)
}

TickBaseMode.FUTURE -> {
repeat(bestTick) {
player.tick()
var totalSkipped = 0

for (i in 0 until bestTick) {
call.tick()
tickBalance -= 1
totalSkipped++

if (breakRequirement()) {
break
}
}
ticksToSkip = bestTick + pauseAfterTick

ModuleDebug.debugParameter(this, "Total Skipped", totalSkipped)
ModuleDebug.debugParameter(this, "Recommended Skip", bestTick)

ticksToSkip = totalSkipped + pause
waitTicks(ticksToSkip)
}
}

waitTicks(cooldown)
}

@Suppress("unused")
Expand Down Expand Up @@ -217,4 +240,29 @@ internal object ModuleTickBase : ClientModule("TickBase", Category.COMBAT) {
FUTURE("Future")
}

@Suppress("unused")
private enum class TickBaseCall(
override val choiceName: String,
val tick: () -> Unit
) : NamedChoice {

/**
* Runs a full game tick.
*
* TODO: Cancel full game ticks after this,
* not just the player ticks.
*/
GAME("Game", { mc.tick() }),

/**
* This will NOT update the game tick,
* but only the player tick - that means
* e.g. Rotation Manager will not update either.
*
* This was the previous default behavior of the TickBase,
* so it is kept for compatibility reasons.
*/
PLAYER("Player", { player.tick() })
}

}

0 comments on commit 25b3555

Please sign in to comment.