From d74e65afb4a8b1bc6c7272406788af0eb78a6ce2 Mon Sep 17 00:00:00 2001 From: zuim Date: Fri, 4 Dec 2020 00:59:40 +0100 Subject: [PATCH] Added NewChunks to the Radar and improved unloading of NewChunks (#1656) Co-authored-by: Dominika --- .../kami/gui/kami/theme/staticui/RadarUI.kt | 83 ++++++++++++++++--- .../kami/module/modules/render/NewChunks.kt | 55 +++++++++--- 2 files changed, 112 insertions(+), 26 deletions(-) diff --git a/src/main/java/me/zeroeightsix/kami/gui/kami/theme/staticui/RadarUI.kt b/src/main/java/me/zeroeightsix/kami/gui/kami/theme/staticui/RadarUI.kt index 657852815..6608df2e9 100644 --- a/src/main/java/me/zeroeightsix/kami/gui/kami/theme/staticui/RadarUI.kt +++ b/src/main/java/me/zeroeightsix/kami/gui/kami/theme/staticui/RadarUI.kt @@ -3,6 +3,7 @@ package me.zeroeightsix.kami.gui.kami.theme.staticui import me.zeroeightsix.kami.gui.kami.component.Radar import me.zeroeightsix.kami.gui.rgui.render.AbstractComponentUI import me.zeroeightsix.kami.manager.managers.FriendManager +import me.zeroeightsix.kami.module.modules.render.NewChunks import me.zeroeightsix.kami.util.EntityUtils.isCurrentlyNeutral import me.zeroeightsix.kami.util.EntityUtils.isPassiveMob import me.zeroeightsix.kami.util.Wrapper @@ -10,6 +11,8 @@ import me.zeroeightsix.kami.util.color.ColorHolder import me.zeroeightsix.kami.util.graphics.GlStateUtils import me.zeroeightsix.kami.util.graphics.RenderUtils2D.drawCircleFilled import me.zeroeightsix.kami.util.graphics.RenderUtils2D.drawCircleOutline +import me.zeroeightsix.kami.util.graphics.RenderUtils2D.drawRectFilled +import me.zeroeightsix.kami.util.graphics.RenderUtils2D.drawRectOutline import me.zeroeightsix.kami.util.graphics.VertexHelper import me.zeroeightsix.kami.util.graphics.font.FontRenderAdapter import me.zeroeightsix.kami.util.math.Vec2d @@ -24,6 +27,13 @@ import kotlin.math.sqrt * Created by 086 on 11/08/2017. */ class RadarUI : AbstractComponentUI() { + private val filledCircleColor = ColorHolder(28, 28, 28, 200) + private val outlineCircleColor = ColorHolder(155, 144, 255, 255) + private val filledCircleColorDarker = ColorHolder(255, 255, 255, 224) + private val rectFilledColor = ColorHolder(100, 100, 100, 100) + private val rectOutlineColor = ColorHolder(255, 0, 0, 100) + private val rectFilledColorOther = ColorHolder(255, 0, 0, 100) + private val radius = 45.0f override fun handleSizeComponent(component: Radar?) { component!! @@ -41,33 +51,64 @@ class RadarUI : AbstractComponentUI() { glTranslated(component.width / 2.0, component.height / 2.0, 0.0) val vertexHelper = VertexHelper(GlStateUtils.useVbo()) - drawCircleFilled(vertexHelper, radius = radius.toDouble(), color = ColorHolder(28, 28, 28, 200)) - drawCircleOutline(vertexHelper, radius = radius.toDouble(), lineWidth = 1.8f, color = ColorHolder(155, 144, 255, 255)) - drawCircleFilled(vertexHelper, radius = 2.0 / scale, color = ColorHolder(255, 255, 255, 224)) - + drawCircleFilled(vertexHelper, radius = radius.toDouble(), color = filledCircleColor) + drawCircleOutline(vertexHelper, radius = radius.toDouble(), lineWidth = 1.8f, color = outlineCircleColor) glRotatef(Wrapper.player!!.rotationYaw + 180, 0f, 0f, -1f) + + if (NewChunks.isEnabled && NewChunks.isRadarMode) renderNewChunks(vertexHelper) + for (entity in Wrapper.world!!.loadedEntityList) { if (entity == null || entity.isDead || entity == Wrapper.player) continue val dX = entity.posX - Wrapper.player!!.posX val dZ = entity.posZ - Wrapper.player!!.posZ val distance = sqrt(dX.pow(2) + dZ.pow(2)) - if (distance > radius * scale || abs(Wrapper.player!!.posY - entity.posY) > 30) continue + if (distance > radius * NewChunks.radarScale.value || abs(Wrapper.player!!.posY - entity.posY) > 30) continue val color = getColor(entity) - drawCircleFilled(vertexHelper, Vec2d(dX / scale, dZ / scale), 2.5 / scale, color = color) + drawCircleFilled(vertexHelper, Vec2d(dX / NewChunks.radarScale.value, dZ / NewChunks.radarScale.value), 2.5 / NewChunks.radarScale.value, color = color) } - FontRenderAdapter.drawString("\u00A77z+", -FontRenderAdapter.getStringWidth("+z") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = false) + drawCircleFilled(vertexHelper, radius = 1.0, color = filledCircleColorDarker) + + FontRenderAdapter.drawString("\u00A77z+", -FontRenderAdapter.getStringWidth("+z") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = true) glRotatef(90f, 0f, 0f, 1f) - FontRenderAdapter.drawString("\u00A77x-", -FontRenderAdapter.getStringWidth("+x") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = false) + FontRenderAdapter.drawString("\u00A77x-", -FontRenderAdapter.getStringWidth("+x") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = true) glRotatef(90f, 0f, 0f, 1f) - FontRenderAdapter.drawString("\u00A77z-", -FontRenderAdapter.getStringWidth("-z") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = false) + FontRenderAdapter.drawString("\u00A77z-", -FontRenderAdapter.getStringWidth("-z") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = true) glRotatef(90f, 0f, 0f, 1f) - FontRenderAdapter.drawString("\u00A77x+", -FontRenderAdapter.getStringWidth("+x") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = false) + FontRenderAdapter.drawString("\u00A77x+", -FontRenderAdapter.getStringWidth("+x") / 2f, radius - FontRenderAdapter.getFontHeight(), drawShadow = true) glPopMatrix() } + private fun renderNewChunks(vertexHelper: VertexHelper) { + val playerOffset = Vec2d((Wrapper.player!!.posX - (Wrapper.player!!.chunkCoordX shl 4)), (Wrapper.player!!.posZ - (Wrapper.player!!.chunkCoordZ shl 4))) + val chunkDist = (radius * NewChunks.radarScale.value).toInt() shr 4 + for (chunkX in -chunkDist..chunkDist) { + for (chunkZ in -chunkDist..chunkDist) { + val pos0 = getChunkPos(chunkX, chunkZ, playerOffset) + val pos1 = getChunkPos(chunkX + 1, chunkZ + 1, playerOffset) + + if (squareInRadius(pos0, pos1)) { + val chunk = Wrapper.world!!.getChunk(Wrapper.player!!.chunkCoordX + chunkX, Wrapper.player!!.chunkCoordZ + chunkZ) + if (!chunk.isLoaded) + drawRectFilled(vertexHelper, pos0, pos1, rectFilledColor) + drawRectOutline(vertexHelper, pos0, pos1, 0.3f, rectOutlineColor) + } + } + } + + for (chunk in NewChunks.chunks) { + + val pos0 = getChunkPos(chunk.x - Wrapper.player!!.chunkCoordX, chunk.z - Wrapper.player!!.chunkCoordZ, playerOffset) + val pos1 = getChunkPos(chunk.x - Wrapper.player!!.chunkCoordX + 1, chunk.z - Wrapper.player!!.chunkCoordZ + 1, playerOffset) + + if (squareInRadius(pos0, pos1)) { + drawRectFilled(vertexHelper, pos0, pos1, rectFilledColorOther) + } + } + } + private fun getColor(entity: Entity): ColorHolder { return if (isPassiveMob(entity) || FriendManager.isFriend(entity.name)) { // green ColorHolder(32, 224, 32, 224) @@ -78,8 +119,24 @@ class RadarUI : AbstractComponentUI() { } } - companion object { - const val scale = 2.0 - const val radius = 45.0f + // p2.x > p1.x and p2.y > p1.y is assumed + private fun squareInRadius(p1: Vec2d, p2: Vec2d): Boolean { + return if ((p1.x + p2.x) / 2 > 0) { + if ((p1.y + p2.y) / 2 > 0) { + p2.length() + } else { + Vec2d(p2.x, p1.y).length() + } + } else { + if ((p1.y + p2.y) / 2 > 0) { + Vec2d(p1.x, p2.y).length() + } else { + p1.length() + } + } < radius + } + + private fun getChunkPos(x: Int, z: Int, playerOffset: Vec2d): Vec2d { + return Vec2d((x shl 4).toDouble(), (z shl 4).toDouble()).subtract(playerOffset).divide(NewChunks.radarScale.value) } } \ No newline at end of file diff --git a/src/main/java/me/zeroeightsix/kami/module/modules/render/NewChunks.kt b/src/main/java/me/zeroeightsix/kami/module/modules/render/NewChunks.kt index 2a834e42a..d781fea56 100644 --- a/src/main/java/me/zeroeightsix/kami/module/modules/render/NewChunks.kt +++ b/src/main/java/me/zeroeightsix/kami/module/modules/render/NewChunks.kt @@ -40,17 +40,21 @@ object NewChunks : Module() { private val saveInRegionFolder = register(Settings.booleanBuilder("InRegion").withValue(false).withVisibility { saveNewChunks.value }) private val alsoSaveNormalCoords = register(Settings.booleanBuilder("SaveNormalCoords").withValue(false).withVisibility { saveNewChunks.value }) private val closeFile = register(Settings.booleanBuilder("CloseFile").withValue(false).withVisibility { saveNewChunks.value }) - private val yOffset = register(Settings.integerBuilder("YOffset").withValue(0).withRange(-256, 256).withStep(4)) - private val customColor = register(Settings.b("CustomColor", false)) - private val red = register(Settings.integerBuilder("Red").withRange(0, 255).withValue(255).withStep(1).withVisibility { customColor.value }) - private val green = register(Settings.integerBuilder("Green").withRange(0, 255).withValue(255).withStep(1).withVisibility { customColor.value }) - private val blue = register(Settings.integerBuilder("Blue").withRange(0, 255).withValue(255).withStep(1).withVisibility { customColor.value }) + private val renderMode = register(Settings.e("RenderMode", RenderMode.BOTH)) + private val yOffset = register(Settings.integerBuilder("YOffset").withValue(0).withRange(-256, 256).withStep(4).withVisibility { isWorldMode }) + private val customColor = register(Settings.booleanBuilder("CustomColor").withValue(false).withVisibility { isWorldMode }) + private val red = register(Settings.integerBuilder("Red").withRange(0, 255).withValue(255).withStep(1).withVisibility { customColor.value && isWorldMode }) + private val green = register(Settings.integerBuilder("Green").withRange(0, 255).withValue(255).withStep(1).withVisibility { customColor.value && isWorldMode }) + private val blue = register(Settings.integerBuilder("Blue").withRange(0, 255).withValue(255).withStep(1).withVisibility { customColor.value && isWorldMode }) private val range = register(Settings.integerBuilder("RenderRange").withValue(256).withRange(64, 1024).withStep(64)) + val radarScale = register(Settings.doubleBuilder("RadarScale").withRange(1.0, 10.0).withValue(2.0).withStep(0.1).withVisibility { isRadarMode }) + private val removeMode = register(Settings.e("RemoveMode", RemoveMode.MAX_NUM)) + private val maxNum = register(Settings.integerBuilder("MaxNum").withRange(1000, 100_000).withValue(10_000).withStep(1000).withVisibility { removeMode.value == RemoveMode.MAX_NUM }) private var lastSetting = LastSetting() private var logWriter: PrintWriter? = null private val timer = TimerUtils.TickTimer(TimerUtils.TimeUnit.MINUTES) - private val chunks = ArrayList() + val chunks = HashSet() override fun onDisable() { logWriterClose() @@ -71,6 +75,7 @@ object NewChunks : Module() { } listener { + if (renderMode.value == RenderMode.RADAR) return@listener val y = yOffset.value.toDouble() + if (relative.value) getInterpolatedPos(mc.player, KamiTessellator.pTicks()).y else 0.0 glLineWidth(2.0f) GlStateUtils.depth(false) @@ -92,10 +97,22 @@ object NewChunks : Module() { if (it.packet.isFullChunk) return@listener chunks.add(it.chunk) if (saveNewChunks.value) saveNewChunk(it.chunk) + if (removeMode.value == RemoveMode.MAX_NUM && chunks.size > maxNum.value) { + var removeChunk = chunks.first() + var maxDist = Double.MIN_VALUE + chunks.forEach { c -> + if (c.pos.getDistanceSq(mc.player) > maxDist) { + maxDist = c.pos.getDistanceSq(mc.player) + removeChunk = c + } + } + chunks.remove(removeChunk) + } } listener { - chunks.remove(it.chunk) + if (removeMode.value == RemoveMode.UNLOAD) + chunks.remove(it.chunk) } } @@ -154,7 +171,7 @@ object NewChunks : Module() { // If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file if (mc.isSingleplayer) { try { - file = Objects.requireNonNull(mc.getIntegratedServer())!!.getWorld(dimension).chunkSaveLocation + file = mc.integratedServer?.getWorld(dimension)?.chunkSaveLocation } catch (e: Exception) { e.printStackTrace() KamiMod.LOG.error("some exception happened when getting canonicalFile -> " + e.message) @@ -201,7 +218,7 @@ object NewChunks : Module() { var folderName: String when (saveOption.value) { SaveOption.LITE_LOADER_WDL -> { - folderName = Objects.requireNonNull(mc.getCurrentServerData())!!.serverName + folderName = mc.currentServerData?.serverName ?: "Offline" rV = File(rV, "saves") rV = File(rV, folderName) } @@ -218,7 +235,7 @@ object NewChunks : Module() { } } else -> { - folderName = Objects.requireNonNull(mc.getCurrentServerData())!!.serverName + "-" + mc.getCurrentServerData()!!.serverIP + folderName = mc.currentServerData?.serverName + "-" + mc.currentServerData?.serverIP if (SystemUtils.IS_OS_WINDOWS) { folderName = folderName.replace(":", "_") } @@ -232,7 +249,7 @@ object NewChunks : Module() { // if there is no port then we have to manually include the standard port.. private val nHackInetName: String get() { - var folderName = Objects.requireNonNull(mc.getCurrentServerData())!!.serverIP + var folderName = mc.currentServerData?.serverIP ?: "Offline" if (SystemUtils.IS_OS_WINDOWS) { folderName = folderName.replace(":", "_") } @@ -260,6 +277,18 @@ object NewChunks : Module() { EXTRA_FOLDER, LITE_LOADER_WDL, NHACK_WDL } + @Suppress("unused") + private enum class RemoveMode { + UNLOAD, MAX_NUM, NEVER + } + + enum class RenderMode { + WORLD, RADAR, BOTH + } + + val isRadarMode get() = renderMode.value == RenderMode.BOTH || renderMode.value == RenderMode.RADAR + private val isWorldMode get() = renderMode.value == RenderMode.BOTH || renderMode.value == RenderMode.WORLD + private class LastSetting { var lastSaveOption: SaveOption? = null var lastInRegion = false @@ -281,7 +310,7 @@ object NewChunks : Module() { || saveInRegionFolder.value != lastInRegion || alsoSaveNormalCoords.value != lastSaveNormal || dimension != mc.player.dimension - || mc.getCurrentServerData()?.serverIP != ip + || mc.currentServerData?.serverIP != ip } private fun update() { @@ -289,7 +318,7 @@ object NewChunks : Module() { lastInRegion = saveInRegionFolder.value lastSaveNormal = alsoSaveNormalCoords.value dimension = mc.player.dimension - ip = Objects.requireNonNull(mc.getCurrentServerData())!!.serverIP + ip = mc.currentServerData?.serverIP } }