@@ -7,69 +7,110 @@ package net.ccbluex.liquidbounce.features.module.modules.visual
77
88import net.ccbluex.liquidbounce.event.EventTarget
99import net.ccbluex.liquidbounce.event.Render3DEvent
10- import net.ccbluex.liquidbounce.event.UpdateEvent
10+ import net.ccbluex.liquidbounce.event.WorldEvent
1111import net.ccbluex.liquidbounce.features.module.Category
1212import net.ccbluex.liquidbounce.features.module.Module
13+ import net.ccbluex.liquidbounce.utils.extensions.*
14+ import net.ccbluex.liquidbounce.utils.render.ColorSettingsInteger
1315import net.ccbluex.liquidbounce.utils.render.ColorUtils.rainbow
1416import net.ccbluex.liquidbounce.utils.render.RenderUtils.glColor
1517import net.ccbluex.liquidbounce.value.boolean
16- import net.ccbluex.liquidbounce.value.int
18+ import net.ccbluex.liquidbounce.value.float
1719import org.lwjgl.opengl.GL11.*
18- import java.awt.Color
1920
2021object Breadcrumbs : Module(" Breadcrumbs" , Category .VISUAL , hideModule = false ) {
21- val colorRainbow by boolean(" Rainbow" , false )
22- val colorRed by int(" R" , 255 , 0 .. 255 ) { ! colorRainbow }
23- val colorGreen by int(" G" , 179 , 0 .. 255 ) { ! colorRainbow }
24- val colorBlue by int(" B" , 72 , 0 .. 255 ) { ! colorRainbow }
22+ val rainbow by boolean(" Rainbow" , false )
23+ val colors = ColorSettingsInteger (this , " Color" , withAlpha = false ) { ! rainbow }
24+ private val lineHeight by float(" LineHeight" , 0.25F , 0.25F .. 2F )
25+ private val temporary by boolean(" Temporary" , true )
26+ private val fade by boolean(" Fade" , true ) { temporary }
27+ private val lifeTime by float(" LifeTime" , 1F , 0F .. 10F ) { temporary }
2528
26- private val positions = mutableListOf<DoubleArray >()
29+ private val positions = mutableListOf<PositionData >()
2730
2831 @EventTarget
2932 fun onRender3D (event : Render3DEvent ) {
30- val color = if (colorRainbow) rainbow() else Color (colorRed, colorGreen, colorBlue)
33+ val player = mc.thePlayer ? : return
34+
35+ if (positions.isEmpty() && ! player.isMoving) {
36+ return
37+ }
38+
39+ val currentTime = System .currentTimeMillis()
40+ val fadeSeconds = lifeTime * 1000L
3141
3242 glPushMatrix()
43+
3344 glDisable(GL_TEXTURE_2D )
3445 glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA )
3546 glEnable(GL_LINE_SMOOTH )
3647 glEnable(GL_BLEND )
3748 glDisable(GL_DEPTH_TEST )
49+ glDisable(GL_CULL_FACE )
50+
51+ glEnable(GL_ALPHA_TEST )
52+ glAlphaFunc(GL_GREATER , 0.0f )
53+
54+ player.interpolatedPosition(player.prevPos).let { pos ->
55+ val data = PositionData (pos.toDoubleArray(), currentTime)
56+
57+ val lastData = positions.lastOrNull()?.array
58+
59+ if (lastData == null || ! lastData.contentEquals(data.array))
60+ positions + = data
61+ }
3862
3963 mc.entityRenderer.disableLightmap()
4064
41- glBegin(GL_LINE_STRIP )
42- glColor(color)
65+ glBegin(GL_QUADS )
4366
4467 val renderPosX = mc.renderManager.viewerPosX
4568 val renderPosY = mc.renderManager.viewerPosY
4669 val renderPosZ = mc.renderManager.viewerPosZ
4770
48- for (pos in positions)
49- glVertex3d(pos[0 ] - renderPosX, pos[1 ] - renderPosY, pos[2 ] - renderPosZ)
71+ positions.removeAll {
72+ val timestamp = System .currentTimeMillis() - it.time
73+ val transparency = if (fade) {
74+ (0f .. 150f ).lerpWith(1 - (timestamp / fadeSeconds).coerceAtMost(1.0F ))
75+ } else 150f
76+
77+ val startPos = it.array
78+ val endPos = positions.getOrNull(positions.indexOf(it) + 1 )?.array
79+
80+ if (endPos != null ) {
81+ val color = if (rainbow) rainbow() else colors.color()
82+
83+ glColor(color.withAlpha(transparency.toInt()))
84+
85+ glVertex3d(startPos[0 ] - renderPosX, startPos[1 ] - renderPosY, startPos[2 ] - renderPosZ)
86+ glVertex3d(startPos[0 ] - renderPosX, startPos[1 ] - renderPosY + lineHeight, startPos[2 ] - renderPosZ)
87+ glVertex3d(endPos[0 ] - renderPosX, endPos[1 ] - renderPosY + lineHeight, endPos[2 ] - renderPosZ)
88+ glVertex3d(endPos[0 ] - renderPosX, endPos[1 ] - renderPosY, endPos[2 ] - renderPosZ)
89+ }
90+
91+ temporary && timestamp > fadeSeconds
92+ }
5093
5194 glColor4d(1.0 , 1.0 , 1.0 , 1.0 )
5295 glEnd()
96+
97+ glEnable(GL_CULL_FACE )
5398 glEnable(GL_DEPTH_TEST )
99+ glDisable(GL_ALPHA_TEST )
54100 glDisable(GL_LINE_SMOOTH )
55101 glDisable(GL_BLEND )
56102 glEnable(GL_TEXTURE_2D )
57103 glPopMatrix()
58104 }
59105
60106 @EventTarget
61- fun onUpdate (event : UpdateEvent ) {
62- positions + = doubleArrayOf(mc.thePlayer.posX, mc.thePlayer.entityBoundingBox.minY, mc.thePlayer.posZ)
63- }
64-
65- override fun onEnable () {
66- val thePlayer = mc.thePlayer ? : return
67-
68- positions + = doubleArrayOf(thePlayer.posX, thePlayer.posY + thePlayer.eyeHeight * 0.5f , thePlayer.posZ)
69- positions + = doubleArrayOf(thePlayer.posX, thePlayer.posY, thePlayer.posZ)
107+ fun onWorld (event : WorldEvent ) {
108+ positions.clear()
70109 }
71110
72111 override fun onDisable () {
73112 positions.clear()
74113 }
75- }
114+ }
115+
116+ data class PositionData (val array : DoubleArray , val time : Long )
0 commit comments