Skip to content

Freecam improvements#247

Open
IceTank wants to merge 1 commit intolambda-client:1.21.11from
IceTank:feature/freecam-tracking-mode
Open

Freecam improvements#247
IceTank wants to merge 1 commit intolambda-client:1.21.11from
IceTank:feature/freecam-tracking-mode

Conversation

@IceTank
Copy link
Contributor

@IceTank IceTank commented Feb 27, 2026

Adds a follow mode to freecam that keeps the freecam camera close to the player but only moves it if the player is moving away. This also adds an option in follow mode to track the player's eye position with the camera.

tracking.freecam.mp4

@IceTank IceTank changed the title Add Freecam tracking mode Add Freecam follow mode Feb 27, 2026
@IceTank IceTank changed the title Add Freecam follow mode Freecam improvements Mar 2, 2026
@IceTank IceTank marked this pull request as ready for review March 2, 2026 09:58
Copy link
Member

@beanbag44 beanbag44 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really cool, didnt know it would act like a string attached to the player. Some changes tho


private fun Vec2d.normalize(): Vec2d {
val length = distanceTo(Vec2d(0.0, 0.0))
return if (length > 0) Vec2d(x / length, y / length) else Vec2d(0.0, 0.0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use Vec2d.ZERO

return players.minByOrNull { it.eyePos.squaredDistanceTo(position) }
}

private fun Vec2d.distanceTo(other: Vec2d): Double {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have the dist functions in Vectors.kt, could prob just add the extension functions for dist and distSq in there for Vec2d

if (player.gameMode != GameMode.SPECTATOR) {
return player
}
val players = world.players.filter { it != player && it !is ClientPlayerEntity }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could remove the it != player check as the ClientPlayerEntity check already acounts for that

}
}

enum class FreecamRotationMode(override val displayName: String, override val description: String) : NamedEnum, Describable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usually for local private enums i dont bother with the name prefix and just use RotationMode or Mode for example. Also these could be private

private val keepYLevel by setting("Keep Y Level", false, "Don't change the camera y-level on player movement. Applies to relative and follow modes")


override val rotationConfig = RotationConfig.Instant(RotationMode.Lock)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be applied using setDefaultAutomationConfig { hideAllGroupsExcept(rotationConfig) } or something like that in the init block before the listeners

FreecamRotationMode.None -> return@listen
FreecamRotationMode.KeepRotation -> rotationRequest { rotation(rotation) }.submit()
FreecamRotationMode.LookAtTarget -> mc.crosshairTarget?.let {
runSafeAutomated {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think runSafeAutomated is required here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants