diff options
6 files changed, 399 insertions, 1 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 904f47c29..bed769fa5 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -263,6 +263,7 @@ import at.hannibal2.skyhanni.features.mining.DeepCavernsParkour import at.hannibal2.skyhanni.features.mining.HighlightMiningCommissionMobs import at.hannibal2.skyhanni.features.mining.KingTalismanHelper import at.hannibal2.skyhanni.features.mining.crystalhollows.CrystalHollowsNamesInCore +import at.hannibal2.skyhanni.features.mining.crystalhollows.CrystalHollowsWalls import at.hannibal2.skyhanni.features.mining.eventtracker.MiningEventDisplay import at.hannibal2.skyhanni.features.mining.eventtracker.MiningEventTracker import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker @@ -565,6 +566,7 @@ class SkyHanniMod { loadModule(SeaCreatureMessageShortener()) loadModule(AshfangFreezeCooldown) loadModule(AshfangNextResetCooldown()) + loadModule(CrystalHollowsWalls()) loadModule(SummoningSoulsName()) loadModule(AshfangGravityOrbs()) loadModule(AshfangBlazingSouls()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/mining/AreaWallsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/mining/AreaWallsConfig.java new file mode 100644 index 000000000..5e2efff9d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/mining/AreaWallsConfig.java @@ -0,0 +1,20 @@ +package at.hannibal2.skyhanni.config.features.mining; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class AreaWallsConfig { + + @Expose + @ConfigOption(name = "Area Walls", desc = "Show walls between the main areas of the Crystal Hollows.") + @ConfigEditorBoolean + @FeatureToggle + public boolean enabled = false; + + @Expose + @ConfigOption(name = "In Nucleus", desc = "Shows the walls also when inside the Nucleus.") + @ConfigEditorBoolean + public boolean nucleus = false; +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java index 9a16e7ba8..77d70ea7a 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/mining/MiningConfig.java @@ -29,6 +29,11 @@ public class MiningConfig { public DeepCavernsParkourConfig deepCavernsParkour = new DeepCavernsParkourConfig(); @Expose + @ConfigOption(name = "Area Walls", desc = "") + @Accordion + public AreaWallsConfig crystalHollowsAreaWalls = new AreaWallsConfig(); + + @Expose @ConfigOption(name = "Highlight Commission Mobs", desc = "Highlight Mobs that are part of active commissions.") @ConfigEditorBoolean @FeatureToggle diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsWalls.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsWalls.kt new file mode 100644 index 000000000..2747ebca2 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/crystalhollows/CrystalHollowsWalls.kt @@ -0,0 +1,297 @@ +package at.hannibal2.skyhanni.features.mining.crystalhollows + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.RenderUtils +import at.hannibal2.skyhanni.utils.RenderUtils.expandBlock +import at.hannibal2.skyhanni.utils.RenderUtils.inflateBlock +import net.minecraft.client.Minecraft +import net.minecraft.util.AxisAlignedBB +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.awt.Color + +class CrystalHollowsWalls { + + val config get() = SkyHanniMod.feature.mining.crystalHollowsAreaWalls + + fun isEnabled() = config.enabled && IslandType.CRYSTAL_HOLLOWS.isInIsland() + + private enum class Areas(val color: Color) { + MITHRIL(LorenzColor.GREEN.addOpacity(60)), + PRECURSOR(LorenzColor.BLUE.addOpacity(60)), + JUNGLE(LorenzColor.LIGHT_PURPLE.addOpacity(60)), + GOBLIN(LorenzColor.GOLD.addOpacity(60)), + HEAT(LorenzColor.RED.addOpacity(60)), + NUCLEUS(LorenzColor.WHITE.addOpacity(60)) + ; + } + + private val expandTimes = 20 + + private val heatHeight = 64.0 + private val maxHeight = 190.0 + + private val minX = 0.0 + private val middleX = 513.0 + private val maxX = 1024.0 + + private val minZ = 0.0 + private val middleZ = 513.0 + private val maxZ = 1024.0 + + private val yViewOffset get() = -Minecraft.getMinecraft().thePlayer.getEyeHeight().toDouble() + + // Yes Hypixel has misaligned the nucleus + private val nucleusBB = AxisAlignedBB( + 463.0, heatHeight, 460.0, + 560.0, maxHeight, 563.0 + ) + + private val nucleusBBInflate = nucleusBB.inflateBlock(expandTimes) + private val nucleusBBExpand = nucleusBB.expandBlock(expandTimes) + + private val nucleusBBOffsetY get() = nucleusBB.offset(0.0, yViewOffset, 0.0) + + private fun Double.shiftPX() = this + LorenzVec.expandVector.x * expandTimes + private fun Double.shiftNX() = this - LorenzVec.expandVector.x * expandTimes + + private fun Double.shiftPY() = this + LorenzVec.expandVector.y * expandTimes + private fun Double.shiftNY() = this - LorenzVec.expandVector.y * expandTimes + + private fun Double.shiftPZ() = this + LorenzVec.expandVector.z * expandTimes + private fun Double.shiftNZ() = this - LorenzVec.expandVector.z * expandTimes + + @SubscribeEvent + fun onRender(event: LorenzRenderWorldEvent) { + if (!isEnabled()) return + val position = RenderUtils.getViewerPos(event.partialTicks) + if (position.y < heatHeight + yViewOffset) { + drawHeat(event) + } else if (nucleusBBOffsetY.isVecInside(position.toVec3())) { + if (!config.nucleus) return + drawNucleus(event) + } else if (position.x > middleX) { + if (position.z > middleZ) { + drawPrecursor(event) + } else { + drawMithril((event)) + } + } else { + if (position.z > middleZ) { + drawGoblin(event) + } else { + drawJungle(event) + } + } + } + + private fun drawGoblin(event: LorenzRenderWorldEvent) = RenderUtils.QuadDrawer.draw3D(event.partialTicks) { + drawArea(true, false, Areas.JUNGLE.color, Areas.PRECURSOR.color) + } + + private fun drawJungle(event: LorenzRenderWorldEvent) = RenderUtils.QuadDrawer.draw3D(event.partialTicks) { + drawArea(true, true, Areas.GOBLIN.color, Areas.MITHRIL.color) + } + + private fun drawPrecursor(event: LorenzRenderWorldEvent) = RenderUtils.QuadDrawer.draw3D(event.partialTicks) { + drawArea(false, false, Areas.MITHRIL.color, Areas.GOBLIN.color) + } + + private fun drawMithril(event: LorenzRenderWorldEvent) = RenderUtils.QuadDrawer.draw3D(event.partialTicks) { + drawArea(false, true, Areas.PRECURSOR.color, Areas.JUNGLE.color) + } + + private fun drawHeat(event: LorenzRenderWorldEvent) = RenderUtils.QuadDrawer.draw3D(event.partialTicks) { + val heatHeight = heatHeight.shiftNY() + draw( + LorenzVec(nucleusBB.minX, heatHeight, nucleusBB.minZ), + LorenzVec(nucleusBB.maxX, heatHeight, nucleusBB.minZ), + LorenzVec(nucleusBB.minX, heatHeight, nucleusBB.maxZ), + Areas.NUCLEUS.color + ) + + drawHeatAreaForHeat(false, false, Areas.PRECURSOR.color, heatHeight) + drawHeatAreaForHeat(false, true, Areas.MITHRIL.color, heatHeight) + drawHeatAreaForHeat(true, false, Areas.GOBLIN.color, heatHeight) + drawHeatAreaForHeat(true, true, Areas.JUNGLE.color, heatHeight) + } + + private fun drawNucleus(event: LorenzRenderWorldEvent) { + val southEastCorner = LorenzVec(nucleusBBInflate.minX, nucleusBBInflate.minY, nucleusBBInflate.minZ) + val southWestCorner = LorenzVec(nucleusBBInflate.minX, nucleusBBInflate.minY, nucleusBBInflate.maxZ) + val northEastCorner = LorenzVec(nucleusBBInflate.maxX, nucleusBBInflate.minY, nucleusBBInflate.minZ) + val northWestCorner = LorenzVec(nucleusBBInflate.maxX, nucleusBBInflate.minY, nucleusBBInflate.maxZ) + + val southWestTopCorner = LorenzVec(nucleusBBInflate.minX, nucleusBBInflate.maxY, nucleusBBInflate.maxZ) + val southEastTopCorner = LorenzVec(nucleusBBInflate.minX, nucleusBBInflate.maxY, nucleusBBInflate.minZ) + val northEastTopCorner = LorenzVec(nucleusBBInflate.maxX, nucleusBBInflate.maxY, nucleusBBInflate.minZ) + val northWestTopCorner = LorenzVec(nucleusBBInflate.maxX, nucleusBBInflate.maxY, nucleusBBInflate.maxZ) + + RenderUtils.QuadDrawer.draw3D(event.partialTicks) { + draw( + southEastCorner, + southWestCorner, + northEastCorner, + Areas.HEAT.color + ) + draw( + southEastCorner, + southEastTopCorner, + LorenzVec(nucleusBBInflate.minX, nucleusBBInflate.minY, middleZ), + Areas.JUNGLE.color + ) + draw( + southEastCorner, + southEastTopCorner, + LorenzVec(middleX, nucleusBBInflate.minY, nucleusBBInflate.minZ), + Areas.JUNGLE.color + ) + draw( + northWestCorner, + northWestTopCorner, + LorenzVec(nucleusBBInflate.maxX, nucleusBBInflate.minY, middleZ), + Areas.PRECURSOR.color + ) + draw( + northWestCorner, + northWestTopCorner, + LorenzVec(middleX, nucleusBBInflate.minY, nucleusBBInflate.maxZ), + Areas.PRECURSOR.color + ) + draw( + southWestCorner, + southWestTopCorner, + LorenzVec(nucleusBBInflate.minX, nucleusBBInflate.minY, middleZ), + Areas.GOBLIN.color, + ) + draw( + southWestCorner, + southWestTopCorner, + LorenzVec(middleX, nucleusBBInflate.minY, nucleusBBInflate.maxZ), + Areas.GOBLIN.color + ) + draw( + northEastCorner, + northEastTopCorner, + LorenzVec(nucleusBBInflate.maxX, nucleusBBInflate.minY, middleZ), + Areas.MITHRIL.color + ) + draw( + northEastCorner, + northEastTopCorner, + LorenzVec(middleX, nucleusBBInflate.minY, nucleusBBInflate.minZ), + Areas.MITHRIL.color + ) + } + } + + private fun RenderUtils.QuadDrawer.drawArea( + isMinXEsleMaxX: Boolean, + isMinZElseMaxZ: Boolean, + color1: Color, + color2: Color + ) { + val nucleusX = if (isMinXEsleMaxX) nucleusBBExpand.minX else nucleusBBExpand.maxX + val middleX = if (isMinXEsleMaxX) middleX.shiftNX() else middleX.shiftPX() + val x = if (isMinXEsleMaxX) minX else maxX + + val nucleusZ = if (isMinZElseMaxZ) nucleusBBExpand.minZ else nucleusBBExpand.maxZ + val middleZ = if (isMinZElseMaxZ) middleX.shiftNZ() else middleX.shiftPZ() + val z = if (isMinZElseMaxZ) minZ else maxZ + + val heatHeight = heatHeight.shiftPY() + + val nucleusBase = LorenzVec(nucleusX, heatHeight, nucleusZ) + + val nucleusZSideBase = LorenzVec(middleX, heatHeight, nucleusZ) + val nucleusXSideBase = LorenzVec(nucleusX, heatHeight, middleZ) + + drawHeatArea( + Areas.HEAT.color, + heatHeight, + nucleusX, + middleX, + x, + nucleusZ, + middleZ, + z + ) + draw( + nucleusXSideBase, + LorenzVec(nucleusX, maxHeight, middleZ), + LorenzVec(x, heatHeight, middleZ), + color1, + ) + draw( + nucleusZSideBase, + LorenzVec(middleX, maxHeight, nucleusZ), + LorenzVec(middleX, heatHeight, z), + color2, + ) + draw( + nucleusXSideBase, + nucleusBase, + LorenzVec(nucleusX, maxHeight, middleZ), + Areas.NUCLEUS.color, + ) + draw( + nucleusZSideBase, + nucleusBase, + LorenzVec(middleX, maxHeight, nucleusZ), + Areas.NUCLEUS.color, + ) + } + + private fun RenderUtils.QuadDrawer.drawHeatAreaForHeat( + isMinXEsleMaxX: Boolean, + isMinZElseMaxZ: Boolean, + color: Color, + heatHeight: Double, + ) = this.drawHeatArea( + color, + heatHeight, + nucleusX = if (isMinXEsleMaxX) nucleusBB.minX else nucleusBB.maxX, + middleX = if (isMinXEsleMaxX) middleX else middleX, + x = if (isMinXEsleMaxX) minX else maxX, + nucleusZ = if (isMinZElseMaxZ) nucleusBB.minZ else nucleusBB.maxZ, + middleZ = if (isMinZElseMaxZ) middleX else middleX, + z = if (isMinZElseMaxZ) minZ else maxZ, + ) + + private fun RenderUtils.QuadDrawer.drawHeatArea( + color: Color, + heatHeight: Double, + nucleusX: Double, + middleX: Double, + x: Double, + nucleusZ: Double, + middleZ: Double, + z: Double, + ) { + val nucleusBase = LorenzVec(nucleusX, heatHeight, nucleusZ) + + draw( + nucleusBase, + LorenzVec(nucleusX, heatHeight, z), + LorenzVec(middleX, heatHeight, nucleusZ), + color, + ) + draw( + nucleusBase, + LorenzVec(x, heatHeight, nucleusZ), + LorenzVec(nucleusX, heatHeight, middleZ), + color, + ) + draw( + nucleusBase, + LorenzVec(x, heatHeight, nucleusZ), + LorenzVec(nucleusX, heatHeight, z), + color, + ) + } + +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt index 534b54172..37e18e1d0 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.utils.LorenzUtils.round +import net.minecraft.client.renderer.GlStateManager import net.minecraft.entity.Entity import net.minecraft.network.play.server.S2APacketParticles import net.minecraft.util.AxisAlignedBB @@ -178,6 +179,8 @@ data class LorenzVec( return LorenzVec(x, y, z) } + fun negated() = LorenzVec(-x, -y, -z) + fun rotateXY(theta: Double) = LorenzVec(x * cos(theta) - y * sin(theta), x * sin(theta) + y * cos(theta), z) fun rotateXZ(theta: Double) = LorenzVec(x * cos(theta) + z * sin(theta), y, -x * sin(theta) + z * cos(theta)) fun rotateYZ(theta: Double) = LorenzVec(x, y * cos(theta) - z * sin(theta), y * sin(theta) + z * cos(theta)) @@ -201,6 +204,8 @@ data class LorenzVec( } fun getBlockBelowPlayer() = LocationUtils.playerLocation().roundLocationToBlock().add(y = -1.0) + + val expandVector = LorenzVec(0.0020000000949949026, 0.0020000000949949026, 0.0020000000949949026) } } @@ -224,3 +229,7 @@ fun S2APacketParticles.toLorenzVec() = LorenzVec(xCoordinate, yCoordinate, zCoor fun Array<Double>.toLorenzVec(): LorenzVec { return LorenzVec(this[0], this[1], this[2]) } + +fun RenderUtils.translate(vec: LorenzVec) = GlStateManager.translate(vec.x, vec.y, vec.z) + +fun AxisAlignedBB.expand(vec: LorenzVec) = this.expand(vec.x, vec.y, vec.z) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 8841f0d97..368394fae 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -21,6 +21,7 @@ import net.minecraft.client.gui.ScaledResolution import net.minecraft.client.renderer.GLAllocation import net.minecraft.client.renderer.GlStateManager import net.minecraft.client.renderer.Tessellator +import net.minecraft.client.renderer.WorldRenderer import net.minecraft.client.renderer.vertex.DefaultVertexFormats import net.minecraft.enchantment.Enchantment import net.minecraft.entity.Entity @@ -138,7 +139,8 @@ object RenderUtils { fun getViewerPos(partialTicks: Float) = exactLocation(Minecraft.getMinecraft().renderViewEntity, partialTicks) - fun AxisAlignedBB.expandBlock() = expand(0.0020000000949949026, 0.0020000000949949026, 0.0020000000949949026) + fun AxisAlignedBB.expandBlock(n: Int = 1) = expand(LorenzVec.expandVector.multiply(n)) + fun AxisAlignedBB.inflateBlock(n: Int = 1) = expand(LorenzVec.expandVector.multiply(-n)) /** * Taken from NotEnoughUpdates under Creative Commons Attribution-NonCommercial 3.0 @@ -1147,6 +1149,69 @@ object RenderUtils { GlStateManager.disableBlend() } + fun WorldRenderer.pos(vec: LorenzVec) = this.pos(vec.x, vec.y, vec.z) + + fun draw3DQuad( + middlePoint: LorenzVec, + sidePoint1: LorenzVec, + sidePoint2: LorenzVec, + c: Color, + partialTicks: Float = 0F, + ) = QuadDrawer.draw3D(partialTicks) { + draw( + middlePoint, + sidePoint1, + sidePoint2, + c + ) + } + + class QuadDrawer @PublishedApi internal constructor(val tessellator: Tessellator) { + val worldRenderer = tessellator.worldRenderer + inline fun draw( + middlePoint: LorenzVec, + sidePoint1: LorenzVec, + sidePoint2: LorenzVec, + c: Color + ) { + GlStateManager.color(c.red / 255f, c.green / 255f, c.blue / 255f, c.alpha / 255f) + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) + worldRenderer.pos(sidePoint1).endVertex() + worldRenderer.pos(middlePoint).endVertex() + worldRenderer.pos(sidePoint2).endVertex() + worldRenderer.pos(sidePoint1.add(sidePoint2).subtract(middlePoint)).endVertex() + tessellator.draw() + } + + companion object { + inline fun draw3D( + partialTicks: Float = 0F, + crossinline quads: QuadDrawer.() -> Unit + ) { + + GlStateManager.enableBlend() + GlStateManager.disableLighting() + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) + GlStateManager.disableTexture2D() + GlStateManager.disableCull() + + val tessellator = Tessellator.getInstance() + + GlStateManager.pushMatrix() + RenderUtils.translate(getViewerPos(partialTicks).negated()) + getViewerPos(partialTicks) + + quads.invoke(QuadDrawer(Tessellator.getInstance())) + + GlStateManager.popMatrix() + + GlStateManager.enableTexture2D() + GlStateManager.enableCull() + GlStateManager.disableBlend() + } + } + } + fun drawFilledBoundingBox_nea( aabb: AxisAlignedBB, c: Color, |