Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.lambda.module.modules.debug

import com.lambda.event.events.RenderEvent
import com.lambda.event.listener.SafeListener.Companion.listener
import com.lambda.graphics.renderer.esp.builders.build
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
import com.lambda.util.math.VecUtils.blockPos
import com.lambda.util.world.search
import net.minecraft.block.Blocks
import net.minecraft.util.math.Box
import net.minecraft.util.math.Vec3d
import net.minecraft.util.math.Vec3i
import java.awt.Color

object BlockTest : Module(
name = "BlockTest",
description = "BlockTest",
defaultTags = setOf(ModuleTag.DEBUG),
) {
private val rangeX by setting("Range X", 5.0, 0.1..7.0, 0.1, "Range X")
private val rangeY by setting("Range Y", 5.0, 0.1..7.0, 0.1, "Range Y")
private val rangeZ by setting("Range Z", 5.0, 0.1..7.0, 0.1, "Range Z")
private val stepX by setting("Step X", 1, 1..7, 1, "Step X")
private val stepY by setting("Step Y", 1, 1..7, 1, "Step Y")
private val stepZ by setting("Step Z", 1, 1..7, 1, "Step Z")

private val filledColor = Color(100, 150, 255, 128)
private val outlineColor = Color(100, 150, 255, 51)

init {
listener<RenderEvent.StaticESP> {
search {
blocks(
range = Vec3d(rangeX, rangeY, rangeZ),
step = Vec3i(stepX, stepY, stepZ),
) { _, block -> block.isOf(Blocks.DIAMOND_BLOCK) }.forEach { (pos, state) ->
state.getOutlineShape(world, pos.blockPos).boundingBoxes.forEach { box ->
it.renderer.build(box.offset(pos), filledColor, outlineColor)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.lambda.graphics.renderer.esp.builders.build
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
import com.lambda.util.math.ColorUtils.setAlpha
import com.lambda.util.world.WorldUtils.getClosestEntity
import com.lambda.util.world.search
import net.minecraft.entity.LivingEntity
import net.minecraft.util.math.Box
import java.awt.Color
Expand All @@ -29,12 +29,14 @@ object RenderTest : Module(

init {
listener<RenderEvent.DynamicESP> {
val entity = getClosestEntity<LivingEntity>(player.pos, 8.0) ?: return@listener
it.renderer.build(entity.dynamicBox, filledColor, outlineColor)
search {
val entity = closestEntity<LivingEntity>(8.0) ?: return@search
it.renderer.build(entity.dynamicBox, filledColor, outlineColor)
}
}

listener<RenderEvent.StaticESP> {
it.renderer.build(Box.of(player.pos, 0.3, 0.3, 0.3), filledColor, outlineColor)
}
}
}
}
15 changes: 7 additions & 8 deletions common/src/main/kotlin/com/lambda/util/collections/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterPointer(
predicate: (R) -> Boolean,
) {
var index = 0

for (element in this) {
when {
element is R && predicate(element) && destination != null -> {
iterator(element, index++)
destination.add(element)
}
val fulfilled = predicate(element as? R ?: continue)

element is R && predicate(element) && destination == null -> {
iterator(element, index++)
}
if (fulfilled && destination != null) {
destination.add(element)
iterator(element, index)
}

index++
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.lambda.util.primitives.extension

import net.minecraft.block.BlockState
import net.minecraft.block.Blocks
import net.minecraft.fluid.FluidState
import net.minecraft.fluid.Fluids
import net.minecraft.world.World

fun World.getBlockState(x: Int, y: Int, z: Int): BlockState {
if (isOutOfHeightLimit(y)) return Blocks.VOID_AIR.defaultState

val chunk = getChunk(x shr 4, z shr 4)
val sectionIndex = getSectionIndex(y)
if (sectionIndex < 0) return Blocks.VOID_AIR.defaultState

val section = chunk.getSection(sectionIndex)
return section.getBlockState(x and 0xF, y and 0xF, z and 0xF)
}

fun World.getFluidState(x: Int, y: Int, z: Int): FluidState {
if (isOutOfHeightLimit(y)) return Fluids.EMPTY.defaultState

val chunk = getChunk(x shr 4, z shr 4)
val sectionIndex = getSectionIndex(y)
if (sectionIndex < 0) return Fluids.EMPTY.defaultState

val section = chunk.getSection(sectionIndex)
return section.getFluidState(x and 0xF, y and 0xF, z and 0xF)
}
151 changes: 151 additions & 0 deletions common/src/main/kotlin/com/lambda/util/world/Position.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package com.lambda.util.world

import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraft.util.math.Vec3i

/**
* Represents a position in the world encoded as a long.
*
* [ X (26 bits) | Z (26 bits) | Y (12 bits) ]
*
* The position is encoded as a 64-bit long where the X and Z coordinates are stored in the 26 most significant bits,
* and the Y coordinate is stored in the 12 least significant bits.
* This encoding allows for a maximum world size of ±33,554,432 blocks
* in the X and Z directions and ±2,048 blocks in the Y direction, which is more than needed.
*/
typealias FastVector = Long

internal const val X_BITS = 26
internal const val Z_BITS = 26
internal const val Y_BITS = 12

internal const val X_SHIFT = Y_BITS + Z_BITS
internal const val Z_SHIFT = Y_BITS

internal const val X_MASK = (1L shl X_BITS) - 1L
internal const val Z_MASK = (1L shl Z_BITS) - 1L
internal const val Y_MASK = (1L shl Y_BITS) - 1L

internal const val MIN_X = -(1L shl X_BITS - 1)
internal const val MIN_Z = -(1L shl Z_BITS - 1)
internal const val MIN_Y = -(1L shl Y_BITS - 1)
internal const val MAX_X = (1L shl X_BITS - 1) - 1L
internal const val MAX_Z = (1L shl Z_BITS - 1) - 1L
internal const val MAX_Y = (1L shl Y_BITS - 1) - 1L

internal fun Long.bitSetTo(value: Long, position: Int, length: Int): Long {
val mask = (1L shl length) - 1L
return this and (mask shl position).inv() or (value and mask shl position)
}

/**
* Creates a new position from the given coordinates.
*/
fun fastVectorOf(x: Long, y: Long, z: Long): FastVector {
require(x in MIN_X..MAX_X) { "X coordinate out of bounds for $X_BITS bits: $x" }
require(y in MIN_Y..MAX_Y) { "Y coordinate out of bounds for $Y_BITS bits: $y" }
require(z in MIN_Z..MAX_Z) { "Z coordinate out of bounds for $Z_BITS bits: $z" }

return ((x and X_MASK) shl X_SHIFT) or ((z and Z_MASK) shl Z_SHIFT) or (y and Y_MASK)
}

/**
* Creates a new position from the given coordinates.
*/
fun fastVectorOf(x: Int, y: Int, z: Int): FastVector = fastVectorOf(x.toLong(), y.toLong(), z.toLong())

/**
* Gets the X coordinate from the position.
*/
val FastVector.x: Int
get() {
val x = (this shr X_SHIFT and X_MASK).toInt()
return if (x and (1 shl X_BITS - 1) != 0) x - (1 shl X_BITS) else x
}

/**
* Gets the Z coordinate from the position.
*/
val FastVector.z: Int
get() {
val z = (this shr Z_SHIFT and Z_MASK).toInt()
return if (z and (1 shl Z_BITS - 1) != 0) z - (1 shl Z_BITS) else z
}

/**
* Gets the Y coordinate from the position.
*/
val FastVector.y: Int
get() {
val y = (this and Y_MASK).toInt()
return if (y and (1 shl Y_BITS - 1) != 0) y - (1 shl Y_BITS) else y
}

/**
* Sets the X coordinate of the position.
*/
infix fun FastVector.withX(x: Int): FastVector = bitSetTo(x.toLong(), X_SHIFT, X_BITS)

/**
* Sets the Z coordinate of the position.
*/
infix fun FastVector.withZ(z: Int): FastVector = bitSetTo(z.toLong(), Z_SHIFT, Z_BITS)

/**
* Sets the Y coordinate of the position.
*/
infix fun FastVector.withY(y: Int): FastVector = bitSetTo(y.toLong(), 0, Y_BITS)

/**
* Adds the given value to the X coordinate.
*/
infix fun FastVector.addX(value: Int): FastVector = withX(x + value)

/**
* Adds the given value to the Z coordinate.
*/
infix fun FastVector.addZ(value: Int): FastVector = withZ(z + value)

/**
* Adds the given value to the Y coordinate.
*/
infix fun FastVector.addY(value: Int): FastVector = withY(y + value)

/**
* Adds the given vector to the position.
*/
infix fun FastVector.plus(vec: FastVector): FastVector = fastVectorOf(x + vec.x, y + vec.y, z + vec.z)

/**
* Adds the given vector to the position.
* @return The new position.
*/
infix fun FastVector.plus(vec: Vec3i): FastVector = fastVectorOf(x + vec.x, y + vec.y, z + vec.z)

/**
* Converts a [Vec3i] to a [FastVector].
* @return The encoded position.
*/
fun Vec3i.toFastVec(): FastVector = fastVectorOf(x.toLong(), y.toLong(), z.toLong())

/**
* Converts a [Vec3d] to a [FastVector].
* @return The encoded position.
*/
fun Vec3d.toFastVec(): FastVector = fastVectorOf(x.toLong(), y.toLong(), z.toLong())

/**
* Converts the [FastVector] into a [Vec3d].
*/
fun FastVector.toVec3d(): Vec3d = Vec3d(x.toDouble(), y.toDouble(), z.toDouble())

/**
* Converts the [FastVector] into a [Vec3i].
*/
fun FastVector.toVec3i(): Vec3i = Vec3i(x, y, z)

/**
* Converts the [FastVector] into a [BlockPos].
*/
fun FastVector.toBlockPos(): BlockPos = BlockPos(x, y, z)
Loading