diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/ClickScheduler.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/ClickScheduler.kt index a8df184d820..995ca152c36 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/ClickScheduler.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/ClickScheduler.kt @@ -22,11 +22,15 @@ import net.ccbluex.liquidbounce.config.types.Configurable import net.ccbluex.liquidbounce.config.types.NamedChoice import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.EventListener +import net.ccbluex.liquidbounce.event.events.AttackEntityEvent import net.ccbluex.liquidbounce.event.events.GameTickEvent import net.ccbluex.liquidbounce.event.handler +import net.ccbluex.liquidbounce.features.module.modules.combat.criticals.ModuleCriticals import net.ccbluex.liquidbounce.features.module.modules.render.ModuleDebug +import net.ccbluex.liquidbounce.utils.client.player import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention import net.ccbluex.liquidbounce.utils.kotlin.random +import net.minecraft.entity.LivingEntity import kotlin.random.Random import kotlin.random.nextInt @@ -56,12 +60,15 @@ open class ClickScheduler(val parent: T, showCooldown: Boolean, maxCps: Int = newClickCycle() } private val clickTechnique by enumChoice("Technique", ClickTechnique.STABILIZED) + private val smart by boolean("Smart", false) class Cooldown(module: T) : ToggleableConfigurable(module, "Cooldown", true) - where T: EventListener { + where T : EventListener { - private val minimumCooldown by floatRange("Minimum", - 1.0f..1.0f, 0.0f..2.0f) + private val minimumCooldown by floatRange( + "Minimum", + 1.0f..1.0f, 0.0f..2.0f + ) private var nextCooldown = minimumCooldown.random() @@ -114,7 +121,43 @@ open class ClickScheduler(val parent: T, showCooldown: Boolean, maxCps: Int = private fun isOvertime(ticks: Int = 0) = lastClickPassed + (ticks * 50L) > 1000L || (cooldown?.enabled == true && cooldown.readyToAttack(ticks)) + private val shouldClick: Boolean + get() { + if (player.hurtTime > 0 || ModuleCriticals.canDoCriticalHit()) return true + + val enemy = currentEnemy + if (enemy is LivingEntity) { + return enemy.hurtTime <= 3 + } + + return true + } + + private var currentEnemy: LivingEntity? = null + + val attackHandler = handler { event -> + val enemy = event.entity + if (enemy is LivingEntity) { + currentEnemy = enemy + } + ModuleDebug.debugParameter(this, "ShouldClick", shouldClick) + } + + val gameTickHandler = handler { + resetEnemyIfInvalid() + } + + private fun resetEnemyIfInvalid() { + if (currentEnemy?.isAlive == false) { + currentEnemy = null + } + } + fun clicks(click: () -> Boolean) { + if (smart && !shouldClick) { + return + } + val clicks = clickCycle?.clicksAt(isOvertime = isOvertime()) ?: return clickCycle?.let { cycle ->