Overview
The RotationManager handles all rotation-related functionality, including smooth rotation interpolation, server-side rotation synchronization, and movement correction.
Key Concepts
Current vs Server Rotation
- Current Rotation: The rotation the client is aiming at (may not be sent to server yet)
- Server Rotation: The rotation the server has received and acknowledged
- Actual Server Rotation: The rotation that was actually sent to the server
- Theoretical Server Rotation: What the rotation would be if not lagging/blinking
Properties
currentRotation
The rotation the client wants to aim at.
val currentRotation: Rotation?
Example:
if (RotationManager.currentRotation != null) {
val yaw = RotationManager.currentRotation!!.yaw
val pitch = RotationManager.currentRotation!!.pitch
}
serverRotation
The rotation currently active on the server.
val serverRotation: Rotation
Accounts for blink and freeze states automatically.
activeRotationTarget
The current active rotation target being aimed at.
val activeRotationTarget: RotationTarget?
Methods
setRotationTarget (with Rotation)
Sets a target rotation to aim at.
fun setRotationTarget(
rotation: Rotation,
considerInventory: Boolean = true,
valueGroup: RotationsValueGroup,
priority: Priority,
provider: ClientModule,
whenReached: RestrictedSingleUseAction? = null
)
Parameters:
rotation - The target rotation (yaw, pitch)
considerInventory - Don’t rotate if inventory is open
valueGroup - Rotation settings (speed, smoothing, etc.)
priority - Priority level for this rotation request
provider - The module requesting the rotation
whenReached - Callback when rotation target is reached
Example:
val targetRotation = Rotation(
yaw = calculateYaw(target),
pitch = calculatePitch(target)
)
RotationManager.setRotationTarget(
rotation = targetRotation,
valueGroup = rotationsConfigurable,
priority = Priority.IMPORTANT_FOR_USAGE,
provider = this
)
setRotationTarget (with RotationTarget)
Sets a rotation target with advanced options.
fun setRotationTarget(
plan: RotationTarget,
priority: Priority,
provider: ClientModule
)
isRotatingAllowed
Checks if rotation is currently allowed.
fun isRotatingAllowed(rotationTarget: RotationTarget): Boolean
Returns: true if rotation can be updated, false if blocked (e.g., inventory open)
update
Updates the current rotation to the next step. Called automatically every tick.
rotationMatchesPreviousRotation
Checks if the rotation hasn’t changed since last update.
fun rotationMatchesPreviousRotation(): Boolean
Rotation Target Configuration
Movement Correction
Controls how player movement is adjusted during rotation:
OFF - No movement correction
SILENT - Correct movement without changing look direction
CHANGE_LOOK - Change player’s actual look direction
val target = rotationsConfigurable.toRotationTarget(
rotation = targetRotation,
considerInventory = true
)
Usage Examples
Basic Rotation to Entity
val rotationHandler = handler<GameTickEvent> {
val target = world.entities.firstOrNull { it.shouldBeAttacked() }
if (target != null) {
val rotation = aimAt(target.eyePosition)
RotationManager.setRotationTarget(
rotation = rotation,
valueGroup = rotationsConfigurable,
priority = Priority.IMPORTANT_FOR_USAGE,
provider = this
)
}
}
Rotation with Callback
RotationManager.setRotationTarget(
rotation = targetRotation,
valueGroup = rotationsConfigurable,
priority = Priority.IMPORTANT_FOR_USAGE,
provider = this,
whenReached = {
// Rotation has reached target
performAction()
}
)
Checking Server Rotation
val handler = handler<AttackEntityEvent> { event ->
// Only attack if we're actually facing the target on the server
val serverYaw = RotationManager.serverRotation.yaw
val targetYaw = calculateYaw(event.entity)
if (abs(serverYaw - targetYaw) > 10f) {
event.cancelEvent()
}
}
Using Movement Correction
// With silent movement correction (strafe while looking different direction)
val target = rotationsConfigurable.toRotationTarget(
rotation = targetRotation,
considerInventory = true
)
target.movementCorrection = MovementCorrection.SILENT
RotationManager.setRotationTarget(
plan = target,
priority = Priority.IMPORTANT_FOR_USAGE,
provider = this
)
Aiming Utilities
Common rotation calculation utilities:
aimAt
// Aim at a specific position
val rotation = aimAt(targetPos)
facingAngle
// Calculate angle difference
val angle = facingAngle(targetRotation)
Priority System
Rotation requests use a priority system. Higher priority requests override lower ones:
Priority.NOT_IMPORTANT - Low priority
Priority.NORMAL - Standard priority
Priority.IMPORTANT_FOR_PLAYER - Player input priority
Priority.IMPORTANT_FOR_USAGE - Important for module functionality
// High priority rotation (e.g., in KillAura)
RotationManager.setRotationTarget(
rotation = targetRotation,
priority = Priority.IMPORTANT_FOR_USAGE,
valueGroup = rotationsConfigurable,
provider = this
)
Best Practices
Always check if a rotation is allowed before setting it to avoid conflicts with inventory operations.
Don’t set rotations every tick unless necessary. Use the whenReached callback for one-time actions.
The RotationManager automatically handles rotation interpolation and smoothing based on the configured values.
See Also