From 7d6f9ba1b2bfcc8a5cac6605c9e4f8fd45a4d8b0 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sun, 22 Mar 2026 00:25:10 +0000 Subject: [PATCH 1/9] LightLevels module --- .../lambda/config/groups/WorldLineSettings.kt | 2 +- .../com/lambda/graphics/mc/RenderBuilder.kt | 6 +- .../module/modules/render/LightLevels.kt | 138 ++++++++++++++++++ src/main/kotlin/com/lambda/util/BlockUtils.kt | 1 - .../kotlin/com/lambda/util/math/Vectors.kt | 4 +- 5 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt diff --git a/src/main/kotlin/com/lambda/config/groups/WorldLineSettings.kt b/src/main/kotlin/com/lambda/config/groups/WorldLineSettings.kt index d58f9b20c..54a97eec0 100644 --- a/src/main/kotlin/com/lambda/config/groups/WorldLineSettings.kt +++ b/src/main/kotlin/com/lambda/config/groups/WorldLineSettings.kt @@ -36,7 +36,7 @@ class WorldLineSettings( val distanceScaling by c.setting("${prefix}Distance Scaling", true, "Line width stays constant on screen regardless of distance", visibility = visibility).group(*baseGroup, Group.General).index() val worldWidthSetting by c.setting("${prefix}Width", 5, 1..50, 1) { visibility() && !distanceScaling }.group(*baseGroup, Group.General).index() - val screenWidthSetting by c.setting("${prefix}Screen Width", 10, 1..100, 1, "Line width in screen-space (stays constant size)") { visibility() && distanceScaling }.group(*baseGroup, Group.General).index() + val screenWidthSetting by c.setting("${prefix}Screen Width", 20, 1..100, 1, "Line width in screen-space (stays constant size)") { visibility() && distanceScaling }.group(*baseGroup, Group.General).index() override val width: Float get() = if (distanceScaling) -screenWidthSetting * 0.00005f diff --git a/src/main/kotlin/com/lambda/graphics/mc/RenderBuilder.kt b/src/main/kotlin/com/lambda/graphics/mc/RenderBuilder.kt index 1e7933253..10fa7d9f4 100644 --- a/src/main/kotlin/com/lambda/graphics/mc/RenderBuilder.kt +++ b/src/main/kotlin/com/lambda/graphics/mc/RenderBuilder.kt @@ -134,7 +134,7 @@ class RenderBuilder(private val cameraPos: Vec3d, var depthTest: Boolean = false builder: (BoxBuilder.() -> Unit)? = null ) = boxes(pos, safeContext.blockState(pos), lineConfig, builder) - fun filledQuadGradient( + fun filledQuad( corner1: Vec3d, corner2: Vec3d, corner3: Vec3d, @@ -250,10 +250,10 @@ class RenderBuilder(private val cameraPos: Vec3d, var depthTest: Boolean = false fun circleLine( center: Vec3d, radius: Double, - normal: Vec3d = Vec3d(0.0, 1.0, 0.0), color: Color, - segments: Int = 32, width: Float = -0.0005f, + normal: Vec3d = Vec3d(0.0, 1.0, 0.0), + segments: Int = 32, dashStyle: LineDashStyle? = null ) { val up = diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt new file mode 100644 index 000000000..7e27cad19 --- /dev/null +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -0,0 +1,138 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.module.modules.render + +import com.lambda.config.applyEdits +import com.lambda.config.groups.WorldLineSettings +import com.lambda.context.SafeContext +import com.lambda.graphics.mc.RenderBuilder +import com.lambda.graphics.mc.renderer.ChunkedRenderer.Companion.chunkedRenderer +import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag +import com.lambda.threading.runSafe +import com.lambda.util.BlockUtils.blockState +import com.lambda.util.math.flooredBlockPos +import com.lambda.util.math.setAlpha +import com.lambda.util.math.vec3d +import com.lambda.util.world.toBlockPos +import net.minecraft.registry.tag.BlockTags +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import net.minecraft.world.LightType +import java.awt.Color + +object LightLevels : Module( + name = "LightLevels", + description = "Shows light level. Helpful for mob-proofing areas", + tag = ModuleTag.RENDER +) { + private val mode: Mode by setting("Mode", Mode.Chunked) + .onValueChange { _, _ -> chunkedRenderer.clear(); refreshChunkedRenderer(this) } + private val minLightLevel by setting("Min Light Level", 0, 0..15).onValueChange(::refreshChunkedRenderer) + private val renderMode by setting("Render Mode", RenderMode.Square).onValueChange(::refreshChunkedRenderer) + private val color by setting("Color", Color.RED).onValueChange(::refreshChunkedRenderer) + private val size by setting("Size", 14, 1..16).onValueChange(::refreshChunkedRenderer) + private val fill by setting("Fill", false) { renderMode == RenderMode.Square }.onValueChange(::refreshChunkedRenderer) + private val outline by setting("Outline", true) { renderMode == RenderMode.Square }.onValueChange(::refreshChunkedRenderer) + private val fillAlpha by setting("Fill Alpha", 20, 1..100) { renderMode == RenderMode.Square && fill }.onValueChange(::refreshChunkedRenderer) + private val worldLineConfig = WorldLineSettings(c = this) { renderMode != RenderMode.Square || outline }.apply { + applyEdits { + hide(::startColor, ::endColor) + settings.forEach { it.onValueChange(::refreshChunkedRenderer) } + } + } + private val depthTest by setting("Depth Test", false, "Shows renders through terrain") + private val horizontalRange by setting("Horizontal Range", 8, 1..16) { mode == Mode.Radius } + private val verticalRange by setting("Vertical Range", 4, 1..16) { mode == Mode.Radius } + + private val chunkedRenderer = chunkedRenderer("LightLevels Chunked Renderer", { depthTest }) { _, pos -> + if (mode != Mode.Chunked) return@chunkedRenderer + runSafe { buildRender(pos.toBlockPos()) } + } + + init { + tickedRenderer("LightLevels Ticked Renderer", { depthTest }) { + if (mode != Mode.Radius) return@tickedRenderer + runSafe { + val playerPos = mc.gameRenderer.camera.pos.flooredBlockPos + val x = playerPos.x - horizontalRange + val z = playerPos.z - horizontalRange + val y = playerPos.y - verticalRange + (x..x + (horizontalRange * 2)).forEach { x -> + (z..z + (horizontalRange * 2)).forEach { z -> + (y..z + (verticalRange * 2)).forEach { y -> + buildRender(BlockPos(x, y, z)) + } + } + } + } + } + } + + context(safeContext: SafeContext) + private fun RenderBuilder.buildRender(pos: BlockPos) = with(safeContext) { + if (!hasSpawnPotential(pos)) return@with + + val renderVec = pos.vec3d + val trueSize = (16 - size) / 32.0 + val corner1 = renderVec.add(trueSize, 0.001, trueSize) + val corner2 = renderVec.add(1.0 - trueSize, 0.001, trueSize) + val corner3 = renderVec.add(1.0 - trueSize, 0.001, 1.0 - trueSize) + val corner4 = renderVec.add(trueSize, 0.001, 1.0 - trueSize) + + if (world.getLightLevel(LightType.BLOCK, pos) > minLightLevel) return@with + + val dashStyle = worldLineConfig.getDashStyle() + when(renderMode) { + RenderMode.Square -> { + if (fill) filledQuad(corner1, corner2, corner3, corner4, color.setAlpha(fillAlpha)) + if (outline) polyline(listOf(corner1, corner2, corner3, corner4, corner1), color, worldLineConfig.width, dashStyle) + } + RenderMode.Cross -> { + line(corner1, corner3, color, worldLineConfig.width, dashStyle) + line(corner2, corner4, color, worldLineConfig.width, dashStyle) + } + RenderMode.Circle -> circleLine(renderVec.add(0.5, 0.0, 0.5), (size / 32.0), color, worldLineConfig.width, dashStyle = dashStyle) + } + } + + private fun refreshChunkedRenderer(ctx: SafeContext, from: Any? = null, to: Any? = null) { + if (mode == Mode.Chunked) chunkedRenderer.rebuild() + } + + private fun SafeContext.hasSpawnPotential(pos: BlockPos) = + blockState(pos).let { state -> + !state.isFullCube(world, pos) && + !state.emitsRedstonePower() && + state.fluidState.isEmpty && + !state.isIn(BlockTags.PREVENT_MOB_SPAWNING_INSIDE) && + pos.down().let { blockState(it).isSideSolidFullSquare(world, it, Direction.UP) } + } + + private enum class Mode { + Chunked, + Radius + } + + private enum class RenderMode { + Square, + Cross, + Circle + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/util/BlockUtils.kt b/src/main/kotlin/com/lambda/util/BlockUtils.kt index b33faf352..596091027 100644 --- a/src/main/kotlin/com/lambda/util/BlockUtils.kt +++ b/src/main/kotlin/com/lambda/util/BlockUtils.kt @@ -99,7 +99,6 @@ import net.minecraft.util.math.Vec3d import net.minecraft.util.math.Vec3i object BlockUtils { - val signs = setOf( Blocks.OAK_SIGN, Blocks.BIRCH_SIGN, diff --git a/src/main/kotlin/com/lambda/util/math/Vectors.kt b/src/main/kotlin/com/lambda/util/math/Vectors.kt index 3bdcf1125..1dd9e49d7 100644 --- a/src/main/kotlin/com/lambda/util/math/Vectors.kt +++ b/src/main/kotlin/com/lambda/util/math/Vectors.kt @@ -161,9 +161,7 @@ infix operator fun OpenEndRange.rangeTo(other: Float) = infix operator fun OpenEndRange.rangeTo(other: Int) = BlockPos.Mutable(start, endExclusive, other) /* Vec3i */ -val Vec3i.vec3d - get() = - Vec3d(x.toDouble(), y.toDouble(), z.toDouble()) +val Vec3i.vec3d get() = Vec3d(x.toDouble(), y.toDouble(), z.toDouble()) infix fun Vec3i.dist(other: Vec3d): Double = sqrt(this distSq other) infix fun Vec3i.dist(other: Vec3i): Double = sqrt((this distSq other).toDouble()) From 483ff96434c2bf496b50484f45cc7b86440252ac Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sun, 22 Mar 2026 01:33:46 +0000 Subject: [PATCH 2/9] cleanup --- .../lambda/module/modules/render/LightLevels.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index 7e27cad19..7d48cc86d 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -91,10 +91,10 @@ object LightLevels : Module( val renderVec = pos.vec3d val trueSize = (16 - size) / 32.0 - val corner1 = renderVec.add(trueSize, 0.001, trueSize) - val corner2 = renderVec.add(1.0 - trueSize, 0.001, trueSize) - val corner3 = renderVec.add(1.0 - trueSize, 0.001, 1.0 - trueSize) - val corner4 = renderVec.add(trueSize, 0.001, 1.0 - trueSize) + val corner1 = renderVec.add(trueSize, 0.05, trueSize) + val corner2 = renderVec.add(1.0 - trueSize, 0.05, trueSize) + val corner3 = renderVec.add(1.0 - trueSize, 0.05, 1.0 - trueSize) + val corner4 = renderVec.add(trueSize, 0.05, 1.0 - trueSize) if (world.getLightLevel(LightType.BLOCK, pos) > minLightLevel) return@with @@ -112,10 +112,6 @@ object LightLevels : Module( } } - private fun refreshChunkedRenderer(ctx: SafeContext, from: Any? = null, to: Any? = null) { - if (mode == Mode.Chunked) chunkedRenderer.rebuild() - } - private fun SafeContext.hasSpawnPotential(pos: BlockPos) = blockState(pos).let { state -> !state.isFullCube(world, pos) && @@ -125,6 +121,10 @@ object LightLevels : Module( pos.down().let { blockState(it).isSideSolidFullSquare(world, it, Direction.UP) } } + private fun refreshChunkedRenderer(ctx: SafeContext, from: Any? = null, to: Any? = null) { + if (mode == Mode.Chunked) chunkedRenderer.rebuild() + } + private enum class Mode { Chunked, Radius From 0dfefc0969dadbd9caf967430afdbee02b7264b5 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:16:06 +0000 Subject: [PATCH 3/9] fix chunks not updating when block light changes in chunked mode --- .../mixin/world/ClientChunkManagerMixin.java | 48 ++--- .../graphics/mc/renderer/ChunkedRenderer.kt | 5 + .../module/modules/render/LightLevels.kt | 19 +- src/main/resources/lambda.mixins.json | 198 +++++++++--------- 4 files changed, 133 insertions(+), 137 deletions(-) diff --git a/src/main/java/com/lambda/mixin/world/ClientChunkManagerMixin.java b/src/main/java/com/lambda/mixin/world/ClientChunkManagerMixin.java index 3748e0a82..b9d697d5e 100644 --- a/src/main/java/com/lambda/mixin/world/ClientChunkManagerMixin.java +++ b/src/main/java/com/lambda/mixin/world/ClientChunkManagerMixin.java @@ -19,31 +19,27 @@ import com.lambda.event.EventFlow; import com.lambda.event.events.WorldEvent; +import com.lambda.module.modules.render.LightLevels; +import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.client.world.ClientChunkManager; -import net.minecraft.client.world.ClientWorld; import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.s2c.play.ChunkData; import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.world.Heightmap; +import net.minecraft.world.LightType; import net.minecraft.world.chunk.WorldChunk; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.Map; import java.util.function.Consumer; @Mixin(ClientChunkManager.class) public class ClientChunkManagerMixin { - @Final - @Shadow - ClientWorld world; - @Inject(method = "loadChunkFromPacket", at = @At("TAIL")) private void onChunkLoad( int x, int z, PacketByteBuf buf, Map heightmaps, Consumer consumer, CallbackInfoReturnable cir @@ -51,38 +47,22 @@ private void onChunkLoad( EventFlow.post(new WorldEvent.ChunkEvent.Load(cir.getReturnValue())); } - @Inject(method = "loadChunkFromPacket", at = @At(value = "NEW", target = "net/minecraft/world/chunk/WorldChunk", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD) - private void onChunkUnload(int x, int z, PacketByteBuf buf, Map heightmaps, Consumer consumer, CallbackInfoReturnable cir, int i, WorldChunk chunk, ChunkPos chunkPos) { + @Inject(method = "loadChunkFromPacket", at = @At(value = "NEW", target = "net/minecraft/world/chunk/WorldChunk", shift = At.Shift.BEFORE)) + private void onChunkUnload(int x, int z, PacketByteBuf buf, Map heightmaps, Consumer consumer, CallbackInfoReturnable cir, @Local WorldChunk chunk) { if (chunk != null) { EventFlow.post(new WorldEvent.ChunkEvent.Unload(chunk)); } } - @Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;unloadChunk(ILnet/minecraft/world/chunk/WorldChunk;)V"), locals = LocalCapture.CAPTURE_FAILHARD) - private void onChunkUnload(ChunkPos pos, CallbackInfo ci, int i, WorldChunk chunk) { + @Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;unloadChunk(ILnet/minecraft/world/chunk/WorldChunk;)V")) + private void onChunkUnload(ChunkPos pos, CallbackInfo ci, @Local WorldChunk chunk) { EventFlow.post(new WorldEvent.ChunkEvent.Unload(chunk)); } -// @Inject( -// method = "updateLoadDistance", -// at = @At( -// value = "INVOKE", -// target = "net/minecraft/client/world/ClientChunkManager$ClientChunkMap.isInRadius(II)Z" -// ), -// locals = LocalCapture.CAPTURE_FAILHARD -// ) -// private void onUpdateLoadDistance( -// int loadDistance, -// CallbackInfo ci, -// int oldRadius, -// int newRadius, -// ClientChunkManager.ClientChunkMap clientChunkMap, -// int k, -// WorldChunk oldChunk, -// ChunkPos chunkPos -// ) { -// if (!clientChunkMap.isInRadius(chunkPos.x, chunkPos.z)) { -// EventFlow.post(new WorldEvent.ChunkEvent.Unload(this.world, oldChunk)); -// } -// } + @Inject(method = "onLightUpdate", at = @At("RETURN")) + private void injectOnLightUpdate(LightType type, ChunkSectionPos pos, CallbackInfo ci) { + if (LightLevels.INSTANCE.isEnabled()) { + LightLevels.updateChunk(pos.getX(), pos.getZ()); + } + } } diff --git a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt index 555219ad7..cf557605b 100644 --- a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt +++ b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt @@ -100,6 +100,11 @@ class ChunkedRenderer( private fun getChunkKey(chunkX: Int, chunkZ: Int) = (chunkX.toLong() and 0xFFFFFFFFL) or ((chunkZ.toLong() and 0xFFFFFFFFL) shl 32) + context(safeContext: SafeContext) + fun rebuildChunk(x: Int, z: Int) { + safeContext.world.getChunk(x, z)?.chunkData?.markDirty() + } + fun rebuild() { rebuildQueue.clear() mc.world?.chunkManager?.chunks?.let { chunks -> diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index 7d48cc86d..fe8d81791 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -27,6 +27,7 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState +import com.lambda.util.NamedEnum import com.lambda.util.math.flooredBlockPos import com.lambda.util.math.setAlpha import com.lambda.util.math.vec3d @@ -42,16 +43,21 @@ object LightLevels : Module( description = "Shows light level. Helpful for mob-proofing areas", tag = ModuleTag.RENDER ) { + private enum class Group(override val displayName: String) : NamedEnum { + Fill("Fill"), + Line("Line") + } + private val mode: Mode by setting("Mode", Mode.Chunked) .onValueChange { _, _ -> chunkedRenderer.clear(); refreshChunkedRenderer(this) } private val minLightLevel by setting("Min Light Level", 0, 0..15).onValueChange(::refreshChunkedRenderer) private val renderMode by setting("Render Mode", RenderMode.Square).onValueChange(::refreshChunkedRenderer) private val color by setting("Color", Color.RED).onValueChange(::refreshChunkedRenderer) private val size by setting("Size", 14, 1..16).onValueChange(::refreshChunkedRenderer) - private val fill by setting("Fill", false) { renderMode == RenderMode.Square }.onValueChange(::refreshChunkedRenderer) - private val outline by setting("Outline", true) { renderMode == RenderMode.Square }.onValueChange(::refreshChunkedRenderer) - private val fillAlpha by setting("Fill Alpha", 20, 1..100) { renderMode == RenderMode.Square && fill }.onValueChange(::refreshChunkedRenderer) - private val worldLineConfig = WorldLineSettings(c = this) { renderMode != RenderMode.Square || outline }.apply { + private val fill by setting("Fill", false) { renderMode == RenderMode.Square }.group(Group.Fill).onValueChange(::refreshChunkedRenderer) + private val fillAlpha by setting("Fill Alpha", 20, 1..100) { renderMode == RenderMode.Square && fill }.group(Group.Fill).onValueChange(::refreshChunkedRenderer) + private val outline by setting("Outline", true) { renderMode == RenderMode.Square }.group(Group.Line).onValueChange(::refreshChunkedRenderer) + private val worldLineConfig = WorldLineSettings(c = this, baseGroup = arrayOf(Group.Line)) { renderMode != RenderMode.Square || outline }.apply { applyEdits { hide(::startColor, ::endColor) settings.forEach { it.onValueChange(::refreshChunkedRenderer) } @@ -121,6 +127,11 @@ object LightLevels : Module( pos.down().let { blockState(it).isSideSolidFullSquare(world, it, Direction.UP) } } + @JvmStatic + fun updateChunk(x: Int, z: Int) = runSafe { + if (mode == Mode.Chunked) chunkedRenderer.rebuildChunk(x, z) + } + private fun refreshChunkedRenderer(ctx: SafeContext, from: Any? = null, to: Any? = null) { if (mode == Mode.Chunked) chunkedRenderer.rebuild() } diff --git a/src/main/resources/lambda.mixins.json b/src/main/resources/lambda.mixins.json index 0b0415225..afe6ff5c5 100644 --- a/src/main/resources/lambda.mixins.json +++ b/src/main/resources/lambda.mixins.json @@ -1,101 +1,101 @@ { - "required": true, - "minVersion": "0.8", - "package": "com.lambda.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "CrashReportMixin", - "MinecraftClientMixin", - "baritone.BaritonePlayerContextMixin", - "baritone.LookBehaviourMixin", - "client.sound.SoundSystemMixin", - "entity.ClientPlayerEntityMixin", - "entity.ClientPlayInteractionManagerMixin", - "entity.EntityMixin", - "entity.FireworkRocketEntityMixin", - "entity.HandledScreensMixin", - "entity.LivingEntityMixin", - "entity.PlayerEntityMixin", - "entity.PlayerInventoryMixin", - "input.KeyBindingMixin", - "input.KeyboardMixin", - "input.MouseMixin", - "items.BlockItemMixin", - "items.FilledMapItemMixin", - "network.ClientConnectionMixin", - "network.ClientLoginNetworkMixin", - "network.ClientPlayNetworkHandlerMixin", - "network.HandshakeC2SPacketMixin", - "network.LoginHelloC2SPacketMixin", - "network.LoginKeyC2SPacketMixin", - "render.AbstractTerrainRenderContextMixin", - "render.ArmorFeatureRendererMixin", - "render.BlockMixin", - "render.BlockModelRendererMixin", - "render.BossBarHudMixin", - "render.CameraMixin", - "render.CapeFeatureRendererMixin", - "render.ChatHudMixin", - "render.ChatInputSuggestorMixin", - "render.ChatScreenMixin", - "render.ChunkOcclusionDataBuilderMixin", - "render.DrawContextMixin", - "render.ElytraFeatureRendererMixin", - "render.EntityRendererMixin", - "render.EntityRenderManagerMixin", - "render.ItemFrameEntityRendererMixin", - "render.EntityRenderStateMixin", - "render.BlockEntityRendererMixin", - "render.BlockEntityRenderManagerMixin", - "render.FluidRendererMixin", - "render.FogRendererMixin", - "render.GameRendererMixin", - "render.HandledScreenMixin", - "render.HeadFeatureRendererMixin", - "render.HeldItemRendererMixin", - "render.InGameHudMixin", - "render.InGameOverlayRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.PlayerListHudMixin", - "render.RenderLayersMixin", - "render.ScreenHandlerMixin", - "render.ScreenMixin", - "render.SodiumBlockOcclusionCacheMixin", - "render.SodiumBlockRendererMixin", - "render.SodiumFluidRendererImplMixin", - "render.SodiumLightDataAccessMixin", - "render.SodiumWorldRendererMixin", - "render.SplashOverlayMixin", - "render.SplashOverlayMixin$LogoTextureMixin", - "render.StatusEffectFogModifierMixin", - "render.TooltipComponentMixin", - "render.WeatherRenderingMixin", - "render.WorldBorderRenderingMixin", - "render.WorldRendererMixin", - "render.blockentity.AbstractSignBlockEntityRendererMixin", - "render.blockentity.BeaconBlockEntityRendererMixin", - "render.blockentity.BlockEntityRenderDispatcherMixin", - "render.blockentity.EnchantingTableBlockEntityRendererMixin", - "render.blockentity.MobSpawnerBlockEntityRendererMixin", - "render.particle.BillboardParticleMixin", - "render.particle.ElderGuardianParticleRendererMixin", - "render.particle.ItemPickupParticleRendererMixin", - "world.AbstractBlockMixin", - "world.BlockCollisionSpliteratorMixin", - "world.ClientChunkManagerMixin", - "world.ClientWorldMixin", - "world.DirectionMixin", - "world.StructureTemplateMixin", - "world.WorldMixin" - ], - "injectors": { - "defaultRequire": 0 - }, - "overwrites": { - "conformVisibility": true - }, - "mixinextras": { - "minVersion": "0.5.0" - } + "required": true, + "minVersion": "0.8", + "package": "com.lambda.mixin", + "compatibilityLevel": "JAVA_21", + "client": [ + "CrashReportMixin", + "MinecraftClientMixin", + "baritone.BaritonePlayerContextMixin", + "baritone.LookBehaviourMixin", + "client.sound.SoundSystemMixin", + "entity.ClientPlayerEntityMixin", + "entity.ClientPlayInteractionManagerMixin", + "entity.EntityMixin", + "entity.FireworkRocketEntityMixin", + "entity.HandledScreensMixin", + "entity.LivingEntityMixin", + "entity.PlayerEntityMixin", + "entity.PlayerInventoryMixin", + "input.KeyBindingMixin", + "input.KeyboardMixin", + "input.MouseMixin", + "items.BlockItemMixin", + "items.FilledMapItemMixin", + "network.ClientConnectionMixin", + "network.ClientLoginNetworkMixin", + "network.ClientPlayNetworkHandlerMixin", + "network.HandshakeC2SPacketMixin", + "network.LoginHelloC2SPacketMixin", + "network.LoginKeyC2SPacketMixin", + "render.AbstractTerrainRenderContextMixin", + "render.ArmorFeatureRendererMixin", + "render.BlockEntityRendererMixin", + "render.BlockEntityRenderManagerMixin", + "render.BlockMixin", + "render.BlockModelRendererMixin", + "render.BossBarHudMixin", + "render.CameraMixin", + "render.CapeFeatureRendererMixin", + "render.ChatHudMixin", + "render.ChatInputSuggestorMixin", + "render.ChatScreenMixin", + "render.ChunkOcclusionDataBuilderMixin", + "render.DrawContextMixin", + "render.ElytraFeatureRendererMixin", + "render.EntityRendererMixin", + "render.EntityRenderManagerMixin", + "render.EntityRenderStateMixin", + "render.FluidRendererMixin", + "render.FogRendererMixin", + "render.GameRendererMixin", + "render.HandledScreenMixin", + "render.HeadFeatureRendererMixin", + "render.HeldItemRendererMixin", + "render.InGameHudMixin", + "render.InGameOverlayRendererMixin", + "render.ItemFrameEntityRendererMixin", + "render.LightmapTextureManagerMixin", + "render.LivingEntityRendererMixin", + "render.PlayerListHudMixin", + "render.RenderLayersMixin", + "render.ScreenHandlerMixin", + "render.ScreenMixin", + "render.SodiumBlockOcclusionCacheMixin", + "render.SodiumBlockRendererMixin", + "render.SodiumFluidRendererImplMixin", + "render.SodiumLightDataAccessMixin", + "render.SodiumWorldRendererMixin", + "render.SplashOverlayMixin", + "render.SplashOverlayMixin$LogoTextureMixin", + "render.StatusEffectFogModifierMixin", + "render.TooltipComponentMixin", + "render.WeatherRenderingMixin", + "render.WorldBorderRenderingMixin", + "render.WorldRendererMixin", + "render.blockentity.AbstractSignBlockEntityRendererMixin", + "render.blockentity.BeaconBlockEntityRendererMixin", + "render.blockentity.BlockEntityRenderDispatcherMixin", + "render.blockentity.EnchantingTableBlockEntityRendererMixin", + "render.blockentity.MobSpawnerBlockEntityRendererMixin", + "render.particle.BillboardParticleMixin", + "render.particle.ElderGuardianParticleRendererMixin", + "render.particle.ItemPickupParticleRendererMixin", + "world.AbstractBlockMixin", + "world.BlockCollisionSpliteratorMixin", + "world.ClientChunkManagerMixin", + "world.ClientWorldMixin", + "world.DirectionMixin", + "world.StructureTemplateMixin", + "world.WorldMixin" + ], + "injectors": { + "defaultRequire": 0 + }, + "overwrites": { + "conformVisibility": true + }, + "mixinextras": { + "minVersion": "0.5.0" + } } \ No newline at end of file From 19456e59c557d3e9e4890839aa81d9d8321131c2 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:00:09 +0000 Subject: [PATCH 4/9] more accurate spawn potential checks --- .../com/lambda/module/modules/render/LightLevels.kt | 11 +++++++++-- src/main/resources/lambda.accesswidener | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index fe8d81791..7407a74ff 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -32,6 +32,8 @@ import com.lambda.util.math.flooredBlockPos import com.lambda.util.math.setAlpha import com.lambda.util.math.vec3d import com.lambda.util.world.toBlockPos +import net.minecraft.block.Blocks +import net.minecraft.block.SnowBlock import net.minecraft.registry.tag.BlockTags import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction @@ -120,11 +122,16 @@ object LightLevels : Module( private fun SafeContext.hasSpawnPotential(pos: BlockPos) = blockState(pos).let { state -> - !state.isFullCube(world, pos) && + (!state.block.collidable || (state.block === Blocks.SNOW && state.get(SnowBlock.LAYERS) <= 1)) && !state.emitsRedstonePower() && state.fluidState.isEmpty && !state.isIn(BlockTags.PREVENT_MOB_SPAWNING_INSIDE) && - pos.down().let { blockState(it).isSideSolidFullSquare(world, it, Direction.UP) } + pos.down().let { + val underState = blockState(it) + underState.isSideSolidFullSquare(world, it, Direction.UP) && + !underState.isTransparent && + underState.block !== Blocks.BEDROCK + } } @JvmStatic diff --git a/src/main/resources/lambda.accesswidener b/src/main/resources/lambda.accesswidener index ad63e9eda..0c7cc468a 100644 --- a/src/main/resources/lambda.accesswidener +++ b/src/main/resources/lambda.accesswidener @@ -33,8 +33,9 @@ transitive-accessible field net/minecraft/entity/Entity GLIDING_FLAG_INDEX I transitive-accessible method net/minecraft/entity/Entity getFlag (I)Z transitive-accessible method net/minecraft/block/ChestBlock getChestType (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Lnet/minecraft/block/enums/ChestType; transitive-accessible method net/minecraft/block/ChestBlock getNeighborChestDirection (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Lnet/minecraft/util/math/Direction; -accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap loadedChunkCount I -accessible field net/minecraft/block/TrapdoorBlock blockSetType Lnet/minecraft/block/BlockSetType; +transitive-accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap loadedChunkCount I +transitive-accessible field net/minecraft/block/TrapdoorBlock blockSetType Lnet/minecraft/block/BlockSetType; +transitive-accessible field net/minecraft/block/AbstractBlock collidable Z # Entity transitive-accessible field net/minecraft/entity/projectile/FireworkRocketEntity shooter Lnet/minecraft/entity/LivingEntity; From 4a510eca73462dbcbda2cddfb0bfc195883c5a03 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:07:00 +0000 Subject: [PATCH 5/9] fixed chunked renderer rebuilding --- .../graphics/mc/renderer/ChunkedRenderer.kt | 6 ++-- .../com/lambda/module/modules/render/ESP.kt | 2 +- .../module/modules/render/LightLevels.kt | 30 ++++++++----------- src/main/resources/lambda.accesswidener | 1 - 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt index cf557605b..ed942a4f0 100644 --- a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt +++ b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt @@ -108,10 +108,10 @@ class ChunkedRenderer( fun rebuild() { rebuildQueue.clear() mc.world?.chunkManager?.chunks?.let { chunks -> - val chunkCount = chunks.loadedChunkCount - (0..chunkCount).forEach { index -> + val chunkCount = chunks.chunks.length() + (0 until chunkCount).forEach { index -> val chunk = chunks.chunks.get(index) ?: return@forEach - chunkMap.putIfAbsent(chunk.chunkKey, chunk.chunkData) + chunkMap.putIfAbsent(chunk.chunkKey, ChunkData(chunk)) } } rebuildQueue.addAll(chunkMap.values) diff --git a/src/main/kotlin/com/lambda/module/modules/render/ESP.kt b/src/main/kotlin/com/lambda/module/modules/render/ESP.kt index 35f261ca7..ebf682c5f 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ESP.kt @@ -82,7 +82,7 @@ object ESP : Module( ) } val chunkMap = world.chunkManager.chunks - (0 until chunkMap.loadedChunkCount).forEach { chunk -> + (0 until chunkMap.chunks.length()).forEach { chunk -> chunkMap.chunks.get(chunk)?.blockEntities?.values?.forEach { blockEntity -> if (!entitySettings.isSelected(blockEntity)) return@forEach val color = entityColors.getColor(blockEntity) diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index 7407a74ff..3ecc8ac26 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -17,6 +17,7 @@ package com.lambda.module.modules.render +import com.lambda.Lambda.mc import com.lambda.config.applyEdits import com.lambda.config.groups.WorldLineSettings import com.lambda.context.SafeContext @@ -66,8 +67,8 @@ object LightLevels : Module( } } private val depthTest by setting("Depth Test", false, "Shows renders through terrain") - private val horizontalRange by setting("Horizontal Range", 8, 1..16) { mode == Mode.Radius } - private val verticalRange by setting("Vertical Range", 4, 1..16) { mode == Mode.Radius } + private val horizontalRange by setting("Horizontal Range", 16, 1..32) { mode == Mode.Radius } + private val verticalRange by setting("Vertical Range", 8, 1..32) { mode == Mode.Radius } private val chunkedRenderer = chunkedRenderer("LightLevels Chunked Renderer", { depthTest }) { _, pos -> if (mode != Mode.Chunked) return@chunkedRenderer @@ -75,18 +76,14 @@ object LightLevels : Module( } init { - tickedRenderer("LightLevels Ticked Renderer", { depthTest }) { + tickedRenderer("LightLevels Ticked Renderer", { depthTest }) { safeContext -> if (mode != Mode.Radius) return@tickedRenderer - runSafe { - val playerPos = mc.gameRenderer.camera.pos.flooredBlockPos - val x = playerPos.x - horizontalRange - val z = playerPos.z - horizontalRange - val y = playerPos.y - verticalRange - (x..x + (horizontalRange * 2)).forEach { x -> - (z..z + (horizontalRange * 2)).forEach { z -> - (y..z + (verticalRange * 2)).forEach { y -> - buildRender(BlockPos(x, y, z)) - } + val playerPos = mc.gameRenderer.camera.pos.flooredBlockPos + + (playerPos.x - horizontalRange..playerPos.x + horizontalRange).forEach { x -> + (playerPos.z - horizontalRange..playerPos.z + horizontalRange).forEach { z -> + (playerPos.y - verticalRange..playerPos.y + verticalRange).forEach { y -> + with(safeContext) { buildRender(BlockPos(x, y, z)) } } } } @@ -94,8 +91,9 @@ object LightLevels : Module( } context(safeContext: SafeContext) - private fun RenderBuilder.buildRender(pos: BlockPos) = with(safeContext) { - if (!hasSpawnPotential(pos)) return@with + private fun RenderBuilder.buildRender(pos: BlockPos) { + val level = safeContext.world.getLightLevel(LightType.BLOCK, pos) + if (level > minLightLevel || !safeContext.hasSpawnPotential(pos)) return val renderVec = pos.vec3d val trueSize = (16 - size) / 32.0 @@ -104,8 +102,6 @@ object LightLevels : Module( val corner3 = renderVec.add(1.0 - trueSize, 0.05, 1.0 - trueSize) val corner4 = renderVec.add(trueSize, 0.05, 1.0 - trueSize) - if (world.getLightLevel(LightType.BLOCK, pos) > minLightLevel) return@with - val dashStyle = worldLineConfig.getDashStyle() when(renderMode) { RenderMode.Square -> { diff --git a/src/main/resources/lambda.accesswidener b/src/main/resources/lambda.accesswidener index 0c7cc468a..603e9e5c6 100644 --- a/src/main/resources/lambda.accesswidener +++ b/src/main/resources/lambda.accesswidener @@ -33,7 +33,6 @@ transitive-accessible field net/minecraft/entity/Entity GLIDING_FLAG_INDEX I transitive-accessible method net/minecraft/entity/Entity getFlag (I)Z transitive-accessible method net/minecraft/block/ChestBlock getChestType (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Lnet/minecraft/block/enums/ChestType; transitive-accessible method net/minecraft/block/ChestBlock getNeighborChestDirection (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Lnet/minecraft/util/math/Direction; -transitive-accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap loadedChunkCount I transitive-accessible field net/minecraft/block/TrapdoorBlock blockSetType Lnet/minecraft/block/BlockSetType; transitive-accessible field net/minecraft/block/AbstractBlock collidable Z From 1c4985987b4ee65b98c3e9da4688a9e37bb34460 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:18:47 +0000 Subject: [PATCH 6/9] value for pausing chunk updates in ChunkedRenderer --- .../com/lambda/graphics/mc/renderer/ChunkedRenderer.kt | 7 +++++-- src/main/kotlin/com/lambda/module/modules/render/ESP.kt | 6 +++--- .../com/lambda/module/modules/render/LightLevels.kt | 2 +- .../kotlin/com/lambda/module/modules/render/Search.kt | 8 ++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt index ed942a4f0..302266e87 100644 --- a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt +++ b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt @@ -47,6 +47,7 @@ class ChunkedRenderer( owner: Any, name: String, depthTest: SafeContext.() -> Boolean, + private val pauseUpdates: SafeContext.() -> Boolean, private val update: RenderBuilder.(ClientWorld, FastVector) -> Unit ) : AbstractRenderer(name, depthTest) { private val chunkMap = ConcurrentHashMap() @@ -82,9 +83,10 @@ class ChunkedRenderer( owner.listen { rebuild() } owner.listenConcurrently { - val depth = depthTest() + if (pauseUpdates()) return@listenConcurrently val queueSize = rebuildQueue.size val polls = minOf(StyleEditor.rebuildsPerTick, queueSize) + val depth = depthTest() repeat(polls) { rebuildQueue.poll()?.rebuild(depth) } } @@ -187,8 +189,9 @@ class ChunkedRenderer( fun Any.chunkedRenderer( name: String, depthTest: SafeContext.() -> Boolean = { false }, + pauseUpdates: SafeContext.() -> Boolean = { false }, update: RenderBuilder.(ClientWorld, FastVector) -> Unit - ) = ChunkedRenderer(this, name, depthTest, update).also { renderer -> + ) = ChunkedRenderer(this, name, depthTest, pauseUpdates, update).also { renderer -> (this as? Module)?.let { module -> module.onEnable { renderer.rebuild() } module.onDisable { renderer.rebuild() } diff --git a/src/main/kotlin/com/lambda/module/modules/render/ESP.kt b/src/main/kotlin/com/lambda/module/modules/render/ESP.kt index ebf682c5f..9a1301518 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ESP.kt @@ -81,9 +81,9 @@ object ESP : Module( { listOf(it.interpolatedBox) } ) } - val chunkMap = world.chunkManager.chunks - (0 until chunkMap.chunks.length()).forEach { chunk -> - chunkMap.chunks.get(chunk)?.blockEntities?.values?.forEach { blockEntity -> + val chunks = world.chunkManager.chunks.chunks + (0 until chunks.length()).forEach { chunk -> + chunks.get(chunk)?.blockEntities?.values?.forEach { blockEntity -> if (!entitySettings.isSelected(blockEntity)) return@forEach val color = entityColors.getColor(blockEntity) drawEsp( diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index 3ecc8ac26..dee7a0184 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -70,7 +70,7 @@ object LightLevels : Module( private val horizontalRange by setting("Horizontal Range", 16, 1..32) { mode == Mode.Radius } private val verticalRange by setting("Vertical Range", 8, 1..32) { mode == Mode.Radius } - private val chunkedRenderer = chunkedRenderer("LightLevels Chunked Renderer", { depthTest }) { _, pos -> + private val chunkedRenderer = chunkedRenderer("LightLevels Chunked Renderer", { depthTest }, { mode != Mode.Chunked }) { _, pos -> if (mode != Mode.Chunked) return@chunkedRenderer runSafe { buildRender(pos.toBlockPos()) } } diff --git a/src/main/kotlin/com/lambda/module/modules/render/Search.kt b/src/main/kotlin/com/lambda/module/modules/render/Search.kt index 47f01fa08..c223de198 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Search.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Search.kt @@ -25,7 +25,6 @@ import com.lambda.config.settings.collections.CollectionSetting.Companion.onSele import com.lambda.context.SafeContext import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.graphics.RenderMain import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.mc.renderer.ChunkedRenderer.Companion.chunkedRenderer import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer @@ -44,7 +43,6 @@ import com.lambda.util.extension.getBlockState import com.lambda.util.math.setAlpha import com.lambda.util.world.toBlockPos import io.ktor.util.collections.ConcurrentMap -import net.fabricmc.fabric.mixin.block.BlockStateMixin import net.minecraft.block.BlockState import net.minecraft.block.Blocks import net.minecraft.entity.Entity @@ -63,8 +61,10 @@ object Search : Module( private val entities by setting("Entities", decorationEntityMap.values) .onSelect { rebuildMesh(this) }.onDeselect { rebuildMesh(this) } - private var fill: Boolean by setting("Fill", true, "Fill the faces of blocks").onValueChange(::rebuildMesh).onValueChange { _, to -> if (!to) outline = true } - private var outline: Boolean by setting("Outline", true, "Draw the outlines of blocks").onValueChange(::rebuildMesh).onValueChange { _, to -> if (!to) fill = true } + private var fill: Boolean by setting("Fill", true, "Fill the faces of blocks").onValueChange(::rebuildMesh) + .onValueChange { _, to -> if (!to) outline = true } + private var outline: Boolean by setting("Outline", true, "Draw the outlines of blocks").onValueChange(::rebuildMesh) + .onValueChange { _, to -> if (!to) fill = true } private val tracers by setting("Tracers", true, "Draw a line from your cursor to the highlighted position") private val mesh by setting("Mesh", true, "Connect similar adjacent blocks").onValueChange(::rebuildMesh) From 3b0015bb8ee8b41087d2efc8543a7eea8b6a19d4 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:10:55 +0000 Subject: [PATCH 7/9] cleanup --- .../lambda/graphics/mc/renderer/ChunkedRenderer.kt | 4 ++-- .../com/lambda/module/modules/render/LightLevels.kt | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt index 302266e87..3cae90e96 100644 --- a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt +++ b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt @@ -47,7 +47,7 @@ class ChunkedRenderer( owner: Any, name: String, depthTest: SafeContext.() -> Boolean, - private val pauseUpdates: SafeContext.() -> Boolean, + pauseUpdates: SafeContext.() -> Boolean, private val update: RenderBuilder.(ClientWorld, FastVector) -> Unit ) : AbstractRenderer(name, depthTest) { private val chunkMap = ConcurrentHashMap() @@ -194,7 +194,7 @@ class ChunkedRenderer( ) = ChunkedRenderer(this, name, depthTest, pauseUpdates, update).also { renderer -> (this as? Module)?.let { module -> module.onEnable { renderer.rebuild() } - module.onDisable { renderer.rebuild() } + module.onDisable { renderer.clear() } } } } diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index dee7a0184..94e1cf9df 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -21,6 +21,7 @@ import com.lambda.Lambda.mc import com.lambda.config.applyEdits import com.lambda.config.groups.WorldLineSettings import com.lambda.context.SafeContext +import com.lambda.graphics.mc.LineDashStyle import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.mc.renderer.ChunkedRenderer.Companion.chunkedRenderer import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer @@ -58,7 +59,7 @@ object LightLevels : Module( private val color by setting("Color", Color.RED).onValueChange(::refreshChunkedRenderer) private val size by setting("Size", 14, 1..16).onValueChange(::refreshChunkedRenderer) private val fill by setting("Fill", false) { renderMode == RenderMode.Square }.group(Group.Fill).onValueChange(::refreshChunkedRenderer) - private val fillAlpha by setting("Fill Alpha", 20, 1..100) { renderMode == RenderMode.Square && fill }.group(Group.Fill).onValueChange(::refreshChunkedRenderer) + private val fillAlpha by setting("Fill Alpha", 0.2, 0.0..1.0, 0.01) { renderMode == RenderMode.Square && fill }.group(Group.Fill).onValueChange(::refreshChunkedRenderer) private val outline by setting("Outline", true) { renderMode == RenderMode.Square }.group(Group.Line).onValueChange(::refreshChunkedRenderer) private val worldLineConfig = WorldLineSettings(c = this, baseGroup = arrayOf(Group.Line)) { renderMode != RenderMode.Square || outline }.apply { applyEdits { @@ -71,8 +72,7 @@ object LightLevels : Module( private val verticalRange by setting("Vertical Range", 8, 1..32) { mode == Mode.Radius } private val chunkedRenderer = chunkedRenderer("LightLevels Chunked Renderer", { depthTest }, { mode != Mode.Chunked }) { _, pos -> - if (mode != Mode.Chunked) return@chunkedRenderer - runSafe { buildRender(pos.toBlockPos()) } + runSafe { buildRender(pos.toBlockPos(), worldLineConfig.getDashStyle()) } } init { @@ -80,10 +80,11 @@ object LightLevels : Module( if (mode != Mode.Radius) return@tickedRenderer val playerPos = mc.gameRenderer.camera.pos.flooredBlockPos + val dashStyle = worldLineConfig.getDashStyle() (playerPos.x - horizontalRange..playerPos.x + horizontalRange).forEach { x -> (playerPos.z - horizontalRange..playerPos.z + horizontalRange).forEach { z -> (playerPos.y - verticalRange..playerPos.y + verticalRange).forEach { y -> - with(safeContext) { buildRender(BlockPos(x, y, z)) } + with(safeContext) { buildRender(BlockPos(x, y, z), dashStyle) } } } } @@ -91,7 +92,7 @@ object LightLevels : Module( } context(safeContext: SafeContext) - private fun RenderBuilder.buildRender(pos: BlockPos) { + private fun RenderBuilder.buildRender(pos: BlockPos, dashStyle: LineDashStyle?) { val level = safeContext.world.getLightLevel(LightType.BLOCK, pos) if (level > minLightLevel || !safeContext.hasSpawnPotential(pos)) return @@ -102,7 +103,6 @@ object LightLevels : Module( val corner3 = renderVec.add(1.0 - trueSize, 0.05, 1.0 - trueSize) val corner4 = renderVec.add(trueSize, 0.05, 1.0 - trueSize) - val dashStyle = worldLineConfig.getDashStyle() when(renderMode) { RenderMode.Square -> { if (fill) filledQuad(corner1, corner2, corner3, corner4, color.setAlpha(fillAlpha)) From 80c43c86928d14ce31b3aa04833fb6f31efd3ad8 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:26:15 +0000 Subject: [PATCH 8/9] fix buffers not being closed when clearing ticked and chunked renderers --- .../kotlin/com/lambda/graphics/mc/RegionRenderer.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/mc/RegionRenderer.kt b/src/main/kotlin/com/lambda/graphics/mc/RegionRenderer.kt index 715a508d2..b71010199 100644 --- a/src/main/kotlin/com/lambda/graphics/mc/RegionRenderer.kt +++ b/src/main/kotlin/com/lambda/graphics/mc/RegionRenderer.kt @@ -381,17 +381,17 @@ class RegionRenderer { fun hasScreenData(): Boolean = hasScreenData fun clearData() { - faceVertexBuffer = null - edgeVertexBuffer = null - textVertexBuffer = null + faceVertexBuffer?.close(); faceVertexBuffer = null + edgeVertexBuffer?.close(); edgeVertexBuffer = null + textVertexBuffer?.close(); textVertexBuffer = null faceIndexCount = 0 edgeIndexCount = 0 textIndexCount = 0 hasWorldData = false - screenFaceVertexBuffer = null - screenEdgeVertexBuffer = null - screenTextVertexBuffer = null + screenFaceVertexBuffer?.close(); screenFaceVertexBuffer = null + screenEdgeVertexBuffer?.close(); screenEdgeVertexBuffer = null + screenTextVertexBuffer?.close(); screenTextVertexBuffer = null screenFaceIndexCount = 0 screenEdgeIndexCount = 0 screenTextIndexCount = 0 From 813c85dd40c83c5f305a9f54840cf8c5395ecd7d Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Mon, 23 Mar 2026 17:10:00 +0000 Subject: [PATCH 9/9] cleanup --- .../com/lambda/mixin/render/BlockEntityRenderManagerMixin.java | 2 +- src/main/kotlin/com/lambda/config/groups/EntityColorsConfig.kt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/lambda/mixin/render/BlockEntityRenderManagerMixin.java b/src/main/java/com/lambda/mixin/render/BlockEntityRenderManagerMixin.java index c43b8923b..d67129b26 100644 --- a/src/main/java/com/lambda/mixin/render/BlockEntityRenderManagerMixin.java +++ b/src/main/java/com/lambda/mixin/render/BlockEntityRenderManagerMixin.java @@ -42,7 +42,7 @@ private void wrapRenderQueue(BlockEntityRende Operation original) { BlockPos pos = renderState.pos; - if (pos != null && OutlineManager.INSTANCE.shouldCapture(pos)) { + if (pos != null && OutlineManager.shouldCapture(pos)) { VertexCapture.INSTANCE.beginCapture(pos); boolean outlineOnly = !Vec3d.ofCenter(pos).isInRange(cameraState.pos, renderer.getRenderDistance()); diff --git a/src/main/kotlin/com/lambda/config/groups/EntityColorsConfig.kt b/src/main/kotlin/com/lambda/config/groups/EntityColorsConfig.kt index 4f4ce0fb7..02f2a9117 100644 --- a/src/main/kotlin/com/lambda/config/groups/EntityColorsConfig.kt +++ b/src/main/kotlin/com/lambda/config/groups/EntityColorsConfig.kt @@ -17,7 +17,6 @@ package com.lambda.config.groups -import com.lambda.module.modules.render.ESP.Group import java.awt.Color interface EntityColorsConfig {