Skip to main content

Overview

The CombatManager tracks combat state and manages pausing of combat-related actions. It’s essential for coordinating combat modules and preventing conflicts.

Properties

isInCombat

Indicates whether the player is currently in combat.
val isInCombat: Boolean
Returns true if:
  • Recent combat activity (within last 40 ticks / 2 seconds)
  • KillAura is active and has a target
Example:
val handler = handler<GameTickEvent> {
    if (CombatManager.isInCombat) {
        // Player is fighting
        useDefensiveStrategies()
    }
}

shouldPauseCombat

Indicates if combat actions should be paused.
val shouldPauseCombat: Boolean
Used by modules like AutoSoup to temporarily pause combat. Example:
if (CombatManager.shouldPauseCombat) {
    // Don't attack right now
    return
}

shouldPauseRotation

Indicates if rotation updates should be paused.
val shouldPauseRotation: Boolean
Used by modules like AutoPot to prevent rotation interference.

shouldPauseBlocking

Indicates if blocking actions should be paused.
val shouldPauseBlocking: Boolean
Used to coordinate auto-blocking with other actions.

duringCombat

Ticks remaining in combat state.
var duringCombat: Int
Automatically decrements each tick. Set to PAUSE_COMBAT (40 ticks) when attacking.

Methods

pauseCombatForAtLeast

Pauses combat actions for a minimum duration.
fun pauseCombatForAtLeast(pauseTime: Int)
Parameters:
  • pauseTime - Minimum ticks to pause (only extends if longer than current pause)
Example:
// Pause combat for 1 second (20 ticks) to drink soup
CombatManager.pauseCombatForAtLeast(20)

pauseRotationForAtLeast

Pauses rotation updates for a minimum duration.
fun pauseRotationForAtLeast(pauseTime: Int)
Parameters:
  • pauseTime - Minimum ticks to pause
Example:
// Pause rotations while throwing a potion
CombatManager.pauseRotationForAtLeast(10)

pauseBlockingForAtLeast

Pauses blocking actions for a minimum duration.
fun pauseBlockingForAtLeast(pauseTime: Int)
Parameters:
  • pauseTime - Minimum ticks to pause
Example:
// Pause blocking while attacking
CombatManager.pauseBlockingForAtLeast(5)

update

Updates combat state. Called automatically every tick.
fun update()

Constants

PAUSE_COMBAT

Default combat pause duration.
const val PAUSE_COMBAT = 40 // 40 ticks = 2 seconds

Events

CombatManager listens to:

AttackEntityEvent

When the player attacks an entity:
  • Sets duringCombat to PAUSE_COMBAT
  • Fires TargetChangeEvent if attacking a player

GameTickEvent

Every tick:
  • Decrements pause timers
  • Decrements duringCombat counter

Usage Examples

Coordinating with Combat

val healingHandler = handler<GameTickEvent> {
    if (player.health < 10f && !CombatManager.shouldPauseCombat) {
        // Safe to heal, combat is not active
        CombatManager.pauseCombatForAtLeast(20)
        useHealthPotion()
    }
}

Checking Combat State

val escapeHandler = handler<GameTickEvent> {
    if (CombatManager.isInCombat && player.health < 5f) {
        // Player is in combat and low health
        activateEscapeMode()
    }
}

Pausing for Actions

// In AutoPot module
val throwHandler = handler<GameTickEvent> {
    if (shouldThrowPotion()) {
        // Pause combat and rotations while throwing
        CombatManager.pauseCombatForAtLeast(15)
        CombatManager.pauseRotationForAtLeast(15)
        
        throwPotion()
    }
}

Respecting Pauses

// In KillAura module
val attackHandler = handler<GameTickEvent> {
    if (CombatManager.shouldPauseCombat) {
        // Another module needs us to pause
        return@handler
    }
    
    // Continue with attack logic
    findAndAttackTarget()
}

Combat Duration Tracking

val handler = handler<GameTickEvent> {
    val ticksInCombat = CombatManager.duringCombat
    
    if (ticksInCombat > 0) {
        // Player has been in combat for ${ticksInCombat} ticks
        updateCombatUI(ticksInCombat)
    }
}

Combat Coordination Pattern

Typical pattern for combat modules:
object ModuleCombatFeature : ClientModule("CombatFeature", Category.COMBAT) {
    
    val tickHandler = handler<GameTickEvent> {
        // Check if we should pause
        if (CombatManager.shouldPauseCombat) {
            return@handler
        }
        
        // Check if action needed
        if (needsAction()) {
            // Pause combat for our action
            CombatManager.pauseCombatForAtLeast(actionDuration)
            
            // Optionally pause rotations too
            if (needsRotationPause) {
                CombatManager.pauseRotationForAtLeast(actionDuration)
            }
            
            // Perform action
            performAction()
        }
    }
}

Combat State Utilities

Common utility functions for combat:

shouldBeAttacked

Extension function to check if an entity should be attacked:
val validTargets = world.entities.filter { it.shouldBeAttacked() }

Combat Distance Checks

val inMeleeRange = target.distanceTo(player) <= 3.5
val inCombatRange = target.distanceTo(player) <= 6.0

Best Practices

Always check shouldPauseCombat before attacking to respect other modules’ needs.
Don’t set pause timers too long - they block other combat functionality. Most actions need 5-20 ticks.
The combat state (isInCombat) persists for 2 seconds after the last attack, useful for keeping combat-related features active briefly after fighting.

Integration Example

Combining CombatManager with RotationManager:
val smartCombatHandler = handler<GameTickEvent> {
    // Check combat state
    if (CombatManager.shouldPauseCombat || CombatManager.shouldPauseRotation) {
        return@handler
    }
    
    // Find target
    val target = findTarget() ?: return@handler
    
    // Set rotation
    val rotation = aimAt(target.eyePosition)
    RotationManager.setRotationTarget(
        rotation = rotation,
        valueGroup = rotationsConfigurable,
        priority = Priority.IMPORTANT_FOR_USAGE,
        provider = this@ModuleSmartCombat,
        whenReached = {
            // Attack when rotation is ready
            if (!CombatManager.shouldPauseCombat) {
                attackEntity(target)
            }
        }
    )
}

See Also

Build docs developers (and LLMs) love