@@ -26,6 +26,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen
2626import com.lambda.interaction.request.rotating.Rotation
2727import com.lambda.interaction.request.rotating.RotationConfig
2828import com.lambda.interaction.request.rotating.RotationMode
29+ import com.lambda.interaction.request.rotating.visibilty.lookAt
2930import com.lambda.interaction.request.rotating.visibilty.lookAtHit
3031import com.lambda.module.Module
3132import com.lambda.module.tag.ModuleTag
@@ -55,11 +56,16 @@ object Freecam : Module(
5556 private val speed by setting(" Speed" , 0.5 , 0.1 .. 1.0 , 0.1 )
5657 private val sprint by setting(" Sprint Multiplier" , 3.0 , 0.1 .. 10.0 , 0.1 , description = " Set below 1.0 to fly slower on sprint." )
5758 private val reach by setting(" Reach" , 10.0 , 1.0 .. 100.0 , 1.0 , " Freecam reach distance" )
58- private val rotateToTarget by setting(" Rotate to target" , true )
59+ private val rotateMode by setting(" Rotate Mode" , FreecamRotationMode .None , " Rotation mode" )
60+ private val relative by setting(" Relative" , false , " Moves freecam relative to player position" ).onValueChange { _, it ->
61+ if (it) lastPlayerPosition = player.pos
62+ }
63+ private val keepYLevel by setting(" Keep Y Level" , false , " Don't change the camera y-level on player movement" , { relative })
5964
6065 override val rotationConfig = RotationConfig .Instant (RotationMode .Lock )
6166
6267 private var lastPerspective = Perspective .FIRST_PERSON
68+ private var lastPlayerPosition: Vec3d = Vec3d .ZERO
6369 private var prevPosition: Vec3d = Vec3d .ZERO
6470 private var position: Vec3d = Vec3d .ZERO
6571 private val lerpPos: Vec3d
@@ -90,17 +96,24 @@ object Freecam : Module(
9096 position = player.eyePos
9197 rotation = player.rotation
9298 velocity = Vec3d .ZERO
99+ lastPlayerPosition = player.pos
93100 }
94101
95102 onDisable {
96103 mc.options.perspective = lastPerspective
97104 }
98105
99106 listen<UpdateManagerEvent .Rotation > {
100- if (! rotateToTarget) return @listen
101-
102- mc.crosshairTarget?.let {
103- lookAtHit(it)?.requestBy(this @Freecam)
107+ when (rotateMode) {
108+ FreecamRotationMode .None -> return @listen
109+ FreecamRotationMode .KeepRotation -> {
110+ lookAt(rotation).requestBy(this @Freecam)
111+ }
112+ FreecamRotationMode .LookAtTarget -> {
113+ mc.crosshairTarget?.let {
114+ lookAtHit(it)?.requestBy(this @Freecam)
115+ }
116+ }
104117 }
105118 }
106119
@@ -135,6 +148,12 @@ object Freecam : Module(
135148 // Update position
136149 prevPosition = position
137150 position + = velocity
151+
152+ if (relative) {
153+ val delta = player.pos.subtract(lastPlayerPosition)
154+ position + = if (keepYLevel) Vec3d (delta.x, 0.0 , delta.z) else delta
155+ lastPlayerPosition = player.pos
156+ }
138157 }
139158
140159 listen<RenderEvent .UpdateTarget > {
@@ -145,4 +164,10 @@ object Freecam : Module(
145164 .orMiss // Can't be null (otherwise mc will spam "Null returned as 'hitResult', this shouldn't happen!")
146165 }
147166 }
167+
168+ enum class FreecamRotationMode {
169+ None ,
170+ LookAtTarget ,
171+ KeepRotation
172+ }
148173}
0 commit comments