so try to group hitboxes but I'm doing something wront. this doesn't work
This commit is contained in:
parent
d7a5a2913e
commit
3b8d715efb
@ -16,12 +16,11 @@ enum class GemstoneColors(val color: Int) {
|
|||||||
TOPAZ(0xFFFF55), // Yellow
|
TOPAZ(0xFFFF55), // Yellow
|
||||||
JASPER(0xFF55FF) // Magenta
|
JASPER(0xFF55FF) // Magenta
|
||||||
}
|
}
|
||||||
|
|
||||||
object GemstoneFinder {
|
object GemstoneFinder {
|
||||||
private var gemstoneList: ArrayList<GemstoneBlock> = ArrayList()
|
private var gemstoneClusters: ArrayList<GemstoneCluster> = ArrayList()
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
gemstoneList.clear()
|
gemstoneClusters.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun find() {
|
fun find() {
|
||||||
@ -40,6 +39,8 @@ object GemstoneFinder {
|
|||||||
)
|
)
|
||||||
val world = Minecraft.getMinecraft().thePlayer.worldObj
|
val world = Minecraft.getMinecraft().thePlayer.worldObj
|
||||||
|
|
||||||
|
val gemstonesMap = mutableMapOf<GemstoneColors, MutableList<BlockPos>>()
|
||||||
|
|
||||||
for (chunkX in minBounds.x / 16..maxBounds.x / 16) {
|
for (chunkX in minBounds.x / 16..maxBounds.x / 16) {
|
||||||
for (chunkZ in minBounds.z / 16..maxBounds.z / 16) {
|
for (chunkZ in minBounds.z / 16..maxBounds.z / 16) {
|
||||||
val chunk = world.getChunkFromChunkCoords(chunkX, chunkZ)
|
val chunk = world.getChunkFromChunkCoords(chunkX, chunkZ)
|
||||||
@ -73,8 +74,8 @@ object GemstoneFinder {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gemstoneColor != null && !gemstonesList(blockPos.x, blockPos.y, blockPos.z)) {
|
if (gemstoneColor != null) {
|
||||||
gemstoneList.add(GemstoneBlock(blockPos.x, blockPos.y, blockPos.z, gemstoneColor))
|
gemstonesMap.getOrPut(gemstoneColor) { mutableListOf() }.add(blockPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,62 +83,65 @@ object GemstoneFinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mergeAdjacentBlocks()
|
|
||||||
|
for ((color, positions) in gemstonesMap) {
|
||||||
|
val clusters = clusterGemstones(positions)
|
||||||
|
for (cluster in clusters) {
|
||||||
|
gemstoneClusters.add(GemstoneCluster(cluster, color))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mergeAdjacentBlocks() {
|
private fun clusterGemstones(positions: List<BlockPos>): List<List<BlockPos>> {
|
||||||
val mergedList = ArrayList<GemstoneBlock>()
|
val clusters = mutableListOf<List<BlockPos>>()
|
||||||
|
val visited = mutableSetOf<BlockPos>()
|
||||||
|
|
||||||
while (gemstoneList.isNotEmpty()) {
|
fun dfs(start: BlockPos, cluster: MutableList<BlockPos>) {
|
||||||
val firstBlock = gemstoneList.removeAt(0)
|
val stack = ArrayDeque<BlockPos>()
|
||||||
val group = mutableListOf(firstBlock)
|
stack.add(start)
|
||||||
|
|
||||||
val queue = ArrayDeque<GemstoneBlock>()
|
while (stack.isNotEmpty()) {
|
||||||
queue.add(firstBlock)
|
val pos = stack.removeLast()
|
||||||
|
if (pos in visited) continue
|
||||||
|
visited.add(pos)
|
||||||
|
cluster.add(pos)
|
||||||
|
|
||||||
while (queue.isNotEmpty()) {
|
// Check adjacent blocks in all six directions
|
||||||
val current = queue.removeFirst()
|
for (offset in listOf(BlockPos(1, 0, 0), BlockPos(-1, 0, 0), BlockPos(0, 1, 0), BlockPos(0, -1, 0), BlockPos(0, 0, 1), BlockPos(0, 0, -1))) {
|
||||||
val neighbors = gemstoneList.filter {
|
val neighbor = pos.add(offset)
|
||||||
it.color == current.color && isAdjacent(it, current)
|
if (neighbor in positions && neighbor !in visited) {
|
||||||
|
stack.add(neighbor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
group.addAll(neighbors)
|
|
||||||
gemstoneList.removeAll(neighbors)
|
|
||||||
queue.addAll(neighbors)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mergedList.add(mergeGroup(group))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gemstoneList = mergedList
|
for (pos in positions) {
|
||||||
}
|
if (pos !in visited) {
|
||||||
|
val cluster = mutableListOf<BlockPos>()
|
||||||
|
dfs(pos, cluster)
|
||||||
|
clusters.add(cluster)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isAdjacent(a: GemstoneBlock, b: GemstoneBlock): Boolean {
|
return clusters
|
||||||
return (a.x == b.x && a.y == b.y && (a.z == b.z + 1 || a.z == b.z - 1)) ||
|
|
||||||
(a.x == b.x && (a.y == b.y + 1 || a.y == b.y - 1) && a.z == b.z) ||
|
|
||||||
((a.x == b.x + 1 || a.x == b.x - 1) && a.y == b.y && a.z == b.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mergeGroup(group: List<GemstoneBlock>): GemstoneBlock {
|
|
||||||
val minX = group.minOf { it.x }
|
|
||||||
val minY = group.minOf { it.y }
|
|
||||||
val minZ = group.minOf { it.z }
|
|
||||||
val maxX = group.maxOf { it.x }
|
|
||||||
val maxY = group.maxOf { it.y }
|
|
||||||
val maxZ = group.maxOf { it.z }
|
|
||||||
return GemstoneBlock(minX, minY, minZ, group.first().color, maxX, maxY, maxZ)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun renderBlockOverlay(event: RenderWorldLastEvent) {
|
fun renderBlockOverlay(event: RenderWorldLastEvent) {
|
||||||
val player = Minecraft.getMinecraft().thePlayer
|
val player = Minecraft.getMinecraft().thePlayer
|
||||||
|
|
||||||
for (gemstone: GemstoneBlock in gemstoneList) {
|
for (cluster in gemstoneClusters) {
|
||||||
val startPos = BlockPos(gemstone.x, gemstone.y, gemstone.z)
|
RenderFuncs.drawClusterOutline(player, cluster.positions, event.partialTicks, cluster.color.color)
|
||||||
val endPos = BlockPos(gemstone.maxX, gemstone.maxY, gemstone.maxZ)
|
|
||||||
RenderFuncs.drawBlockOutline(player, startPos, endPos, event.partialTicks, gemstone.color.color)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class GemstoneCluster(
|
||||||
|
val positions: List<BlockPos>,
|
||||||
|
val color: GemstoneColors
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
data class GemstoneBlock(
|
data class GemstoneBlock(
|
||||||
val x: Int,
|
val x: Int,
|
||||||
val y: Int,
|
val y: Int,
|
||||||
@ -147,8 +151,4 @@ object GemstoneFinder {
|
|||||||
val maxY: Int = y,
|
val maxY: Int = y,
|
||||||
val maxZ: Int = z
|
val maxZ: Int = z
|
||||||
)
|
)
|
||||||
|
|
||||||
fun gemstonesList(x: Int, y: Int, z: Int): Boolean {
|
|
||||||
return gemstoneList.any { it.x == x && it.y == y && it.z == z }
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ import net.minecraft.client.renderer.GlStateManager
|
|||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.util.AxisAlignedBB
|
import net.minecraft.util.AxisAlignedBB
|
||||||
import net.minecraft.util.BlockPos
|
import net.minecraft.util.BlockPos
|
||||||
|
import net.minecraft.util.EnumFacing
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
|
|
||||||
@ -117,28 +118,15 @@ object RenderFuncs {
|
|||||||
RenderUtils.drawLine(pos1, pos2, lineColor, 2, false, partialTicks)
|
RenderUtils.drawLine(pos1, pos2, lineColor, 2, false, partialTicks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun drawClusterOutline(entity: Entity, positions: List<BlockPos>, partialTicks: Float, outlineColor: Int) {
|
||||||
fun drawBlockOutline(entity: Entity, startPos: BlockPos, endPos: BlockPos, partialTicks: Float, outlineColor: Int) {
|
|
||||||
val padding = 0.0020000000949949026
|
val padding = 0.0020000000949949026
|
||||||
|
|
||||||
|
// Correctly calculate the player's interpolated position
|
||||||
val entityX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks
|
val entityX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks
|
||||||
val entityY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks
|
val entityY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks
|
||||||
val entityZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks
|
val entityZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks
|
||||||
|
|
||||||
val minX = minOf(startPos.x.toDouble(), endPos.x.toDouble())
|
val world = Minecraft.getMinecraft().theWorld
|
||||||
val minY = minOf(startPos.y.toDouble(), endPos.y.toDouble())
|
|
||||||
val minZ = minOf(startPos.z.toDouble(), endPos.z.toDouble())
|
|
||||||
val maxX = maxOf(startPos.x.toDouble() + 1.0, endPos.x.toDouble() + 1.0)
|
|
||||||
val maxY = maxOf(startPos.y.toDouble() + 1.0, endPos.y.toDouble() + 1.0)
|
|
||||||
val maxZ = maxOf(startPos.z.toDouble() + 1.0, endPos.z.toDouble() + 1.0)
|
|
||||||
|
|
||||||
val boundingBox = AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ).expand(padding, padding, padding)
|
|
||||||
|
|
||||||
// Convert integer color to r, g, b, a values
|
|
||||||
val r = (outlineColor shr 16 and 0xFF) / 255.0f
|
|
||||||
val g = (outlineColor shr 8 and 0xFF) / 255.0f
|
|
||||||
val b = (outlineColor and 0xFF) / 255.0f
|
|
||||||
val a = (outlineColor shr 24 and 0xFF) / 255.0f
|
|
||||||
|
|
||||||
GL11.glPushMatrix()
|
GL11.glPushMatrix()
|
||||||
GlStateManager.disableTexture2D()
|
GlStateManager.disableTexture2D()
|
||||||
@ -150,11 +138,44 @@ object RenderFuncs {
|
|||||||
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
|
GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST)
|
||||||
GL11.glLineWidth(2.0f)
|
GL11.glLineWidth(2.0f)
|
||||||
|
|
||||||
|
// Convert integer color to r, g, b, a values
|
||||||
|
val r = (outlineColor shr 16 and 0xFF) / 255.0f
|
||||||
|
val g = (outlineColor shr 8 and 0xFF) / 255.0f
|
||||||
|
val b = (outlineColor and 0xFF) / 255.0f
|
||||||
|
val a = (outlineColor shr 24 and 0xFF) / 255.0f
|
||||||
|
|
||||||
// Set the color with alpha
|
// Set the color with alpha
|
||||||
GL11.glColor4f(r, g, b, a)
|
GL11.glColor4f(r, g, b, a)
|
||||||
|
|
||||||
// Draw the outline using the bounding box
|
// Iterate over the positions and draw the outline around each block
|
||||||
RenderUtils.drawBlock(boundingBox.offset(-entityX, -entityY, -entityZ), outlineColor, outlineColor)
|
for (pos in positions) {
|
||||||
|
val blockState = world.getBlockState(pos)
|
||||||
|
val boundingBox = blockState.block.getCollisionBoundingBox(world, pos, blockState)
|
||||||
|
?: AxisAlignedBB(pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble(), pos.x + 1.0, pos.y + 1.0, pos.z + 1.0).expand(padding, padding, padding)
|
||||||
|
|
||||||
|
// Offset the bounding box by the interpolated player position
|
||||||
|
val offsetBoundingBox = boundingBox.offset(-entityX, -entityY, -entityZ)
|
||||||
|
|
||||||
|
// Check adjacent blocks and only draw faces that are exposed (not adjacent to another gemstone block)
|
||||||
|
if (!positions.contains(pos.add(1, 0, 0))) {
|
||||||
|
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.EAST, outlineColor)
|
||||||
|
}
|
||||||
|
if (!positions.contains(pos.add(-1, 0, 0))) {
|
||||||
|
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.WEST, outlineColor)
|
||||||
|
}
|
||||||
|
if (!positions.contains(pos.add(0, 1, 0))) {
|
||||||
|
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.UP, outlineColor)
|
||||||
|
}
|
||||||
|
if (!positions.contains(pos.add(0, -1, 0))) {
|
||||||
|
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.DOWN, outlineColor)
|
||||||
|
}
|
||||||
|
if (!positions.contains(pos.add(0, 0, 1))) {
|
||||||
|
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.SOUTH, outlineColor)
|
||||||
|
}
|
||||||
|
if (!positions.contains(pos.add(0, 0, -1))) {
|
||||||
|
RenderUtils.drawBlockFace(offsetBoundingBox, EnumFacing.NORTH, outlineColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GL11.glDisable(GL11.GL_LINE_SMOOTH)
|
GL11.glDisable(GL11.GL_LINE_SMOOTH)
|
||||||
GL11.glDisable(GL11.GL_BLEND)
|
GL11.glDisable(GL11.GL_BLEND)
|
||||||
|
@ -8,6 +8,7 @@ import net.minecraft.client.renderer.Tessellator
|
|||||||
import net.minecraft.client.renderer.WorldRenderer
|
import net.minecraft.client.renderer.WorldRenderer
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
||||||
import net.minecraft.util.AxisAlignedBB
|
import net.minecraft.util.AxisAlignedBB
|
||||||
|
import net.minecraft.util.EnumFacing
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
|
|
||||||
@ -256,4 +257,63 @@ object RenderUtils {
|
|||||||
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
|
.color(outlineEndColor.red, outlineEndColor.green, outlineEndColor.blue, outlineEndColor.alpha).endVertex()
|
||||||
TESSELLATOR.draw()
|
TESSELLATOR.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun drawBlockFace(box: AxisAlignedBB, face: EnumFacing, color: Int) {
|
||||||
|
WORLD_RENDERER.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION_COLOR)
|
||||||
|
|
||||||
|
val r = (color shr 16 and 0xFF) / 255.0f
|
||||||
|
val g = (color shr 8 and 0xFF) / 255.0f
|
||||||
|
val b = (color and 0xFF) / 255.0f
|
||||||
|
val a = (color shr 24 and 0xFF) / 255.0f
|
||||||
|
|
||||||
|
GL11.glColor4f(r, g, b, a)
|
||||||
|
|
||||||
|
when (face) {
|
||||||
|
EnumFacing.UP -> {
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
|
||||||
|
}
|
||||||
|
EnumFacing.DOWN -> {
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
|
||||||
|
}
|
||||||
|
EnumFacing.NORTH -> {
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
|
||||||
|
}
|
||||||
|
EnumFacing.SOUTH -> {
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
|
||||||
|
}
|
||||||
|
EnumFacing.WEST -> {
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.maxY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.maxY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.minX, box.minY, box.minZ).endVertex()
|
||||||
|
}
|
||||||
|
EnumFacing.EAST -> {
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.minY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.maxY, box.maxZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.maxY, box.minZ).endVertex()
|
||||||
|
WORLD_RENDERER.pos(box.maxX, box.minY, box.minZ).endVertex()
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
TESSELLATOR.draw()
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user