1+ package org.lambda
2+
3+ import com.lambda.client.event.events.PacketEvent
4+ import com.lambda.client.event.events.RenderOverlayEvent
5+ import com.lambda.client.event.events.RenderWorldEvent
6+ import com.lambda.client.module.Category
7+ import com.lambda.client.plugin.api.PluginModule
8+ import com.lambda.client.util.graphics.ESPRenderer
9+ import com.lambda.client.util.graphics.GlStateUtils
10+ import com.lambda.client.util.graphics.ProjectionUtils
11+ import com.lambda.client.util.graphics.font.FontRenderAdapter
12+ import com.lambda.client.util.math.CoordinateConverter.asString
13+ import com.lambda.client.util.math.VectorUtils.toVec3dCenter
14+ import com.lambda.client.util.text.MessageSendHelper
15+ import com.lambda.event.listener.listener
16+ import net.minecraft.init.SoundEvents
17+ import net.minecraft.network.play.server.SPacketSoundEffect
18+ import net.minecraft.util.SoundEvent
19+ import net.minecraft.util.math.BlockPos
20+ import net.minecraftforge.event.world.NoteBlockEvent
21+ import org.lambda.util.Note
22+ import org.lwjgl.opengl.GL11
23+ import java.util.concurrent.ConcurrentHashMap
24+ import kotlin.math.log2
25+ import kotlin.math.roundToInt
26+
27+ internal object NoteESP: PluginModule(
28+ name = " NoteESP" ,
29+ category = Category .RENDER ,
30+ description = " Shows note block pitch" ,
31+ pluginMain = MusicToolsPlugin
32+ ) {
33+ private val filled by setting(" Filled" , true , description = " Renders surfaces" )
34+ private val outline by setting(" Outline" , true , description = " Renders outline" )
35+ private val alphaFilled by setting(" Alpha Filled" , 26 , 0 .. 255 , 1 , { filled }, description = " Alpha for surfaces" )
36+ private val alphaOutline by setting(" Alpha Outline" , 26 , 0 .. 255 , 1 , { outline }, description = " Alpha for outline" )
37+ private val thickness by setting(" Outline Thickness" , 2f , .25f .. 4f , .25f , { outline })
38+ private val textScale by setting(" Text Scale" , 1f , .0f .. 4f , .25f )
39+ private val reset = setting(" Reset" , false , description = " Resets cached notes" )
40+ private val debug by setting(" Debug" , false , description = " Debug messages in chat" )
41+
42+ private val cachedNotes = ConcurrentHashMap <BlockPos , Note >()
43+ private val renderer = ESPRenderer ()
44+
45+ init {
46+ reset.consumers.add { _, it ->
47+ if (it) {
48+ cachedNotes.clear()
49+ }
50+ false
51+ }
52+
53+ listener<PacketEvent .Receive > { event ->
54+ if (event.packet is SPacketSoundEffect ) {
55+ val packet = (event.packet as SPacketSoundEffect )
56+
57+ val instrument = getInstrument(packet.sound) ? : return @listener
58+ val pos = BlockPos (packet.x, packet.y, packet.z)
59+ val note = Note .values()[(log2(packet.pitch.toDouble()) * 12.0 ).roundToInt() + 12 ]
60+
61+ cachedNotes[pos] = note
62+
63+ if (debug) {
64+ MessageSendHelper .sendChatMessage(" Instrument: ${instrument.name} Pos: (${packet.x} ,${packet.y} ,${packet.z} ) Pitch: ${note.name} " )
65+ }
66+ }
67+ }
68+
69+ listener<RenderWorldEvent > {
70+ renderer.aFilled = if (filled) alphaFilled else 0
71+ renderer.aOutline = if (outline) alphaOutline else 0
72+ renderer.thickness = thickness
73+
74+ cachedNotes.forEach {
75+ renderer.add(it.key, it.value.color)
76+ }
77+
78+ renderer.render(true )
79+ }
80+
81+ listener<RenderOverlayEvent > {
82+ GlStateUtils .rescaleActual()
83+
84+ cachedNotes.forEach {
85+ GL11 .glPushMatrix()
86+
87+ val screenPos = ProjectionUtils .toScreenPos(it.key.toVec3dCenter())
88+
89+ GL11 .glTranslated(screenPos.x, screenPos.y, 0.0 )
90+ GL11 .glScalef(textScale * 2f , textScale * 2f , 1f )
91+
92+ val center = FontRenderAdapter .getStringWidth(it.value.ordinal.toString()) / - 2f
93+ FontRenderAdapter .drawString(it.value.ordinal.toString(), center, 0f , color = it.value.color)
94+
95+ GL11 .glPopMatrix()
96+ }
97+ }
98+ }
99+
100+ private fun getInstrument (soundEvent : SoundEvent ): NoteBlockEvent .Instrument ? {
101+ return when (soundEvent) {
102+ SoundEvents .BLOCK_NOTE_HARP -> NoteBlockEvent .Instrument .PIANO
103+ SoundEvents .BLOCK_NOTE_BASEDRUM -> NoteBlockEvent .Instrument .BASSDRUM
104+ SoundEvents .BLOCK_NOTE_SNARE -> NoteBlockEvent .Instrument .SNARE
105+ SoundEvents .BLOCK_NOTE_HAT -> NoteBlockEvent .Instrument .CLICKS
106+ SoundEvents .BLOCK_NOTE_BASS -> NoteBlockEvent .Instrument .BASSGUITAR
107+ SoundEvents .BLOCK_NOTE_FLUTE -> NoteBlockEvent .Instrument .FLUTE
108+ SoundEvents .BLOCK_NOTE_BELL -> NoteBlockEvent .Instrument .BELL
109+ SoundEvents .BLOCK_NOTE_GUITAR -> NoteBlockEvent .Instrument .GUITAR
110+ SoundEvents .BLOCK_NOTE_CHIME -> NoteBlockEvent .Instrument .CHIME
111+ SoundEvents .BLOCK_NOTE_XYLOPHONE -> NoteBlockEvent .Instrument .XYLOPHONE
112+ else -> null
113+ }
114+ }
115+ }
0 commit comments