package com.github.itzilly.sbt.features import com.github.itzilly.sbt.SkyBlockTweaks import com.github.itzilly.sbt.renderer.RenderUtils import java.awt.Color import com.github.itzilly.sbt.util.Chatterbox import com.github.itzilly.sbt.util.DelayedFunction import com.github.itzilly.sbt.util.SimpleChatMsg import com.github.itzilly.sbt.util.Vecd3 import net.minecraft.block.Block import net.minecraft.client.Minecraft import net.minecraft.client.renderer.GlStateManager import net.minecraft.init.Blocks import net.minecraft.util.BlockPos import net.minecraft.entity.Entity import net.minecraft.tileentity.TileEntityChest import net.minecraft.util.AxisAlignedBB import net.minecraft.util.MovingObjectPosition import net.minecraftforge.client.event.ClientChatReceivedEvent import net.minecraftforge.client.event.RenderWorldLastEvent import net.minecraftforge.common.config.Configuration import net.minecraftforge.event.entity.player.PlayerInteractEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import org.lwjgl.opengl.GL11 data class ChestNode( val x: Int, val y: Int, val z: Int, ) fun chestNodeExists(x: Int, y: Int, z: Int): Boolean { return ChestEsp.chestList.any { it.x == x && it.y == y && it.z == z } } object ChestEsp { var chestList: ArrayList = ArrayList() var enabled: Boolean = SkyBlockTweaks.config.getBoolean("powderchestenable", Configuration.CATEGORY_GENERAL, true, "Enables/Disables Powder ChestESP") @SubscribeEvent fun chatMessageEvent(event: ClientChatReceivedEvent) { if (!enabled) return if (event.message.unformattedText == "You uncovered a treasure chest!") { DelayedFunction({ highlightChests() }, 5) } } @SubscribeEvent fun renderBlockOverlay(event: RenderWorldLastEvent) { if (!enabled) return val player = Minecraft.getMinecraft().thePlayer for (chest: ChestNode in chestList) { val pos = BlockPos(chest.x, chest.y, chest.z) drawChestOutline(player, pos, event.partialTicks) drawChestLine(pos, event.partialTicks) } } @SubscribeEvent fun rightClickEvent(event: PlayerInteractEvent) { if (!enabled) return if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { val pos = event.pos if (chestNodeExists(pos.x, pos.y, pos.z)) { chestList.removeIf { it.x == pos.x && it.y == pos.y && it.z == pos.z } checkChestLocations() } } } fun checkChestLocations() { for (chest in chestList) { if (chestNodeExists(chest.x, chest.y, chest.z)) { chestList.removeIf { it.x == chest.x && it.y == chest.y && it.z == chest.z } } } } fun highlightChests() { if (!enabled) return val searchRadius = 8 val world = Minecraft.getMinecraft().thePlayer.worldObj val posX = Minecraft.getMinecraft().thePlayer.posX val posY = Minecraft.getMinecraft().thePlayer.posY val posZ = Minecraft.getMinecraft().thePlayer.posZ val boundXMax = posX + searchRadius val boundXMin = posX - searchRadius val boundYMax = posY + searchRadius val boundYMin = posY - searchRadius val boundZMax = posZ + searchRadius val boundZMin = posZ - searchRadius for (x in boundXMin.toInt()..boundXMax.toInt()) { for (y in boundYMin.toInt()..boundYMax.toInt()) { for (z in boundZMin.toInt()..boundZMax.toInt()) { val block = world.getBlockState(BlockPos(x, y, z)).block if (block == Blocks.chest || block == Blocks.trapped_chest || block == Blocks.ender_chest) { val tileEntity = world.getTileEntity(BlockPos(x, y, z)) if (tileEntity is TileEntityChest) { if (tileEntity.numPlayersUsing != 0) { val point = ChestNode(x, y, z) if (!chestNodeExists(x, y, z)) { chestList.add(point) } } } } } } } checkChestLocations() } private fun drawChestOutline(entity: Entity, blockPos: BlockPos, partialTicks: Float) { val padding: Double = 0.0020000000949949026 val entityX: Double = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks val entityY: Double = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks val entityZ: Double = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks val outlineStartColor = 0xFFFFFF val outlineEndColor = 0xFFFFFF val world = Minecraft.getMinecraft().theWorld val blockState = world.getBlockState(blockPos) val block: Block = blockState.block // Create a default bounding box for blocks that don't have one val boundingBox: AxisAlignedBB = block.getCollisionBoundingBox(world, blockPos, blockState) ?: AxisAlignedBB( blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(), blockPos.x + 1.0, blockPos.y + 1.0, blockPos.z + 1.0 ).expand(padding, padding, padding) GL11.glPushMatrix() GlStateManager.disableTexture2D() GlStateManager.depthMask(false) GlStateManager.disableDepth() GL11.glEnable(GL11.GL_LINE_SMOOTH) GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST) GL11.glLineWidth(2.0f) GL11.glShadeModel(GL11.GL_SMOOTH) RenderUtils.drawBlock(boundingBox.offset(-entityX, -entityY, -entityZ), outlineStartColor, outlineEndColor) GL11.glLineWidth(2.0f) GL11.glDisable(GL11.GL_LINE_SMOOTH) GlStateManager.enableDepth() GlStateManager.depthMask(true) GlStateManager.enableAlpha() GlStateManager.enableTexture2D() GL11.glPopMatrix() } private fun drawChestLine(pos: BlockPos, partialTicks: Float) { val render = Minecraft.getMinecraft().renderViewEntity val rm = Minecraft.getMinecraft().renderManager // TODO: Fix this not working with view bobbing enabled val pos1 = Vecd3(rm.viewerPosX, rm.viewerPosY + render.eyeHeight, rm.viewerPosZ) val pos2 = Vecd3( pos.x.toDouble() + 0.5, // Center of the block pos.y.toDouble() + 0.5, // Center of the block pos.z.toDouble() + 0.5 // Center of the block ) val lineColor = Color(0xe310d5) RenderUtils.drawLine(pos1, pos2, lineColor, 2, false, partialTicks) } }