From b01af78657ee336c3ebacacb4d6b11699ec0b957 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Sun, 10 Dec 2023 03:06:15 +0100 Subject: Add region selector (#732) Added WorldEdit region selection preview support. #732 --- src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt | 2 + .../hannibal2/skyhanni/config/commands/Commands.kt | 21 +++- .../at/hannibal2/skyhanni/data/ItemClickData.kt | 4 +- .../java/at/hannibal2/skyhanni/test/WorldEdit.kt | 117 +++++++++++++++++++++ .../java/at/hannibal2/skyhanni/utils/LorenzVec.kt | 7 +- .../at/hannibal2/skyhanni/utils/RenderUtils.kt | 59 +++++++++++ 6 files changed, 203 insertions(+), 7 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/test/WorldEdit.kt (limited to 'src/main/java') diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 947369f92..e4a912842 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -323,6 +323,7 @@ import at.hannibal2.skyhanni.test.TestCopyBestiaryValues import at.hannibal2.skyhanni.test.TestCopyRngMeterValues import at.hannibal2.skyhanni.test.TestExportTools import at.hannibal2.skyhanni.test.TestShowSlotNumber +import at.hannibal2.skyhanni.test.WorldEdit import at.hannibal2.skyhanni.test.command.CopyNearbyParticlesCommand import at.hannibal2.skyhanni.utils.EntityOutlineRenderer import at.hannibal2.skyhanni.utils.KeyboardManager @@ -686,6 +687,7 @@ class SkyHanniMod { loadModule(ParkourWaypointSaver()) loadModule(TestShowSlotNumber()) loadModule(SkyHanniDebugsAndTests) + loadModule(WorldEdit) loadModule(HotSwapDetection) PreInitFinishedEvent().postAndCatch() } diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt index cc8754d49..77b189589 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -46,6 +46,7 @@ import at.hannibal2.skyhanni.test.PacketTest import at.hannibal2.skyhanni.test.SkyHanniConfigSearchResetCommand import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests import at.hannibal2.skyhanni.test.TestBingo +import at.hannibal2.skyhanni.test.WorldEdit import at.hannibal2.skyhanni.test.command.CopyItemCommand import at.hannibal2.skyhanni.test.command.CopyNearbyEntitiesCommand import at.hannibal2.skyhanni.test.command.CopyNearbyParticlesCommand @@ -174,9 +175,18 @@ object Commands { "shresetendernodetracker", "Resets the Ender Node Tracker" ) { EnderNodeTracker.resetCommand(it) } - registerCommand("shresetarmordroptracker", "Resets the Armor Drop Tracker") { ArmorDropTracker.resetCommand(it) } - registerCommand("shresetfrozentreasuretracker", "Resets the Frozen Treasure Tracker") { FrozenTreasureTracker.resetCommand(it) } - registerCommand("shresetfishingtracker", "Resets the Frozen Treasure Tracker") { FishingProfitTracker.resetCommand(it) } + registerCommand( + "shresetarmordroptracker", + "Resets the Armor Drop Tracker" + ) { ArmorDropTracker.resetCommand(it) } + registerCommand( + "shresetfrozentreasuretracker", + "Resets the Frozen Treasure Tracker" + ) { FrozenTreasureTracker.resetCommand(it) } + registerCommand( + "shresetfishingtracker", + "Resets the Frozen Treasure Tracker" + ) { FishingProfitTracker.resetCommand(it) } registerCommand("shbingotoggle", "Toggle the bingo card display mode") { BingoCardDisplay.toggleCommand() } registerCommand( "shfarmingprofile", @@ -264,6 +274,11 @@ object Commands { registerCommand("shtestinquisitor", "dev command") { InquisitorWaypointShare.test() } registerCommand("shshowcropmoneycalculation", "dev command") { CropMoneyDisplay.toggleShowCalculation() } registerCommand("shcropspeedmeter", "Debugs how many crops you collect over time") { CropSpeedMeter.toggle() } + registerCommand0( + "shworldedit", + "Select regions in the world", + { WorldEdit.command(it) }, + { listOf("copy", "reset", "help") }) registerCommand( "shconfigsave", "Manually saving the config" diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt index 842cbcfcc..3d154666f 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt @@ -20,7 +20,7 @@ class ItemClickData { @SubscribeEvent fun onItemClickSend(event: PacketEvent.SendEvent) { val packet = event.packet - if (packet is C08PacketPlayerBlockPlacement) { + if (packet is C08PacketPlayerBlockPlacement && packet.placedBlockDirection != 255) { val position = packet.position.toLorenzVec() BlockClickEvent(ClickType.RIGHT_CLICK, position, packet.stack).postAndCatch() } @@ -50,4 +50,4 @@ class ItemClickData { EntityClickEvent(clickType, clickedEntity).postAndCatch() } -} \ No newline at end of file +} diff --git a/src/main/java/at/hannibal2/skyhanni/test/WorldEdit.kt b/src/main/java/at/hannibal2/skyhanni/test/WorldEdit.kt new file mode 100644 index 000000000..3dced63f7 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/test/WorldEdit.kt @@ -0,0 +1,117 @@ +package at.hannibal2.skyhanni.test + +import at.hannibal2.skyhanni.data.ClickType +import at.hannibal2.skyhanni.events.BlockClickEvent +import at.hannibal2.skyhanni.events.withAlpha +import at.hannibal2.skyhanni.utils.ClipboardUtils +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils +import at.hannibal2.skyhanni.utils.RenderUtils.expandBlock +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getItemId +import net.minecraft.util.AxisAlignedBB +import net.minecraft.util.BlockPos +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.awt.Color + +object WorldEdit { + var leftPos = null as BlockPos? + var rightPos = null as BlockPos? + + fun funAABB(left: BlockPos, right: BlockPos): AxisAlignedBB { + return AxisAlignedBB( + minOf(left.x, left.x + 1, right.x, right.x + 1).toDouble(), + minOf(left.y, left.y + 1, right.y, right.y + 1).toDouble(), + minOf(left.z, left.z + 1, right.z, right.z + 1).toDouble(), + maxOf(left.x, left.x + 1, right.x, right.x + 1).toDouble(), + maxOf(left.y, left.y + 1, right.y, right.y + 1).toDouble(), + maxOf(left.z, left.z + 1, right.z, right.z + 1).toDouble(), + ) + } + + val aabb + get() = leftPos?.let { l -> + rightPos?.let { r -> + funAABB(l, r) + } + } + + fun copyToClipboard() { + ClipboardUtils.copyToClipboard(generateCodeSnippet()) + } + + fun generateCodeSnippet(): String { + var text = "" + leftPos?.let { text += "val redLeft = net.minecraft.util.BlockPos(${it.x}, ${it.y}, ${it.z})\n" } + rightPos?.let { text += "val blueRight = net.minecraft.util.BlockPos(${it.x}, ${it.y}, ${it.z})\n" } + aabb?.let { text += "val aabb = net.minecraft.util.AxisAlignedBB(${it.minX}, ${it.minY}, ${it.minZ}, ${it.maxX}, ${it.maxY}, ${it.maxZ})\n" } + return text + } + + @SubscribeEvent + fun onBlockClick(event: BlockClickEvent) { + if (event.itemInHand?.getItemId() != "WOOD_AXE") return + if (event.clickType == ClickType.LEFT_CLICK) { + leftPos = event.position.toBlockPos() + } else if (event.clickType == ClickType.RIGHT_CLICK) { + rightPos = event.position.toBlockPos() + } + } + + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + leftPos = null + rightPos = null + } + + @SubscribeEvent + fun onRenderWorldLast(event: RenderWorldLastEvent) { + leftPos?.let { l -> + RenderUtils.drawWireframeBoundingBox_nea( + funAABB(l, l).expandBlock(), + Color.RED, + event.partialTicks + ) + } + rightPos?.let { r -> + RenderUtils.drawWireframeBoundingBox_nea( + funAABB(r, r).expandBlock(), + Color.BLUE, + event.partialTicks + ) + } + aabb?.let { + RenderUtils.drawFilledBoundingBox_nea( + it.expandBlock(), + Color(Color.CYAN.withAlpha(60), true), + partialTicks = event.partialTicks, + renderRelativeToCamera = false + ) + } + } + + fun command(it: Array) { + when (it.firstOrNull()) { + null, "help" -> { + LorenzUtils.chat("Use a wood axe and left/right click to select a region in the world. Then use /shworldedit copy or /shworldedit reset.") + } + + "copy" -> { + copyToClipboard() + LorenzUtils.chat("Copied text to clipboard.") + } + + "reset" -> { + leftPos = null + rightPos = null + LorenzUtils.chat("Reset selected region") + } + + else -> { + LorenzUtils.chat("Unknown subcommand") + } + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt index b3cd44032..2a35a488a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt @@ -23,7 +23,9 @@ data class LorenzVec( constructor(x: Float, y: Float, z: Float) : this(x.toDouble(), y.toDouble(), z.toDouble()) - fun toBlocPos(): BlockPos = BlockPos(x, y, z) + @Deprecated("Misspelled function name", replaceWith = ReplaceWith("toBlockPos()")) + fun toBlocPos(): BlockPos = toBlockPos() + fun toBlockPos(): BlockPos = BlockPos(x, y, z) fun toVec3(): Vec3 = Vec3(x, y, z) @@ -48,7 +50,8 @@ data class LorenzVec( return (dx * dx + dz * dz) } - fun add(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z) + fun add(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): LorenzVec = + LorenzVec(this.x + x, this.y + y, this.z + z) fun add(x: Int = 0, y: Int = 0, z: Int = 0): LorenzVec = LorenzVec(this.x + x, this.y + y, this.z + z) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index f9e2b7cdf..60beaf029 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -858,6 +858,65 @@ object RenderUtils { drawFilledBoundingBox_nea(aabb, c, alphaMultiplier, renderRelativeToCamera, drawVerticalBarriers, partialTicks) } + + fun drawWireframeBoundingBox_nea( + aabb: AxisAlignedBB, + c: Color, + partialTicks: Float, + ) { + GlStateManager.enableBlend() + GlStateManager.disableLighting() + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) + GlStateManager.disableTexture2D() + GlStateManager.disableCull() + val vp = getViewerPos(partialTicks) + val effectiveAABB = AxisAlignedBB( + aabb.minX - vp.x, aabb.minY - vp.y, aabb.minZ - vp.z, + aabb.maxX - vp.x, aabb.maxY - vp.y, aabb.maxZ - vp.z, + ) + val tessellator = Tessellator.getInstance() + val worldRenderer = tessellator.worldRenderer + + GlStateManager.color(c.red / 255f, c.green / 255f, c.blue / 255f, c.alpha / 255f) + // Bottom face + worldRenderer.begin(GL11.GL_LINE_LOOP, DefaultVertexFormats.POSITION) + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + tessellator.draw() + + // Top face + worldRenderer.begin(GL11.GL_LINE_LOOP, DefaultVertexFormats.POSITION) + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + tessellator.draw() + + + worldRenderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION) + + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + + tessellator.draw() + + GlStateManager.enableTexture2D() + GlStateManager.enableCull() + GlStateManager.disableBlend() + } + + fun drawFilledBoundingBox_nea( aabb: AxisAlignedBB, c: Color, -- cgit