1
1
package com.lambda.client.module.modules.movement
2
2
3
- import com.lambda.client.commons.extension.ceilToInt
4
- import com.lambda.client.commons.extension.floorToInt
3
+ import com.lambda.client.event.SafeClientEvent
4
+ import com.lambda.client.event.events.AddCollisionBoxToListEvent
5
5
import com.lambda.client.event.events.PacketEvent
6
- import com.lambda.client.event.events.PlayerTravelEvent
7
- import com.lambda.client.mixin.extension.playerMoving
6
+ import com.lambda.client.event.events.PlayerMoveEvent
7
+ import com.lambda.client.manager.managers.TimerManager.modifyTimer
8
8
import com.lambda.client.mixin.extension.playerY
9
9
import com.lambda.client.module.Category
10
10
import com.lambda.client.module.Module
11
- import com.lambda.client.util.BaritoneUtils
12
- import com.lambda.client.util.EntityUtils
11
+ import com.lambda.client.util.EntityUtils.flooredPosition
12
+ import com.lambda.client.util.threads.runSafe
13
13
import com.lambda.client.util.threads.safeListener
14
+ import com.lambda.mixin.accessor.player.AccessorEntityPlayerSP
14
15
import net.minecraft.block.Block
15
- import net.minecraft.block.BlockLiquid
16
- import net.minecraft.entity.Entity
17
- import net.minecraft.entity.item.EntityBoat
16
+ import net.minecraft.init.Blocks
18
17
import net.minecraft.network.play.client.CPacketPlayer
18
+ import net.minecraft.network.play.server.SPacketPlayerPosLook
19
19
import net.minecraft.util.math.AxisAlignedBB
20
20
import net.minecraft.util.math.BlockPos
21
+ import net.minecraft.util.math.BlockPos.PooledMutableBlockPos
22
+ import net.minecraftforge.client.event.InputUpdateEvent
23
+ import net.minecraftforge.fml.common.gameevent.TickEvent
24
+ import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent
25
+ import kotlin.math.ceil
26
+ import kotlin.math.floor
27
+ import kotlin.math.hypot
28
+
21
29
22
30
object Jesus : Module(
23
31
name = " Jesus" ,
24
32
description = " Allows you to walk on water" ,
25
33
category = Category .MOVEMENT
26
34
) {
27
- private val mode by setting(" Mode" , Mode .SOLID )
28
35
29
- private enum class Mode {
30
- SOLID , DOLPHIN
36
+ private val mode by setting(" Mode" , Mode .STRICT )
37
+
38
+ enum class Mode {
39
+ SOLID ,
40
+ STRICT ,
41
+ DOLPHIN
31
42
}
32
43
33
- private val waterWalkBox = AxisAlignedBB (0.0 , 0.0 , 0.0 , 1.0 , 0.99 , 1.0 )
44
+ private val preventJump by setting(" Prevent Jumping" , false , { mode == Mode .SOLID || mode == Mode .STRICT }, description = " Prevent jumping when using Jesus" )
45
+
46
+ private val bb = AxisAlignedBB (- 1.0 , - 1.0 , - 1.0 , 0.0 , 0.0 , 0.0 )
47
+ private val liquids = listOf (Blocks .WATER , Blocks .FLOWING_WATER , Blocks .LAVA , Blocks .FLOWING_LAVA )
48
+
49
+ private var ticksEnabled = 0
50
+ private var fakeY = 0.0
34
51
35
52
init {
36
- onToggle {
37
- BaritoneUtils .settings?.assumeWalkOnWater?.value = it
53
+ onDisable {
54
+ ticksEnabled = 0
55
+ fakeY = .0
38
56
}
39
57
40
- safeListener<PlayerTravelEvent > {
41
- if (mc.gameSettings.keyBindSneak.isKeyDown || player.fallDistance > 3.0f || ! isInWater(player) ) return @safeListener
58
+ safeListener<ClientTickEvent > {
59
+ if (it.phase != TickEvent . Phase . START ) return @safeListener
42
60
43
- if (mode == Mode .DOLPHIN ) {
44
- player.motionY + = 0.03999999910593033 // regular jump speed
45
- } else {
46
- player.motionY = 0.1
61
+ ticksEnabled++
62
+ }
47
63
48
- player.ridingEntity?.let {
49
- if (it !is EntityBoat ) it.motionY = 0.3
50
- }
64
+ safeListener<AddCollisionBoxToListEvent > {
65
+ if (mc.gameSettings.keyBindSneak.isKeyDown)
66
+ return @safeListener
67
+
68
+ if ((mode == Mode .SOLID || mode == Mode .STRICT )
69
+ && world.getBlockState(BlockPos (player.positionVector.add(.0 , - .1 + player.motionY, .0 ))).material.isLiquid
70
+ ) {
71
+ it.collisionBoxList.add(bb.offset(player.posX, floor(player.posY), player.posZ))
51
72
}
52
73
}
53
74
54
- safeListener<PacketEvent .Send > {
55
- if (it.packet !is CPacketPlayer || ! it.packet.playerMoving) return @safeListener
56
- if (mc.gameSettings.keyBindSneak.isKeyDown || player.ticksExisted % 2 != 0 ) return @safeListener
75
+ safeListener<PlayerMoveEvent > { event ->
76
+ (player as AccessorEntityPlayerSP ).lcSetLastReportedPosY(- 99.9 )
77
+
78
+ if (mc.gameSettings.keyBindSneak.isKeyDown) return @safeListener
57
79
58
- val entity = player.ridingEntity ? : player
80
+ ( player as AccessorEntityPlayerSP ).lcSetLastReportedPosY( - 999.0 )
59
81
60
- if (EntityUtils .isAboveLiquid(entity, true ) && ! isInWater(entity)) {
61
- it.packet.playerY + = 0.02
82
+ if (player.isInWater || world.getBlockState(player.flooredPosition).material.isLiquid) {
83
+ event.y = (.11 .also { player.motionY = it })
84
+ }
85
+
86
+ if (player.onGround &&
87
+ ! checkBlockCollisionNoLiquid(
88
+ player.entityBoundingBox.offset(.0 , - .01 , .0 ),
89
+ liquids + Blocks .AIR
90
+ )
91
+ ) {
92
+ when (mode) {
93
+ Mode .DOLPHIN -> {
94
+ if (hypot(event.x, event.y) > .2873 * .9 ) {
95
+ event.x * = .95
96
+ event.z * = .95
97
+ }
98
+ }
99
+ Mode .STRICT -> {
100
+ val lava = ! checkBlockCollisionNoLiquid(
101
+ player.entityBoundingBox.offset(.0 , - .01 , .0 ),
102
+ listOf (Blocks .AIR , Blocks .LAVA , Blocks .FLOWING_LAVA )
103
+ )
104
+ // .38 is from lava liquid speed at max speed, 1.24 is from water liquid speed at max speed
105
+ // because of the way "Lambda Client" handled its "PlayerMoveEvent" I have to use "magic numbers" to compensate
106
+ event.x * = if (lava) .57 else 1.09
107
+ event.z * = if (lava) .57 else 1.09
108
+ }
109
+
110
+ else -> {}
111
+ }
62
112
}
63
113
}
64
- }
65
114
66
- @JvmStatic
67
- fun handleAddCollisionBoxToList (pos : BlockPos , block : Block , entity : Entity ? , collidingBoxes : MutableList <AxisAlignedBB >) {
68
- if (isDisabled || mode == Mode .DOLPHIN ) return
69
- if (mc.gameSettings.keyBindSneak.isKeyDown) return
70
- if (block !is BlockLiquid ) return
71
- if (entity == null || entity is EntityBoat ) return
115
+ safeListener<InputUpdateEvent > {
116
+ if (preventJump &&
117
+ fakeY != .0
118
+ ) it.movementInput.jump = false
119
+ }
72
120
73
- val player = mc.player ? : return
74
- if (player.fallDistance > 3.0f ) return
121
+ safeListener< PacketEvent . Send > { event ->
122
+ if (event.packet !is CPacketPlayer ) return @safeListener
75
123
76
- if (entity != player && entity != player.ridingEntity) return
77
- if (isInWater(entity) || entity.posY < pos.y) return
78
- if (! EntityUtils .isAboveLiquid(entity)) return
124
+ if (mc.gameSettings.keyBindSneak.isKeyDown) {
125
+ if (mode == Mode .STRICT ) {
126
+ player.posY - = fakeY
127
+ }
79
128
80
- collidingBoxes.add(waterWalkBox.offset(pos))
81
- }
129
+ fakeY = 0.0
130
+ return @safeListener
131
+ }
132
+
133
+ val playerBB = player.entityBoundingBox
134
+ if (player.isInWater
135
+ || ! world.getBlockState(BlockPos (player.positionVector.add(.0 , - .1 + player.motionY, .0 ))).material.isLiquid
136
+ || world.getCollisionBoxes(player, playerBB.offset(0.0 , - .0001 , 0.0 )).isEmpty()
137
+ ) {
138
+ fakeY = 0.0
139
+ return @safeListener
140
+ }
141
+
142
+ val packet = event.packet
143
+
144
+ when (mode) {
145
+ Mode .STRICT -> {
146
+ if ((- .4 ).coerceAtLeast(fakeY).also { fakeY = it } > - .4 ) {
147
+ fakeY - = .08
148
+ fakeY * = .98
149
+ packet.playerY + = fakeY
150
+ } else {
151
+ packet.playerY + = fakeY - if (ticksEnabled % 2 == 0 ) .0 else - .00001
152
+ }
153
+
154
+ if (checkBlockCollisionNoLiquid(
155
+ player.entityBoundingBox.offset(.0 , packet.playerY - player.posY, .0 ),
156
+ liquids + Blocks .AIR
157
+ )) {
158
+ packet.playerY = player.posY
159
+ }
160
+ }
161
+ Mode .SOLID -> {
162
+ fakeY = 0.0
82
163
83
- private fun isInWater (entity : Entity ): Boolean {
84
- mc.world?.let {
85
- val y = (entity.posY + 0.01 ).floorToInt()
164
+ if (ticksEnabled % 2 == 0 ) packet.playerY - = .001
86
165
87
- for (x in entity.posX.floorToInt() until entity.posX.ceilToInt()) {
88
- for (z in entity.posZ.floorToInt() until entity.posZ.ceilToInt()) {
89
- val pos = BlockPos (x, y, z)
90
- if (it.getBlockState(pos).block is BlockLiquid ) return true
166
+ if (checkBlockCollisionNoLiquid(
167
+ player.entityBoundingBox.offset(.0 , packet.playerY - player.posY, .0 ),
168
+ liquids + Blocks .AIR
169
+ )) {
170
+ packet.playerY = player.posY
171
+ }
91
172
}
173
+
174
+ else -> {}
92
175
}
93
176
}
94
177
95
- return false
178
+ safeListener<PacketEvent .Receive > {
179
+ if (it.packet !is SPacketPlayerPosLook ) return @safeListener
180
+
181
+ fakeY = player.posY - it.packet.y
182
+ }
96
183
}
97
184
185
+ private fun SafeClientEvent.checkBlockCollisionNoLiquid (bb : AxisAlignedBB , allowed : List <Block >): Boolean {
186
+ val minX = floor(bb.minX).toInt()
187
+ val maxX = ceil(bb.maxX).toInt()
188
+ val minY = floor(bb.minY).toInt()
189
+ val maxY = ceil(bb.maxY).toInt()
190
+ val minZ = floor(bb.minZ).toInt()
191
+ val maxZ = ceil(bb.maxZ).toInt()
192
+
193
+ val mutableBlockPos = PooledMutableBlockPos .retain()
194
+
195
+ for (x in minX until maxX) {
196
+ for (y in minY until maxY) {
197
+ for (z in minZ until maxZ) {
198
+ val blockState = world.getBlockState(mutableBlockPos.setPos(x, y, z))
199
+
200
+ if (! allowed.contains(blockState.block)) {
201
+ mutableBlockPos.release()
202
+ return true
203
+ }
204
+ }
205
+ }
206
+ }
207
+
208
+ mutableBlockPos.release()
209
+ return false
210
+ }
98
211
}
0 commit comments