diff --git a/src/main/kotlin/com/lambda/event/events/RenderEvent.kt b/src/main/kotlin/com/lambda/event/events/RenderEvent.kt index de8dbc6e8..812979bfa 100644 --- a/src/main/kotlin/com/lambda/event/events/RenderEvent.kt +++ b/src/main/kotlin/com/lambda/event/events/RenderEvent.kt @@ -17,22 +17,22 @@ package com.lambda.event.events +import com.lambda.context.SafeContext import com.lambda.event.Event import com.lambda.event.callback.Cancellable import com.lambda.event.callback.ICancellable -import com.lambda.graphics.renderer.esp.global.DynamicESP -import com.lambda.graphics.renderer.esp.global.StaticESP +import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.graphics.renderer.esp.ShapeBuilder +import com.lambda.graphics.renderer.esp.Treed -sealed class RenderEvent { - class World : Event - - class StaticESP : Event { - val renderer = StaticESP - } +fun Any.onStaticRender(block: SafeContext.(ShapeBuilder) -> Unit) = + listen { block(ShapeBuilder(Treed.Static.faceBuilder, Treed.Static.edgeBuilder)) } +fun Any.onDynamicRender(block: SafeContext.(ShapeBuilder) -> Unit) = + listen { block(ShapeBuilder(Treed.Dynamic.faceBuilder, Treed.Dynamic.edgeBuilder)) } - class DynamicESP : Event { - val renderer = DynamicESP - } +sealed class RenderEvent { + object Upload : Event + object Render : Event class UpdateTarget : ICancellable by Cancellable() } diff --git a/src/main/kotlin/com/lambda/graphics/RenderMain.kt b/src/main/kotlin/com/lambda/graphics/RenderMain.kt index 1d3b5b20b..3668298f2 100644 --- a/src/main/kotlin/com/lambda/graphics/RenderMain.kt +++ b/src/main/kotlin/com/lambda/graphics/RenderMain.kt @@ -25,8 +25,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.gl.GlStateUtils.setupGL import com.lambda.graphics.gl.Matrices import com.lambda.graphics.gl.Matrices.resetMatrices -import com.lambda.graphics.renderer.esp.global.DynamicESP -import com.lambda.graphics.renderer.esp.global.StaticESP +import com.lambda.graphics.renderer.esp.Treed import com.lambda.util.math.Vec2d import com.mojang.blaze3d.opengl.GlStateManager import com.mojang.blaze3d.systems.RenderSystem @@ -56,21 +55,22 @@ object RenderMain { GlStateManager._glBindFramebuffer(GL_FRAMEBUFFER, prevFramebuffer) - RenderEvent.World().post() - StaticESP.render() - DynamicESP.render() + Treed.Static.render() + Treed.Dynamic.render() + + RenderEvent.Render.post() } } init { listen { - StaticESP.clear() - RenderEvent.StaticESP().post() - StaticESP.upload() + Treed.Static.clear() + Treed.Dynamic.clear() + + RenderEvent.Upload.post() - DynamicESP.clear() - RenderEvent.DynamicESP().post() - DynamicESP.upload() + Treed.Static.upload() + Treed.Dynamic.upload() } } } diff --git a/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt b/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt index 02ec17360..9ee396552 100644 --- a/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt +++ b/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt @@ -150,8 +150,8 @@ class DynamicByteBuffer private constructor(initialCapacity: Int) { val offset = position - pointer memCopy(pointer, newPointer, offset) - data = newBuffer + data = newBuffer pointer = newPointer position = newPointer + offset capacity = newCapacity @@ -176,6 +176,13 @@ class DynamicByteBuffer private constructor(initialCapacity: Int) { capacity = newCapacity } + /** + * Returns the relative index of the first mismatch between this and the given buffer, otherwise -1 if no mismatch. + * + * @see [ByteBuffer.mismatch] + */ + fun mismatch(other: DynamicByteBuffer) = data.mismatch(other.data) + companion object { /** * Creates a new DynamicByteBuffer with specified initial capacity @@ -184,4 +191,4 @@ class DynamicByteBuffer private constructor(initialCapacity: Int) { fun dynamicByteBuffer(initialCapacity: Int) = DynamicByteBuffer(initialCapacity) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt b/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt index 351e6ee0a..44ce5014e 100644 --- a/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt +++ b/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt @@ -18,10 +18,8 @@ package com.lambda.graphics.pipeline import com.lambda.graphics.buffer.Buffer.Companion.createPipelineBuffer -import com.lambda.graphics.buffer.DynamicByteBuffer import com.lambda.graphics.buffer.DynamicByteBuffer.Companion.dynamicByteBuffer import com.lambda.graphics.gl.kibibyte -import org.lwjgl.system.MemoryUtil import org.lwjgl.system.MemoryUtil.memCopy /** @@ -64,7 +62,7 @@ class PersistentBuffer( } if (snapshotData > 0 && snapshot.capacity >= byteBuffer.bytesPut) { - if (memcmp(snapshot, byteBuffer, uploadOffset, dataCount)) return + if (snapshot.mismatch(byteBuffer) >= 0) return } glBuffer.update(uploadOffset, dataCount, dataStart) @@ -90,30 +88,4 @@ class PersistentBuffer( } fun use(block: () -> Unit) = glBuffer.bind { block() } - - private fun memcmp(a: DynamicByteBuffer, b: DynamicByteBuffer, position: Long, size: Long): Boolean { - if (a.capacity != b.capacity) return false - - val end = position + size - var head = position - - // Process the aligned bytes in chunks of 8 until we've reached the end - while (head + 8 <= end) { - val first = MemoryUtil.memGetLong(a.pointer + head) - val second = MemoryUtil.memGetLong(b.pointer + head) - if (first != second) return false - - head += 8 - } - - while (head < end) { - val first = MemoryUtil.memGetByte(a.pointer + head) - val second = MemoryUtil.memGetByte(b.pointer + head) - if (first != second) return false - - head++ - } - - return true - } } diff --git a/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt b/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt index 676e27fff..e3346dca1 100644 --- a/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt +++ b/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt @@ -29,8 +29,8 @@ import org.joml.Vector4d class VertexBuilder( private val direct: VertexPipeline? = null ) { - val vertices by lazy { mutableListOf() } - val indices by lazy { mutableListOf() } + val vertices by lazy(LazyThreadSafetyMode.PUBLICATION) { mutableListOf() } + val indices by lazy(LazyThreadSafetyMode.PUBLICATION) { mutableListOf() } private var verticesCounter = 0 @@ -115,9 +115,6 @@ class VertexBuilder( fun collect(vararg indices: Int) = indices - fun use(block: VertexBuilder.() -> Unit) = - apply(block) - /** * Creates a new vertex with specified attributes * @param block Configuration lambda for defining vertex attributes diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt index 7caa5f688..2e284e8fc 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt @@ -20,11 +20,13 @@ package com.lambda.graphics.renderer.esp import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.SafeListener.Companion.listenConcurrently -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer import com.lambda.module.modules.client.StyleEditor import com.lambda.threading.awaitMainThread +import com.lambda.util.world.FastVector +import com.lambda.util.world.fastVectorOf import net.minecraft.util.math.ChunkPos import net.minecraft.world.World import net.minecraft.world.chunk.WorldChunk @@ -33,13 +35,11 @@ import java.util.concurrent.ConcurrentLinkedDeque class ChunkedESP private constructor( owner: Any, - private val update: StaticESPRenderer.(World, Int, Int, Int) -> Unit + private val update: ShapeBuilder.(World, FastVector) -> Unit ) { private val rendererMap = ConcurrentHashMap() private val WorldChunk.renderer - get() = rendererMap.getOrPut(pos.toLong()) { - EspChunk(this, this@ChunkedESP) - } + get() = rendererMap.getOrPut(pos.toLong()) { EspChunk(this, this@ChunkedESP) } private val uploadQueue = ConcurrentLinkedDeque<() -> Unit>() private val rebuildQueue = ConcurrentLinkedDeque() @@ -52,92 +52,63 @@ class ChunkedESP private constructor( } init { - listenConcurrently { event -> - world.getWorldChunk(event.pos).renderer.notifyChunks() - } + //listen { rebuildQueue.add(rendererMap[ChunkPos.toLong(it.pos)] ?: return@listen) } + listen { it.chunk.renderer.notifyChunks() } + listen { rendererMap.remove(it.chunk.pos.toLong())?.notifyChunks() } - listenConcurrently { event -> - event.chunk.renderer.notifyChunks() - } - - listenConcurrently { event -> - rendererMap.remove(event.chunk.pos.toLong())?.notifyChunks() - } - - owner.listenConcurrently { + listenConcurrently { if (++ticks % StyleEditor.updateFrequency == 0) { val polls = minOf(StyleEditor.rebuildsPerTick, rebuildQueue.size) - repeat(polls) { - rebuildQueue.poll()?.rebuild() - } + repeat(polls) { rebuildQueue.poll()?.rebuild() } + ticks = 0 } } - owner.listen { - if (uploadQueue.isEmpty()) return@listen + owner.onStaticRender { + if (uploadQueue.isEmpty()) return@onStaticRender val polls = minOf(StyleEditor.uploadsPerTick, uploadQueue.size) - repeat(polls) { - uploadQueue.poll()?.invoke() - } + repeat(polls) { uploadQueue.poll()?.invoke() } } - owner.listen { - rendererMap.values.forEach { - it.renderer?.render() - } - } + owner.listen { rendererMap.values.forEach { it.renderer.render() } } } companion object { fun Any.newChunkedESP( - update: StaticESPRenderer.(World, Int, Int, Int) -> Unit - ) = ChunkedESP(this, update) + update: ShapeBuilder.(World, FastVector) -> Unit + ) = ChunkedESP(this@newChunkedESP, update) } private class EspChunk(val chunk: WorldChunk, val owner: ChunkedESP) { - var renderer: StaticESPRenderer? = null - - private val chunkOffsets = listOf(1 to 0, 0 to 1, -1 to 0, 0 to -1) + var renderer = Treed(static = true) + private val builder: ShapeBuilder + get() = ShapeBuilder(renderer.faceBuilder, renderer.edgeBuilder) - val neighbors = chunkOffsets.map { - ChunkPos(chunk.pos.x + it.first, chunk.pos.z + it.second) - }.toTypedArray() + val neighbors = listOf(1 to 0, 0 to 1, -1 to 0, 0 to -1) + .map { ChunkPos(chunk.pos.x + it.first, chunk.pos.z + it.second) } fun notifyChunks() { neighbors.forEach { owner.rendererMap[it.toLong()]?.let { - owner.rebuildQueue.apply { - if (!contains(it)) add(it) - } + if (!owner.rebuildQueue.contains(it)) + owner.rebuildQueue.add(it) } } } suspend fun rebuild() { - val newRenderer = awaitMainThread { StaticESPRenderer() } + renderer = awaitMainThread { Treed(static = true) } - iterateChunk { x, y, z -> - owner.update(newRenderer, chunk.world, x, y, z) - } + for (x in chunk.pos.startX..chunk.pos.endX) + for (z in chunk.pos.startZ..chunk.pos.endZ) + for (y in chunk.bottomY..chunk.height) + owner.update(builder, chunk.world, fastVectorOf(x, y, z)) - owner.uploadQueue.add { - newRenderer.upload() - renderer = newRenderer - } - } - - private fun iterateChunk(block: (Int, Int, Int) -> Unit) = chunk.apply { - for (x in pos.startX..pos.endX) { - for (z in pos.startZ..pos.endZ) { - for (y in bottomY..height) { - block(x, y, z) - } - } - } + owner.uploadQueue.add { renderer.upload() } } } } diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt index 1b58e7cbf..159b32268 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt @@ -26,6 +26,8 @@ class DynamicAABB { private var prev: Box? = null private var curr: Box? = null + val pair get() = prev?.let { prev -> curr?.let { curr -> prev to curr } } + fun update(box: Box): DynamicAABB { prev = curr ?: box curr = box @@ -38,16 +40,6 @@ class DynamicAABB { curr = null } - fun getBoxPair(): Pair? { - prev?.let { previous -> - curr?.let { current -> - return previous to current - } - } - - return null - } - companion object { val Entity.dynamicBox get() = DynamicAABB().apply { diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt new file mode 100644 index 000000000..a47e154ec --- /dev/null +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt @@ -0,0 +1,365 @@ +/* + * Copyright 2025 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.graphics.renderer.esp + +import com.lambda.graphics.pipeline.VertexBuilder +import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection +import com.lambda.threading.runSafe +import com.lambda.util.BlockUtils.blockState +import com.lambda.util.extension.max +import com.lambda.util.extension.min +import com.lambda.util.extension.outlineShape +import net.minecraft.block.BlockState +import net.minecraft.block.entity.BlockEntity +import net.minecraft.entity.Entity +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Box +import net.minecraft.util.shape.VoxelShape +import java.awt.Color + +@DslMarker +annotation class ShapeDsl + +class ShapeBuilder( + val faces: VertexBuilder = VertexBuilder(), + val edges: VertexBuilder = VertexBuilder(), +) { + @ShapeDsl + fun filled( + box : DynamicAABB, + color : Color, + sides : Int = DirectionMask.ALL, + ) = faces.apply { + val boxes = box.pair ?: return@apply + + val pos11 = boxes.first.min + val pos12 = boxes.first.max + val pos21 = boxes.second.min + val pos22 = boxes.second.max + + val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } + val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } + val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } + val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } + val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } + val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } + val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } + val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } + + if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) + if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) + if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) + if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) + if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) + if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) + } + + @ShapeDsl + fun filled( + box : Box, + bottomColor : Color, + topColor : Color = bottomColor, + sides : Int = DirectionMask.ALL + ) = faces.apply { + val pos1 = box.min + val pos2 = box.max + + val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(bottomColor) } } + val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(bottomColor) } } + val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(bottomColor) } } + val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(bottomColor) } } + + val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(topColor) } } + val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(topColor) } } + val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(topColor) } } + val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(topColor) } } + + if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) + if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) + if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) + if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) + if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) + if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) + } + + @ShapeDsl + fun filled( + pos : BlockPos, + state : BlockState, + color : Color, + sides : Int = DirectionMask.ALL, + ) = runSafe { faces.apply { + val shape = state.getOutlineShape(world, pos) + filled(shape, color, sides) + } } + + @ShapeDsl + fun filled( + pos : BlockPos, + color : Color, + sides : Int = DirectionMask.ALL, + ) = runSafe { faces.apply { + val shape = blockState(pos).getOutlineShape(world, pos) + filled(shape, color, sides) + } } + + @ShapeDsl + fun filled( + pos : BlockPos, + entity : BlockEntity, + color : Color, + sides : Int = DirectionMask.ALL, + ) = runSafe { + val shape = outlineShape(entity.cachedState, pos) + filled(shape, color, sides) + } + + @ShapeDsl + fun filled( + shape: VoxelShape, + color: Color, + sides: Int = DirectionMask.ALL, + ) { + shape.boundingBoxes + .forEach { filled(it, color, color, sides) } + } + + @ShapeDsl + fun filled( + box : Box, + color : Color, + sides : Int = DirectionMask.ALL, + ) = filled(box, color, color, sides) + + @ShapeDsl + fun outline( + box : DynamicAABB, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = edges.apply { + val boxes = box.pair ?: return@apply + + val pos11 = boxes.first.min + val pos12 = boxes.first.max + val pos21 = boxes.second.min + val pos22 = boxes.second.max + + val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } + val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } + val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } + val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } + val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } + val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } + val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } + val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } + + val hasEast = sides.hasDirection(DirectionMask.EAST) + val hasWest = sides.hasDirection(DirectionMask.WEST) + val hasUp = sides.hasDirection(DirectionMask.UP) + val hasDown = sides.hasDirection(DirectionMask.DOWN) + val hasSouth = sides.hasDirection(DirectionMask.SOUTH) + val hasNorth = sides.hasDirection(DirectionMask.NORTH) + + if (mode.check(hasUp, hasNorth)) buildLine(tlb, trb) + if (mode.check(hasUp, hasSouth)) buildLine(tlf, trf) + if (mode.check(hasUp, hasWest)) buildLine(tlb, tlf) + if (mode.check(hasUp, hasEast)) buildLine(trf, trb) + + if (mode.check(hasDown, hasNorth)) buildLine(blb, brb) + if (mode.check(hasDown, hasSouth)) buildLine(blf, brf) + if (mode.check(hasDown, hasWest)) buildLine(blb, blf) + if (mode.check(hasDown, hasEast)) buildLine(brb, brf) + + if (mode.check(hasWest, hasNorth)) buildLine(tlb, blb) + if (mode.check(hasNorth, hasEast)) buildLine(trb, brb) + if (mode.check(hasEast, hasSouth)) buildLine(trf, brf) + if (mode.check(hasSouth, hasWest)) buildLine(tlf, blf) + } + + @ShapeDsl + fun outline( + box : Box, + bottomColor : Color, + topColor : Color = bottomColor, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = edges.apply { + val pos1 = box.min + val pos2 = box.max + + val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(bottomColor) } } + val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(bottomColor) } } + val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(bottomColor) } } + val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(bottomColor) } } + val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(topColor) } } + val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(topColor) } } + val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(topColor) } } + val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(topColor) } } + + val hasEast = sides.hasDirection(DirectionMask.EAST) + val hasWest = sides.hasDirection(DirectionMask.WEST) + val hasUp = sides.hasDirection(DirectionMask.UP) + val hasDown = sides.hasDirection(DirectionMask.DOWN) + val hasSouth = sides.hasDirection(DirectionMask.SOUTH) + val hasNorth = sides.hasDirection(DirectionMask.NORTH) + + if (mode.check(hasUp, hasNorth)) buildLine(tlb, trb) + if (mode.check(hasUp, hasSouth)) buildLine(tlf, trf) + if (mode.check(hasUp, hasWest)) buildLine(tlb, tlf) + if (mode.check(hasUp, hasEast)) buildLine(trf, trb) + + if (mode.check(hasDown, hasNorth)) buildLine(blb, brb) + if (mode.check(hasDown, hasSouth)) buildLine(blf, brf) + if (mode.check(hasDown, hasWest)) buildLine(blb, blf) + if (mode.check(hasDown, hasEast)) buildLine(brb, brf) + + if (mode.check(hasWest, hasNorth)) buildLine(tlb, blb) + if (mode.check(hasNorth, hasEast)) buildLine(trb, brb) + if (mode.check(hasEast, hasSouth)) buildLine(trf, brf) + if (mode.check(hasSouth, hasWest)) buildLine(tlf, blf) + } + + @ShapeDsl + fun outline( + pos : BlockPos, + state : BlockState, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + val shape = state.getOutlineShape(world, pos) + outline(shape, color, sides, mode) + } + + @ShapeDsl + fun outline( + pos : BlockPos, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + val shape = blockState(pos).getOutlineShape(world, pos) + outline(shape, color, sides, mode) + } + + @ShapeDsl + fun outline( + pos : BlockPos, + entity : BlockEntity, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + val shape = outlineShape(entity.cachedState, pos) + outline(shape, color, sides, mode) + } + + @ShapeDsl + fun outline( + shape : VoxelShape, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + shape.boundingBoxes + .forEach { outline(it, color, sides, mode) } + } + + @ShapeDsl + fun outline( + box : Box, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + outline(box, color, color, sides, mode) + } + + @ShapeDsl + fun box( + pos : BlockPos, + state : BlockState, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + val shape = state.getOutlineShape(world, pos) + filled(shape, filled, sides) + outline(shape, outline, sides, mode) + } + + @ShapeDsl + fun box( + pos : BlockPos, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + filled(pos, filled, sides) + outline(pos, outline, sides, mode) + } + + @ShapeDsl + fun box( + box : DynamicAABB, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + filled(box, filled, sides) + outline(box, outline, sides, mode) + } + + @ShapeDsl + fun box( + box : Box, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + filled(box, filled, sides) + outline(box, outline, sides, mode) + } + + @ShapeDsl + fun box( + entity : BlockEntity, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + filled(entity.pos, entity, color, sides) + outline(entity.pos, entity, color, sides, mode) + } + + @ShapeDsl + fun box( + entity : Entity, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + filled(entity.boundingBox, color, sides) + outline(entity.boundingBox, color, sides, mode) + } +} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ESPRenderer.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt similarity index 59% rename from src/main/kotlin/com/lambda/graphics/renderer/esp/ESPRenderer.kt rename to src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt index bf6676636..90e96ca44 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ESPRenderer.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt @@ -23,34 +23,22 @@ import com.lambda.graphics.buffer.vertex.attributes.VertexMode import com.lambda.graphics.gl.GlStateUtils import com.lambda.graphics.pipeline.VertexBuilder import com.lambda.graphics.pipeline.VertexPipeline -import com.lambda.graphics.shader.Shader import com.lambda.graphics.shader.Shader.Companion.shader import com.lambda.module.modules.client.StyleEditor import com.lambda.util.extension.partialTicks -open class ESPRenderer(tickedMode: Boolean) { - val shader: Shader +open class Treed(static: Boolean) { + val shader = if (static) staticMode.first else dynamicMode.first - val faces: VertexPipeline - var faceBuilder: VertexBuilder + val faces = VertexPipeline(VertexMode.TRIANGLES, if (static) staticMode.second else dynamicMode.second) + val edges = VertexPipeline(VertexMode.LINES, if (static) staticMode.second else dynamicMode.second) - val outlines: VertexPipeline - var outlineBuilder: VertexBuilder - - init { - val mode = if (tickedMode) dynamicMode else staticMode - shader = mode.first - - faces = VertexPipeline(VertexMode.TRIANGLES, mode.second) - faceBuilder = faces.build() - - outlines = VertexPipeline(VertexMode.LINES, mode.second) - outlineBuilder = outlines.build() - } + var faceBuilder = VertexBuilder(); private set + var edgeBuilder = VertexBuilder(); private set fun upload() { faces.upload(faceBuilder) - outlines.upload(outlineBuilder) + edges.upload(edgeBuilder) } fun render() { @@ -59,23 +47,22 @@ open class ESPRenderer(tickedMode: Boolean) { shader["u_CameraPosition"] = Lambda.mc.gameRenderer.camera.pos GlStateUtils.withFaceCulling(faces::render) - GlStateUtils.withLineWidth(StyleEditor.outlineWidth, outlines::render) + GlStateUtils.withLineWidth(StyleEditor.outlineWidth, edges::render) } fun clear() { faces.clear() - outlines.clear() - faceBuilder = faces.build() - outlineBuilder = outlines.build() + edges.clear() + + faceBuilder = VertexBuilder() + edgeBuilder = VertexBuilder() } - companion object { - private val staticMode = shader( - "renderer/box_static" - ) to VertexAttrib.Group.STATIC_RENDERER + object Static : Treed(true) + object Dynamic : Treed(false) - private val dynamicMode = shader( - "renderer/box_dynamic" - ) to VertexAttrib.Group.DYNAMIC_RENDERER + companion object { + private val staticMode = shader("renderer/box_static") to VertexAttrib.Group.STATIC_RENDERER + private val dynamicMode = shader("renderer/box_dynamic") to VertexAttrib.Group.DYNAMIC_RENDERER } } diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/DynamicESPBuilders.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/DynamicESPBuilders.kt deleted file mode 100644 index cb0653245..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/DynamicESPBuilders.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2025 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.graphics.renderer.esp.builders - -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection -import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.impl.DynamicESPRenderer -import com.lambda.util.extension.max -import com.lambda.util.extension.min -import java.awt.Color - -fun DynamicESPRenderer.ofBox( - box: DynamicAABB, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - buildFilled(box, filledColor, sides) - buildOutline(box, outlineColor, sides, outlineMode) -} - -fun DynamicESPRenderer.buildFilled( - box: DynamicAABB, - color: Color, - sides: Int = DirectionMask.ALL -) = faceBuilder.use { - val boxes = box.getBoxPair() ?: return@use - val pos11 = boxes.first.min - val pos12 = boxes.first.max - val pos21 = boxes.second.min - val pos22 = boxes.second.max - - val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } - val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } - val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } - val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } - val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } - val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } - val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } - val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } - - if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) - if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) - if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) - if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) - if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) - if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) -} - -fun DynamicESPRenderer.buildOutline( - box: DynamicAABB, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = outlineBuilder.use { - val boxes = box.getBoxPair() ?: return@use - - val pos11 = boxes.first.min - val pos12 = boxes.first.max - val pos21 = boxes.second.min - val pos22 = boxes.second.max - - val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } - val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } - val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } - val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } - val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } - val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } - val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } - val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } - - val hasEast = sides.hasDirection(DirectionMask.EAST) - val hasWest = sides.hasDirection(DirectionMask.WEST) - val hasUp = sides.hasDirection(DirectionMask.UP) - val hasDown = sides.hasDirection(DirectionMask.DOWN) - val hasSouth = sides.hasDirection(DirectionMask.SOUTH) - val hasNorth = sides.hasDirection(DirectionMask.NORTH) - - if (outlineMode.check(hasUp, hasNorth)) buildLine(tlb, trb) - if (outlineMode.check(hasUp, hasSouth)) buildLine(tlf, trf) - if (outlineMode.check(hasUp, hasWest)) buildLine(tlb, tlf) - if (outlineMode.check(hasUp, hasEast)) buildLine(trf, trb) - - if (outlineMode.check(hasDown, hasNorth)) buildLine(blb, brb) - if (outlineMode.check(hasDown, hasSouth)) buildLine(blf, brf) - if (outlineMode.check(hasDown, hasWest)) buildLine(blb, blf) - if (outlineMode.check(hasDown, hasEast)) buildLine(brb, brf) - - if (outlineMode.check(hasWest, hasNorth)) buildLine(tlb, blb) - if (outlineMode.check(hasNorth, hasEast)) buildLine(trb, brb) - if (outlineMode.check(hasEast, hasSouth)) buildLine(trf, brf) - if (outlineMode.check(hasSouth, hasWest)) buildLine(tlf, blf) -} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/StaticESPBuilders.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/StaticESPBuilders.kt deleted file mode 100644 index d4a733726..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/StaticESPBuilders.kt +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2025 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.graphics.renderer.esp.builders - -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer -import com.lambda.threading.runSafe -import com.lambda.util.BlockUtils.blockState -import com.lambda.util.extension.max -import com.lambda.util.extension.min -import net.minecraft.block.BlockState -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box -import net.minecraft.util.shape.VoxelShape -import java.awt.Color - -fun StaticESPRenderer.ofShape( - pos: BlockPos, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = blockState(pos).getOutlineShape(world, pos) - ofShape(pos, shape, filledColor, outlineColor, sides, outlineMode) -} - -fun StaticESPRenderer.ofShape( - pos: BlockPos, - state: BlockState, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = state.getOutlineShape(world, pos) - ofShape(pos, shape, filledColor, outlineColor, sides, outlineMode) -} - -fun StaticESPRenderer.ofShape( - pos: BlockPos, - shape: VoxelShape, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - shape.boundingBoxes.forEach { - ofBox(it.offset(pos), filledColor, outlineColor, sides, outlineMode) - } -} - -fun StaticESPRenderer.ofBox( - box: Box, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - buildFilled(box, filledColor, sides) - buildOutline(box, outlineColor, sides, outlineMode) -} - -fun StaticESPRenderer.buildFilledShape( - pos: BlockPos, - state: BlockState, - color: Color, - sides: Int = DirectionMask.ALL, -) = runSafe { - val shape = state.getOutlineShape(world, pos) - buildFilledShape(shape, color, sides) -} - -fun StaticESPRenderer.buildFilledShape( - pos: BlockPos, - color: Color, - sides: Int = DirectionMask.ALL, -) = runSafe { - val shape = blockState(pos).getOutlineShape(world, pos) - buildFilledShape(shape, color, sides) -} - -fun StaticESPRenderer.buildFilledShape( - shape: VoxelShape, - color: Color, - sides: Int = DirectionMask.ALL, -) { - shape.boundingBoxes - .forEach { buildFilled(it, color, sides) } -} - - -fun StaticESPRenderer.buildFilled( - box: Box, - color: Color, - sides: Int = DirectionMask.ALL -) { - buildFilled(box, color, color, sides) -} - -fun StaticESPRenderer.buildOutlineShape( - pos: BlockPos, - state: BlockState, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = state.getOutlineShape(world, pos) - buildOutlineShape(shape, color, sides, outlineMode) -} - -fun StaticESPRenderer.buildOutlineShape( - pos: BlockPos, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = blockState(pos).getOutlineShape(world, pos) - buildOutlineShape(shape, color, sides, outlineMode) -} - -fun StaticESPRenderer.buildOutlineShape( - shape: VoxelShape, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - shape.boundingBoxes - .forEach { buildOutline(it, color, sides, outlineMode) } -} - -fun StaticESPRenderer.buildOutline( - box: Box, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - buildOutline(box, color, color, sides, outlineMode) -} - -fun StaticESPRenderer.buildFilled( - box: Box, - colorBottom: Color, - colorTop: Color = colorBottom, - sides: Int = DirectionMask.ALL -) = faceBuilder.use { - val pos1 = box.min - val pos2 = box.max - - val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(colorBottom) } } - val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(colorBottom) } } - val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(colorBottom) } } - val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(colorBottom) } } - - val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(colorTop) } } - val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(colorTop) } } - val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(colorTop) } } - val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(colorTop) } } - - if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) - if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) - if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) - if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) - if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) - if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) -} - -fun StaticESPRenderer.buildOutline( - box: Box, - colorBottom: Color, - colorTop: Color = colorBottom, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = outlineBuilder.use { - val pos1 = box.min - val pos2 = box.max - - val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(colorBottom) } } - val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(colorBottom) } } - val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(colorBottom) } } - val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(colorBottom) } } - val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(colorTop) } } - val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(colorTop) } } - val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(colorTop) } } - val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(colorTop) } } - - val hasEast = sides.hasDirection(DirectionMask.EAST) - val hasWest = sides.hasDirection(DirectionMask.WEST) - val hasUp = sides.hasDirection(DirectionMask.UP) - val hasDown = sides.hasDirection(DirectionMask.DOWN) - val hasSouth = sides.hasDirection(DirectionMask.SOUTH) - val hasNorth = sides.hasDirection(DirectionMask.NORTH) - - if (outlineMode.check(hasUp, hasNorth)) buildLine(tlb, trb) - if (outlineMode.check(hasUp, hasSouth)) buildLine(tlf, trf) - if (outlineMode.check(hasUp, hasWest)) buildLine(tlb, tlf) - if (outlineMode.check(hasUp, hasEast)) buildLine(trf, trb) - - if (outlineMode.check(hasDown, hasNorth)) buildLine(blb, brb) - if (outlineMode.check(hasDown, hasSouth)) buildLine(blf, brf) - if (outlineMode.check(hasDown, hasWest)) buildLine(blb, blf) - if (outlineMode.check(hasDown, hasEast)) buildLine(brb, brf) - - if (outlineMode.check(hasWest, hasNorth)) buildLine(tlb, blb) - if (outlineMode.check(hasNorth, hasEast)) buildLine(trb, brb) - if (outlineMode.check(hasEast, hasSouth)) buildLine(trf, brf) - if (outlineMode.check(hasSouth, hasWest)) buildLine(tlf, blf) -} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/DynamicESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/global/DynamicESP.kt deleted file mode 100644 index cc8758055..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/DynamicESP.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2025 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.graphics.renderer.esp.global - -import com.lambda.graphics.renderer.esp.impl.DynamicESPRenderer - -object DynamicESP : DynamicESPRenderer() diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/StaticESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/global/StaticESP.kt deleted file mode 100644 index 7e0c9b6ce..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/StaticESP.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2025 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.graphics.renderer.esp.global - -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer - -object StaticESP : StaticESPRenderer() diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/DynamicESPRenderer.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/DynamicESPRenderer.kt deleted file mode 100644 index 9ba314bdd..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/DynamicESPRenderer.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2025 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.graphics.renderer.esp.impl - -import com.lambda.graphics.renderer.esp.ESPRenderer - -open class DynamicESPRenderer : ESPRenderer(true) diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/StaticESPRenderer.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/StaticESPRenderer.kt deleted file mode 100644 index d3d48deea..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/StaticESPRenderer.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2025 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.graphics.renderer.esp.impl - -import com.lambda.graphics.renderer.esp.ESPRenderer - -open class StaticESPRenderer : ESPRenderer(false) \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt index 04cef97b8..9a449a891 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt @@ -17,9 +17,9 @@ package com.lambda.interaction.construction.context -import com.lambda.context.SafeContext import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.exclude +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.material.StackSelection import com.lambda.interaction.request.breaking.BreakConfig import com.lambda.interaction.request.breaking.BreakRequest @@ -72,9 +72,8 @@ data class BreakContext( } } - override fun SafeContext.buildRenderer() { - withState(cachedState, blockPos, baseColor, DirectionMask.ALL.exclude(result.side)) - withState(cachedState, blockPos, sideColor, result.side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, cachedState, baseColor, sideColor, DirectionMask.ALL.exclude(result.side)) } fun requestSwap(breakRequest: BreakRequest, minKeepTicks: Int = 0): Boolean = @@ -83,4 +82,4 @@ data class BreakContext( breakRequest.hotbar, breakRequest.hotbar.keepTicks.coerceAtLeast(minKeepTicks) ).submit(false).done -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt index 33bcb966a..e61351a32 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt @@ -17,16 +17,14 @@ package com.lambda.interaction.construction.context -import com.lambda.context.SafeContext -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.exclude +import com.lambda.graphics.renderer.esp.DirectionMask.mask +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.request.Request.Companion.submit import com.lambda.interaction.request.hotbar.HotbarManager import com.lambda.interaction.request.hotbar.HotbarRequest import com.lambda.interaction.request.interacting.InteractRequest import com.lambda.interaction.request.rotating.RotationRequest import com.lambda.util.BlockUtils -import com.lambda.util.BlockUtils.blockState import net.minecraft.block.BlockState import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.math.BlockPos @@ -61,9 +59,8 @@ class InteractionContext( else -> 1 } - override fun SafeContext.buildRenderer() { - withState(expectedState, blockPos, baseColor, DirectionMask.ALL.exclude(result.side.opposite)) - withState(blockState(result.blockPos), result.blockPos, sideColor, result.side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, expectedState, baseColor, sideColor, result.side.mask) } fun requestDependencies(request: InteractRequest): Boolean { @@ -71,4 +68,4 @@ class InteractionContext( val validRotation = if (request.rotate) submit(rotation, false).done else true return hotbarRequest.done && validRotation } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt index f25101867..76689dab2 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt @@ -21,6 +21,8 @@ import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.exclude +import com.lambda.graphics.renderer.esp.DirectionMask.mask +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.request.Request.Companion.submit import com.lambda.interaction.request.hotbar.HotbarManager import com.lambda.interaction.request.hotbar.HotbarRequest @@ -70,9 +72,8 @@ data class PlaceContext( else -> 1 } - override fun SafeContext.buildRenderer() { - withState(expectedState, blockPos, baseColor, DirectionMask.ALL.exclude(result.side.opposite)) - withState(blockState(result.blockPos), result.blockPos, sideColor, result.side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, expectedState, baseColor, sideColor, result.side.mask) } fun requestDependencies(request: PlaceRequest): Boolean { diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt index b6f032a47..58092620a 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt @@ -19,7 +19,8 @@ package com.lambda.interaction.construction.result import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalInverted -import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.DirectionMask.mask +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.BreakContext import com.lambda.interaction.material.StackSelection.Companion.selectStack import com.lambda.interaction.material.container.ContainerManager.transfer @@ -44,7 +45,7 @@ sealed class BreakResult : BuildResult() { ) : Drawable, Contextual, BreakResult() { override val rank = Rank.BREAK_SUCCESS - override fun SafeContext.buildRenderer() { + override fun ShapeBuilder.buildRenderer() { with(context) { buildRenderer() } } @@ -68,8 +69,8 @@ sealed class BreakResult : BuildResult() { override val rank = Rank.BREAK_NOT_EXPOSED private val color = Color(46, 0, 0, 30) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color, side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color, side.mask) } override fun compareTo(other: ComparableResult): Int { @@ -108,8 +109,8 @@ sealed class BreakResult : BuildResult() { ) } - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -132,8 +133,8 @@ sealed class BreakResult : BuildResult() { override val rank = Rank.BREAK_SUBMERGE private val color = Color(114, 27, 255, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -147,8 +148,8 @@ sealed class BreakResult : BuildResult() { override val rank = Rank.BREAK_IS_BLOCKED_BY_FLUID private val color = Color(50, 12, 112, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -164,8 +165,8 @@ sealed class BreakResult : BuildResult() { override val goal = GoalInverted(GoalBlock(blockPos)) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } } diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt index 5e8d657f9..1712db18c 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.construction.result import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalNear -import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.BuildContext import com.lambda.interaction.material.StackSelection import com.lambda.interaction.material.StackSelection.Companion.select @@ -27,12 +27,10 @@ import com.lambda.interaction.material.container.ContainerManager.transfer import com.lambda.interaction.material.container.MaterialContainer import com.lambda.interaction.material.container.containers.MainHandContainer import com.lambda.interaction.request.inventory.InventoryConfig -import com.lambda.util.BlockUtils.blockState import com.lambda.util.Nameable import net.minecraft.block.BlockState import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import java.awt.Color @@ -81,8 +79,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val goal = GoalBlock(blockPos) - override fun SafeContext.buildRenderer() { - withBox(Box(blockPos), color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -104,8 +102,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.BREAK_RESTRICTED private val color = Color(255, 0, 0, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -122,8 +120,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank get() = Rank.BREAK_NO_PERMISSION private val color = Color(255, 0, 0, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -138,8 +136,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.OUT_OF_WORLD private val color = Color(3, 148, 252, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -156,8 +154,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.UNBREAKABLE private val color = Color(11, 11, 11, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -176,8 +174,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.NOT_VISIBLE private val color = Color(46, 0, 0, 80) - override fun SafeContext.buildRenderer() { - withBox(Box(blockPos), color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -215,12 +213,8 @@ abstract class BuildResult : ComparableResult, Nameable { ) } - override fun SafeContext.buildRenderer() { - if (blockState(blockPos).isAir) { - withBox(Box(blockPos), color) - } else { - withPos(blockPos, color) - } + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -258,12 +252,8 @@ abstract class BuildResult : ComparableResult, Nameable { ) } - override fun SafeContext.buildRenderer() { - if (blockState(blockPos).isAir) { - withBox(Box(blockPos), color) - } else { - withPos(blockPos, color) - } + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -295,8 +285,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val goal = GoalNear(blockPos, 3) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt b/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt index 04b6f84a1..84b71901e 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt @@ -17,51 +17,8 @@ package com.lambda.interaction.construction.result -import com.lambda.context.SafeContext -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.include -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.global.StaticESP -import com.lambda.util.BlockUtils.blockState -import net.minecraft.block.BlockState -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box -import net.minecraft.util.math.Direction -import net.minecraft.util.shape.VoxelShape -import java.awt.Color +import com.lambda.graphics.renderer.esp.ShapeBuilder interface Drawable { - fun SafeContext.buildRenderer() - - fun SafeContext.withBox(box: Box, color: Color, mask: Int = DirectionMask.ALL) { - StaticESP.buildFilled(box, color, mask) - //StaticESP.buildOutline(box, color, mask) - } - - fun SafeContext.withState(blockState: BlockState, blockPos: BlockPos, color: Color, side: Direction) { - withState(blockState, blockPos, color, DirectionMask.NONE.include(side)) - } - - fun SafeContext.withState(blockState: BlockState, blockPos: BlockPos, color: Color, mask: Int = DirectionMask.ALL) { - withShape(blockState.getOutlineShape(world, blockPos), blockPos, color, mask) - } - - fun SafeContext.withPos(blockPos: BlockPos, color: Color, side: Direction) { - withPos(blockPos, color, DirectionMask.NONE.include(side)) - } - - fun SafeContext.withPos(blockPos: BlockPos, color: Color, mask: Int = DirectionMask.ALL) { - val shape = blockState(blockPos).getOutlineShape(world, blockPos) - withShape(shape, blockPos, color, mask) - } - - fun SafeContext.withShape(shape: VoxelShape, offset: BlockPos, color: Color, mask: Int = DirectionMask.ALL) { - if (shape.isEmpty) { - withBox(Box(offset), color, mask) - return - } - shape.boundingBoxes.forEach { box -> - withBox(box.offset(offset), color, mask) - } - } + fun ShapeBuilder.buildRenderer() } diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt index bbfcd5137..e70102e26 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt @@ -18,6 +18,7 @@ package com.lambda.interaction.construction.result import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.InteractionContext import net.minecraft.util.math.BlockPos @@ -28,7 +29,7 @@ sealed class InteractResult : BuildResult() { ) : Contextual, Drawable, InteractResult() { override val rank = Rank.INTERACT_SUCCESS - override fun SafeContext.buildRenderer() { + override fun ShapeBuilder.buildRenderer() { with(context) { buildRenderer() } } @@ -38,4 +39,4 @@ sealed class InteractResult : BuildResult() { else -> super.compareTo(other) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt index 6b2dc65a0..067eb08e7 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.construction.result import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalInverted import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.PlaceContext import com.lambda.task.tasks.BuildTask.Companion.breakBlock import net.minecraft.block.BlockState @@ -46,7 +47,7 @@ sealed class PlaceResult : BuildResult() { ) : Contextual, Drawable, PlaceResult() { override val rank = Rank.PLACE_SUCCESS - override fun SafeContext.buildRenderer() { + override fun ShapeBuilder.buildRenderer() { with(context) { buildRenderer() } } @@ -77,8 +78,8 @@ sealed class PlaceResult : BuildResult() { override val rank = Rank.PLACE_NO_INTEGRITY private val color = Color(252, 3, 3, 100) - override fun SafeContext.buildRenderer() { - withState(expected, blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, expected, color, color) } } diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt index 6e8b1c1fc..5bf40b099 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.construction.simulation import com.lambda.config.groups.BuildConfig import com.lambda.config.groups.InteractionConfig import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.blueprint.Blueprint import com.lambda.interaction.construction.result.BuildResult import com.lambda.interaction.construction.result.Drawable @@ -71,8 +72,8 @@ data class Simulation( .map { PossiblePos(it.key.toBlockPos(), it.value.count { it.rank.ordinal < 4 }) } class PossiblePos(val pos: BlockPos, val interactions: Int) : Drawable { - override fun SafeContext.buildRenderer() { - withBox(Vec3d.ofBottomCenter(pos).playerBox(), Color(0, 255, 0, 50)) + override fun ShapeBuilder.buildRenderer() { + box(Vec3d.ofBottomCenter(pos).playerBox(), Color(0, 255, 0, 50), Color(0, 255, 0, 50)) } } diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt index 7fbdc5699..b57f8ebb3 100644 --- a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt @@ -22,15 +22,13 @@ import com.lambda.event.Event import com.lambda.event.EventFlow.post import com.lambda.event.events.ConnectionEvent import com.lambda.event.events.EntityEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.UpdateManagerEvent import com.lambda.event.events.WorldEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.context.BreakContext @@ -217,16 +215,16 @@ object BreakManager : RequestHandler( ?.internalOnItemDrop(it.entity) } - listen { event -> + onStaticRender { val activeStack = breakInfos .filterNotNull() - .firstOrNull()?.swapStack ?: return@listen + .firstOrNull()?.swapStack ?: return@onStaticRender breakInfos .filterNotNull() .forEach { info -> val config = info.breakConfig - if (!config.renders) return@listen + if (!config.renders) return@onStaticRender val swapMode = info.breakConfig.swapMode val breakDelta = info.context.cachedState.calcBreakDelta( player, @@ -265,8 +263,8 @@ object BreakManager : RequestHandler( val dynamicAABB = DynamicAABB() dynamicAABB.update(interpolatedNow) dynamicAABB.update(interpolatedNext) - if (config.fill) event.renderer.buildFilled(dynamicAABB, fillColor) - if (config.outline) event.renderer.buildOutline(dynamicAABB, outlineColor) + if (config.fill) it.filled(dynamicAABB, fillColor) + if (config.outline) it.outline(dynamicAABB, outlineColor) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt b/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt index 314657674..944b343fe 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt @@ -22,8 +22,8 @@ import com.lambda.config.groups.HotbarSettings import com.lambda.config.groups.InteractionSettings import com.lambda.config.groups.InventorySettings import com.lambda.config.groups.RotationSettings -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.event.events.onStaticRender +import com.lambda.interaction.construction.result.BuildResult import com.lambda.interaction.construction.result.Drawable import com.lambda.module.Module import com.lambda.module.tag.ModuleTag @@ -58,10 +58,8 @@ object TaskFlowModule : Module( var drawables = listOf() init { - listen { - drawables.toList().forEach { res -> - with(res) { buildRenderer() } - } + onStaticRender { + with(it) { drawables.forEach { with(it) { buildRenderer() } } } } } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 9ec6177f2..3d6d2994e 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -180,7 +180,7 @@ object CrystalAura : Module( updatesThisFrame = 0 } - listen { + listen { if (!debug) return@listen Matrices.push { diff --git a/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt index 223812b68..1a649301c 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt @@ -17,9 +17,7 @@ package com.lambda.module.modules.debug -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.graphics.renderer.esp.builders.ofBox +import com.lambda.event.events.onStaticRender import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.world.blockSearch @@ -49,12 +47,12 @@ object BlockTest : Module( private val outlineColor = Color(100, 150, 255, 51) init { - listen { + onStaticRender { blockSearch(range, step = step) { _, state -> state.isOf(Blocks.DIAMOND_BLOCK) }.forEach { (pos, state) -> state.getOutlineShape(world, pos).boundingBoxes.forEach { box -> - it.renderer.ofBox(box.offset(pos), filledColor, outlineColor) + it.box(box.offset(pos), filledColor, outlineColor) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt index 71248fedd..1618c3a6f 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt @@ -17,10 +17,10 @@ package com.lambda.module.modules.debug -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.event.events.onDynamicRender +import com.lambda.event.events.onStaticRender +import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DynamicAABB.Companion.dynamicBox -import com.lambda.graphics.renderer.esp.builders.ofBox import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.setAlpha @@ -45,15 +45,15 @@ object RenderTest : Module( private val filledColor = outlineColor.setAlpha(0.2) init { - listen { + onDynamicRender { entitySearch(8.0) .forEach { entity -> - it.renderer.ofBox(entity.dynamicBox, filledColor, outlineColor) + it.box(entity.dynamicBox, filledColor, outlineColor, DirectionMask.ALL, DirectionMask.OutlineMode.AND) } } - listen { - it.renderer.ofBox(Box.of(player.pos, 0.3, 0.3, 0.3), filledColor, outlineColor) + onStaticRender { + it.box(Box.of(player.pos, 0.3, 0.3, 0.3), filledColor, outlineColor) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt index a7fc452e3..98f8d6ab2 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt @@ -20,11 +20,10 @@ package com.lambda.module.modules.movement import com.lambda.context.SafeContext import com.lambda.event.events.ConnectionEvent import com.lambda.event.events.PacketEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent +import com.lambda.event.events.onDynamicRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.builders.ofBox import com.lambda.module.Module import com.lambda.module.modules.client.GuiSettings import com.lambda.module.modules.combat.KillAura @@ -111,15 +110,15 @@ object BackTrack : Module( poolPackets() } - listen { - val target = target ?: return@listen + onDynamicRender { + val target = target ?: return@onDynamicRender val c1 = GuiSettings.primaryColor val c2 = Color.RED val p = target.hurtTime / 10.0 val c = lerp(p, c1, c2) - it.renderer.ofBox(box, c.multAlpha(0.3), c.multAlpha(0.8)) + it.box(box, c.multAlpha(0.3), c.multAlpha(0.8)) } listen { event -> diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt index 6b54ed4f4..bc9266d99 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt @@ -20,9 +20,9 @@ package com.lambda.module.modules.movement import com.lambda.context.SafeContext import com.lambda.event.events.PacketEvent import com.lambda.event.events.RenderEvent +import com.lambda.event.events.onDynamicRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.builders.ofBox import com.lambda.module.Module import com.lambda.module.modules.client.GuiSettings import com.lambda.module.modules.combat.KillAura @@ -58,7 +58,7 @@ object Blink : Module( private var lastBox = Box(BlockPos.ORIGIN) init { - listen { + listen { val time = System.currentTimeMillis() if (isActive && time - lastUpdate < delay) return@listen @@ -67,9 +67,9 @@ object Blink : Module( poolPackets() } - listen { event -> + onDynamicRender { val color = GuiSettings.primaryColor - event.renderer.ofBox(box.update(lastBox), color.setAlpha(0.3), color) + it.box(box.update(lastBox), color.setAlpha(0.3), color) } listen { event -> diff --git a/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt b/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt index b5d6f130e..20787710a 100644 --- a/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt +++ b/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt @@ -53,7 +53,7 @@ object PacketDelay : Module( private var inboundLastUpdate = 0L init { - listen { + listen { if (mode != Mode.Static) return@listen flushPools(System.currentTimeMillis()) diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 387418393..c42d2ec79 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -24,11 +24,9 @@ import com.lambda.config.groups.InventorySettings import com.lambda.config.groups.RotationSettings import com.lambda.context.SafeContext import com.lambda.event.events.PlayerEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.context.BreakContext import com.lambda.interaction.construction.context.BuildContext @@ -161,8 +159,8 @@ object PacketMine : Module( } } - listen { event -> - if (!renderQueue) return@listen + onStaticRender { + if (!renderQueue) return@onStaticRender queueSorted.forEachIndexed { index, positions -> positions.forEach { pos -> val color = if (dynamicColor) lerp(index / queuePositions.size.toDouble(), startColor, endColor) @@ -173,8 +171,8 @@ object PacketMine : Module( }.map { lerp(renderSize.toDouble(), Box(it.center, it.center), it).offset(pos) } boxes.forEach { box -> - event.renderer.buildFilled(box, color) - event.renderer.buildOutline(box, color.setAlpha(1.0)) + it.filled(box, color) + it.outline(box, color.setAlpha(1.0)) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt b/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt index a8d6208d2..42a8807e2 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt @@ -17,9 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.graphics.renderer.esp.builders.buildOutline +import com.lambda.event.events.onStaticRender import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.verify.TargetState @@ -67,9 +65,7 @@ object WorldEater : Module( BaritoneUtils.cancel() } - listen { - it.renderer.buildOutline(Box.enclosing(pos1, pos2), Color.BLUE) - } + onStaticRender { it.outline(Box.enclosing(pos1, pos2), Color.BLUE) } } private fun buildLayer() { diff --git a/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt b/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt index 99fe807f4..c979b9263 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt @@ -18,19 +18,17 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc +import com.lambda.context.SafeContext import com.lambda.graphics.renderer.esp.ChunkedESP.Companion.newChunkedESP import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.buildSideMesh -import com.lambda.graphics.renderer.esp.builders.buildFilledShape -import com.lambda.graphics.renderer.esp.builders.buildOutlineShape -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.extension.blockColor import com.lambda.util.extension.getBlockState import com.lambda.util.extension.outlineShape -import com.lambda.util.world.fastVectorOf import com.lambda.util.world.toBlockPos import net.minecraft.block.BlockState import net.minecraft.block.Blocks @@ -45,19 +43,19 @@ object BlockESP : Module( ) { // ToDo: Toggle searching, solve memory leak private val searchBlocks by setting("Search Blocks", true, "Search for blocks around the player") - private val blocks by setting("Blocks", setOf(Blocks.BEDROCK), setOf(Blocks.BEDROCK), "Render blocks") { searchBlocks }.onValueSet(::rebuildMesh) - private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks") { searchBlocks }.onValueSet(::rebuildMesh).onValueSet { _, to -> if (!to) drawOutlines = true } - private var drawOutlines: Boolean by setting("Draw Outlines", true, "Draw outlines of blocks") { searchBlocks }.onValueSet(::rebuildMesh).onValueSet { _, to -> if (!to) drawFaces = true } - private val mesh by setting("Mesh", true, "Connect similar adjacent blocks") { searchBlocks }.onValueSet(::rebuildMesh) + private val blocks by setting("Blocks", setOf(Blocks.BEDROCK), setOf(Blocks.BEDROCK), "Render blocks") { searchBlocks }.onValueChange(::rebuildMesh) + private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks") { searchBlocks }.onValueChange(::rebuildMesh).onValueChange { _, to -> if (!to) drawOutlines = true } + private var drawOutlines: Boolean by setting("Draw Outlines", true, "Draw outlines of blocks") { searchBlocks }.onValueChange(::rebuildMesh).onValueChange { _, to -> if (!to) drawFaces = true } + private val mesh by setting("Mesh", true, "Connect similar adjacent blocks") { searchBlocks }.onValueChange(::rebuildMesh) - private val useBlockColor by setting("Use Block Color", false, "Use the color of the block instead") { searchBlocks }.onValueSet(::rebuildMesh) - private val faceColor by setting("Face Color", Color(100, 150, 255, 51), "Color of the surfaces") { searchBlocks && drawFaces && !useBlockColor }.onValueSet(::rebuildMesh) - private val outlineColor by setting("Outline Color", Color(100, 150, 255, 128), "Color of the outlines") { searchBlocks && drawOutlines && !useBlockColor }.onValueSet(::rebuildMesh) + private val useBlockColor by setting("Use Block Color", false, "Use the color of the block instead") { searchBlocks }.onValueChange(::rebuildMesh) + private val faceColor by setting("Face Color", Color(100, 150, 255, 51), "Color of the surfaces") { searchBlocks && drawFaces && !useBlockColor }.onValueChange(::rebuildMesh) + private val outlineColor by setting("Outline Color", Color(100, 150, 255, 128), "Color of the outlines") { searchBlocks && drawOutlines && !useBlockColor }.onValueChange(::rebuildMesh) - private val outlineMode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode") { searchBlocks }.onValueSet(::rebuildMesh) + private val outlineMode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode") { searchBlocks }.onValueChange(::rebuildMesh) @JvmStatic - val barrier by setting("Solid Barrier Block", true, "Render barrier blocks").onValueChange { _, _ -> mc.worldRenderer.reload() } + val barrier by setting("Solid Barrier Block", true, "Render barrier blocks") // ToDo: I wanted to render this as a transparent / translucent block with a red tint. // Like the red stained glass block without the texture sprite. @@ -66,14 +64,7 @@ object BlockESP : Module( @JvmStatic val model: BlockStateModel get() = mc.bakedModelManager.missingModel - init { - onToggle { - if (barrier) mc.worldRenderer.reload() - } - } - - private val esp = newChunkedESP { world, x, y, z -> - val position = fastVectorOf(x, y, z) + private val esp = newChunkedESP { world, position -> val state = world.getBlockState(position) if (state.block !in blocks) return@newChunkedESP @@ -86,7 +77,7 @@ object BlockESP : Module( build(state, position.toBlockPos(), sides) } - private fun StaticESPRenderer.build( + private fun ShapeBuilder.build( state: BlockState, pos: BlockPos, sides: Int, @@ -94,9 +85,9 @@ object BlockESP : Module( val shape = outlineShape(state, pos) val blockColor = blockColor(state, pos) - if (drawFaces) buildFilledShape(shape, if (useBlockColor) blockColor else faceColor, sides) - if (drawOutlines) buildOutlineShape(shape, if (useBlockColor) blockColor else outlineColor, sides, outlineMode) + if (drawFaces) filled(shape, if (useBlockColor) blockColor else faceColor, sides) + if (drawOutlines) outline(shape, if (useBlockColor) blockColor else outlineColor, sides, outlineMode) } - private fun rebuildMesh(from: Any, to: Any): Unit = esp.rebuild() + private fun rebuildMesh(ctx: SafeContext, from: Any, to: Any): Unit = esp.rebuild() } diff --git a/src/main/kotlin/com/lambda/module/modules/render/Particles.kt b/src/main/kotlin/com/lambda/module/modules/render/Particles.kt index 7a7bc021b..d10e76a69 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Particles.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Particles.kt @@ -17,11 +17,50 @@ package com.lambda.module.modules.render +import com.lambda.Lambda.mc +import com.lambda.context.SafeContext +import com.lambda.event.events.MovementEvent +import com.lambda.event.events.PlayerEvent +import com.lambda.event.events.RenderEvent +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.graphics.buffer.vertex.attributes.VertexAttrib +import com.lambda.graphics.buffer.vertex.attributes.VertexMode +import com.lambda.graphics.gl.GlStateUtils.withBlendFunc +import com.lambda.graphics.gl.GlStateUtils.withDepth +import com.lambda.graphics.gl.Matrices +import com.lambda.graphics.gl.Matrices.buildWorldProjection +import com.lambda.graphics.gl.Matrices.withVertexTransform +import com.lambda.graphics.pipeline.VertexBuilder +import com.lambda.graphics.pipeline.VertexPipeline +import com.lambda.graphics.shader.Shader.Companion.shader +import com.lambda.interaction.request.rotating.Rotation +import com.lambda.module.Module +import com.lambda.module.modules.client.GuiSettings +import com.lambda.module.modules.client.GuiSettings.colorSpeed +import com.lambda.module.tag.ModuleTag +import com.lambda.util.extension.partialTicks +import com.lambda.util.math.DOWN +import com.lambda.util.math.MathUtils.random +import com.lambda.util.math.UP +import com.lambda.util.math.lerp +import com.lambda.util.math.multAlpha +import com.lambda.util.math.plus +import com.lambda.util.math.times +import com.lambda.util.math.transform +import com.lambda.util.player.MovementUtils.moveDelta +import com.lambda.util.world.raycast.InteractionMask +import com.mojang.blaze3d.opengl.GlConst.GL_ONE +import com.mojang.blaze3d.opengl.GlConst.GL_SRC_ALPHA +import net.minecraft.entity.Entity +import net.minecraft.util.math.Vec3d +import kotlin.math.sin + // FixMe: Do not call render stuff in the initialization block -/*object Particles : Module( +object Particles : Module( name = "Particles", description = "Spawns fancy particles", - defaultTags = setOf(ModuleTag.RENDER) + tag = ModuleTag.RENDER, ) { // ToDo: resort, cleanup settings private val duration by setting("Duration", 5.0, 1.0..500.0, 1.0) @@ -52,12 +91,10 @@ package com.lambda.module.modules.render particles.removeIf(Particle::update) } - listen { + listen { // Todo: interpolated tickbased upload? val builder = pipeline.build() - particles.forEach { - it.build(builder) - } + particles.forEach { it.build(builder) } withBlendFunc(GL_SRC_ALPHA, GL_ONE) { shader.use() @@ -182,4 +219,4 @@ package com.lambda.module.modules.render } } } -}*/ +} diff --git a/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt b/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt index 853d0d8b5..5a8ff3533 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt @@ -18,15 +18,10 @@ package com.lambda.module.modules.render import com.lambda.context.SafeContext -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.event.events.onStaticRender import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.buildSideMesh -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.builders.buildFilledShape -import com.lambda.graphics.renderer.esp.builders.buildOutline -import com.lambda.graphics.renderer.esp.builders.buildOutlineShape -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe @@ -52,7 +47,6 @@ import net.minecraft.entity.Entity import net.minecraft.entity.decoration.ItemFrameEntity import net.minecraft.entity.vehicle.AbstractMinecartEntity import net.minecraft.entity.vehicle.MinecartEntity -import net.minecraft.util.math.BlockPos import java.awt.Color object StorageESP : Module( @@ -64,14 +58,15 @@ object StorageESP : Module( private val distance by setting("Distance", 64.0, 10.0..256.0, 1.0, "Maximum distance for rendering").group(Group.General) /* Render settings */ - private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueSet { _, to -> if (!to) drawOutlines = true }.group(Group.Render) - private var drawOutlines: Boolean by setting("Draw Outlines", true, "Draw outlines of blocks").onValueSet { _, to -> if (!to) drawFaces = true }.group(Group.Render) - private val outlineMode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode").group(Group.Render) + private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueChange { _, to -> drawEdges = !to && !drawFaces }.group(Group.Render) + private var drawEdges: Boolean by setting("Draw Edges", true, "Draw edges of blocks").onValueChange { _, to -> drawFaces = !to && !drawEdges }.group(Group.Render) + private val mode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode").group(Group.Render) private val mesh by setting("Mesh", true, "Connect similar adjacent blocks").group(Group.Render) /* Color settings */ private val useBlockColor by setting("Use Block Color", true, "Use the color of the block instead").group(Group.Color) - private val alpha by setting("Alpha", 0.3, 0.1..1.0, 0.05).group(Group.Color) + private val facesAlpha by setting("Faces Alpha", 0.3, 0.1..1.0, 0.05).group(Group.Color) + private val edgesAlpha by setting("Edges Alpha", 0.3, 0.1..1.0, 0.05).group(Group.Color) // TODO: // val blockColors by setting("Block Colors", mapOf()) { page == Page.Color && !useBlockColor } @@ -118,15 +113,15 @@ object StorageESP : Module( ) init { - listen { event -> + onStaticRender { builder -> blockEntitySearch(distance) .filter { it::class in entities } - .forEach { event.renderer.build(it, it.pos, excludedSides(it)) } + .forEach { with(builder) { build(it, excludedSides(it)) } } val mineCarts = entitySearch(distance) val itemFrames = entitySearch(distance) (mineCarts + itemFrames) - .forEach { event.renderer.build(it, DirectionMask.ALL) } + .forEach { with(builder) { build(it, DirectionMask.ALL) } } // FixMe: Exclude entity shape sides } } @@ -144,32 +139,32 @@ object StorageESP : Module( } else DirectionMask.ALL } - private fun StaticESPRenderer.build( + private fun ShapeBuilder.build( block: BlockEntity, - pos: BlockPos, sides: Int, ) = runSafe { - val color = if (useBlockColor) { - blockColor(block.cachedState, pos) - } else getBlockEntityColor(block) ?: return@runSafe - val shape = outlineShape(block.cachedState, pos) + val color = + if (useBlockColor) blockColor(block.cachedState, block.pos) + else block.color ?: return@runSafe - if (drawFaces) buildFilledShape(shape, color.setAlpha(alpha), sides) - if (drawOutlines) buildOutlineShape(shape, color, sides, outlineMode) + val shape = outlineShape(block.cachedState, block.pos) + + if (drawFaces) filled(shape, color.setAlpha(facesAlpha), sides) + if (drawEdges) outline(shape, color.setAlpha(edgesAlpha), sides, mode) } - private fun StaticESPRenderer.build( + private fun ShapeBuilder.build( entity: Entity, sides: Int, ) = runSafe { - val color = getEntityColor(entity) ?: return@runSafe + val color = entity.color ?: return@runSafe - if (drawFaces) buildFilled(entity.boundingBox, color.setAlpha(alpha), sides) - if (drawOutlines) buildOutline(entity.boundingBox, color, sides, outlineMode) + if (drawFaces) filled(entity.boundingBox, color.setAlpha(facesAlpha), sides) + if (drawEdges) outline(entity.boundingBox, color.setAlpha(edgesAlpha), sides, mode) } - private fun getBlockEntityColor(block: BlockEntity?) = - when (block) { + private val BlockEntity?.color get() = + when (this) { is BarrelBlockEntity -> barrelColor is BlastFurnaceBlockEntity -> blastFurnaceColor is BrewingStandBlockEntity -> brewingStandColor @@ -184,8 +179,8 @@ object StorageESP : Module( else -> null } - private fun getEntityColor(entity: Entity?) = - when (entity) { + private val Entity?.color get() = + when (this) { is AbstractMinecartEntity -> cartColor is ItemFrameEntity -> itemFrameColor else -> null diff --git a/src/main/kotlin/com/lambda/threading/Threading.kt b/src/main/kotlin/com/lambda/threading/Threading.kt index 08dfab0a2..b08659907 100644 --- a/src/main/kotlin/com/lambda/threading/Threading.kt +++ b/src/main/kotlin/com/lambda/threading/Threading.kt @@ -97,8 +97,9 @@ inline fun runSafeConcurrent(crossinline block: suspend SafeContext.() -> Unit) * * @param block The task to be executed on the game's main thread. */ -inline fun recordRenderCall(crossinline block: () -> Unit) = +inline fun recordRenderCall(crossinline block: () -> Unit) { mc.renderTaskQueue.add { block() } +} /** * Executes a given task on the game's main thread.