11package com.lambda.module.modules.movement
22
3+ import com.lambda.context.SafeContext
4+ import com.lambda.event.events.MovementEvent
5+ import com.lambda.event.events.PlayerPacketEvent
6+ import com.lambda.event.events.TickEvent
37import com.lambda.event.events.WorldEvent
48import com.lambda.event.listener.SafeListener.Companion.listener
59import com.lambda.module.Module
610import com.lambda.module.tag.ModuleTag
11+ import com.lambda.util.Nameable
12+ import com.lambda.util.math.MathUtils.toInt
13+ import com.lambda.util.math.VecUtils.minus
14+ import com.lambda.util.player.MovementUtils.isInputting
15+ import com.lambda.util.player.MovementUtils.motionY
16+ import com.lambda.util.player.MovementUtils.setSpeed
717import net.minecraft.block.Blocks
18+ import net.minecraft.util.math.BlockPos
19+ import net.minecraft.util.math.Vec3d
820import net.minecraft.util.shape.VoxelShapes
921
1022object Jesus : Module(
1123 name = " Jesus" ,
1224 description = " Allows to walk on water" ,
1325 defaultTags = setOf(ModuleTag .MOVEMENT )
1426) {
15- private val waterState by lazy { Blocks .WATER .defaultState }
27+ private val mode by setting(" Mode" , Mode .NCP )
28+
29+ // Dolphin
30+ private val dolphinStrength by setting(" Dolphin Strength" , 0.1 , 0.01 .. 0.2 , 0.01 ) { mode == Mode .NCP_DOLPHIN }
31+
32+ // NCP New
33+ private val slowDown by setting(" Slow Down" , true ) { mode == Mode .NCP_NEW }
34+
1635 private val fullShape = VoxelShapes .fullCube()
36+ private var goUp = true
37+ private var swimmingTicks = 0
38+
39+ enum class Mode (override val displayName : String , val collision : Boolean ) : Nameable.NamedEnum {
40+ NCP (" NCP" , true ),
41+ NCP_DOLPHIN (" NCP Dolphin" , false ),
42+ NCP_NEW (" NCP New" , true )
43+ }
44+
45+ private var shouldWork = false
1746
1847 init {
48+ listener<PlayerPacketEvent .Pre > { event ->
49+ if (! shouldWork || ! waterAt(- 0.0001 )) return @listener
50+ event.onGround = false
51+
52+ if (! player.isOnGround) return @listener
53+
54+ when (mode) {
55+ Mode .NCP -> {
56+ val offset = if (player.age % 2 == 0 ) 0.001 else 0.002
57+ event.position - = Vec3d (0.0 , offset, 0.0 )
58+ }
59+
60+ Mode .NCP_NEW -> {
61+ event.position - = Vec3d (0.0 , 0.02 + 0.0001 * swimmingTicks, 0.0 )
62+ }
63+
64+ else -> {}
65+ }
66+ }
67+
68+ listener<MovementEvent .Pre > {
69+ if (! shouldWork) return @listener
70+
71+ goUp = waterAt(0.0001 )
72+ val collidingWater = waterAt(- 0.0001 )
73+
74+ when (mode) {
75+ Mode .NCP -> {
76+ if (! collidingWater || ! player.isOnGround) return @listener
77+ setSpeed(Speed .NCP_BASE_SPEED * isInputting.toInt())
78+ }
79+
80+ Mode .NCP_DOLPHIN -> {
81+ if (goUp) {
82+ player.motionY = dolphinStrength
83+
84+ if (! waterAt(0.2 )) {
85+ setSpeed(Speed .NCP_BASE_SPEED * isInputting.toInt())
86+ } else player.motionY = 0.18
87+ }
88+ }
89+
90+ Mode .NCP_NEW -> {
91+ if (! collidingWater) {
92+ swimmingTicks = 0
93+ return @listener
94+ }
95+
96+ if (++ swimmingTicks < 15 ) {
97+ if (player.isOnGround) {
98+ setSpeed(Speed .NCP_BASE_SPEED * isInputting.toInt())
99+ }
100+
101+ return @listener
102+ }
103+
104+ swimmingTicks = 0
105+
106+ if (slowDown) setSpeed(0.0 )
107+ player.motionY = 0.08000001
108+ }
109+ }
110+ }
111+
19112 listener<WorldEvent .Collision > { event ->
20- if (event.state == waterState) {
113+ if (! shouldWork || goUp || ! mode.collision) return @listener
114+
115+ if (event.state.block == Blocks .WATER ) {
21116 event.shape = fullShape
22117 }
23118 }
119+
120+ listener<MovementEvent .InputUpdate > {
121+ if (! shouldWork || ! goUp || mode == Mode .NCP_DOLPHIN ) return @listener
122+ it.input.jumping = true
123+ }
124+
125+ listener<TickEvent .Pre > {
126+ shouldWork = ! player.abilities.flying && ! player.isFallFlying && ! player.input.sneaking
127+ }
128+
129+ onEnable {
130+ goUp = false
131+ swimmingTicks = 0
132+ shouldWork = false
133+ }
134+ }
135+
136+ private fun SafeContext.waterAt (yOffset : Double ) : Boolean {
137+ val b = player.boundingBox
138+ val y = b.minY + yOffset
139+
140+ for (xref in 0 .. 1 ) {
141+ for (zref in 0 .. 1 ) {
142+ val x = if (xref == 0 ) b.minX else b.maxX
143+ val z = if (zref == 0 ) b.minZ else b.maxZ
144+
145+ val pos = BlockPos .ofFloored(x, y, z)
146+ val state = world.getBlockState(pos)
147+ if (state.block != Blocks .WATER ) return false
148+ }
149+ }
150+
151+ return true
24152 }
25153}
0 commit comments