diff options
author | Appability <appable@icloud.com> | 2022-10-13 18:58:00 -0700 |
---|---|---|
committer | Appability <appable@icloud.com> | 2022-10-13 18:58:00 -0700 |
commit | d0cbc11018c8126575117aaeb2b861957386fa9a (patch) | |
tree | c5419fb1f00b147604bded231c1388d6b391d27e /src/main/kotlin/com | |
parent | c599ee0d78ed8bc17488636f2d9b9b1d5b6dd4a8 (diff) | |
download | AmbientAddons-d0cbc11018c8126575117aaeb2b861957386fa9a.tar.gz AmbientAddons-d0cbc11018c8126575117aaeb2b861957386fa9a.tar.bz2 AmbientAddons-d0cbc11018c8126575117aaeb2b861957386fa9a.zip |
steal a bunch of code from sbc! +melodyhelper, kuudra ready, wither shield overlay
Diffstat (limited to 'src/main/kotlin/com')
17 files changed, 651 insertions, 16 deletions
diff --git a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt index b87b28b..a7c6458 100644 --- a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt +++ b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt @@ -1,12 +1,16 @@ import com.ambientaddons.commands.AmbientCommand import com.ambientaddons.config.Config import com.ambientaddons.config.PersistentData +import com.ambientaddons.features.display.WitherShieldOverlay import com.ambientaddons.features.dungeon.* +import com.ambientaddons.features.dungeon.terminals.MelodyHelper import com.ambientaddons.features.misc.BonzoMask import com.ambientaddons.features.keybinds.PerspectiveKeybind import com.ambientaddons.features.keybinds.SendLastMessageKeybind import com.ambientaddons.features.misc.CancelInteractions +import com.ambientaddons.features.misc.KuudraReady import com.ambientaddons.utils.SkyBlock +import com.ambientaddons.utils.dungeon.DungeonPlayers import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiScreen import net.minecraft.client.settings.KeyBinding @@ -54,7 +58,12 @@ class AmbientAddons { ShortbowClicker, BonzoMask, PerspectiveKeybind, - SendLastMessageKeybind + SendLastMessageKeybind, + DungeonPlayers, + MelodyHelper, + WitherShieldOverlay, + KuudraReady, + DungeonHighlights ).forEach(MinecraftForge.EVENT_BUS::register) keyBinds.values.forEach(ClientRegistry::registerKeyBinding) } diff --git a/src/main/kotlin/com/ambientaddons/config/Config.kt b/src/main/kotlin/com/ambientaddons/config/Config.kt index 722a853..00017c3 100644 --- a/src/main/kotlin/com/ambientaddons/config/Config.kt +++ b/src/main/kotlin/com/ambientaddons/config/Config.kt @@ -8,19 +8,102 @@ import java.io.File object Config : Vigilant( File(AmbientAddons.configDirectory, "config.toml"), AmbientAddons.metadata.name ) { + + var kuudraReady = false + + var batHighlight = 0 + var batColor = Color.CYAN + var saHighlight = 0 + var saColor = Color.CYAN + var starredHighlight = 0 + var starredColor = Color.CYAN + var bestiaryHighlight = 0 + var bestiaryColor = Color.MAGENTA + + + var blockLowReroll = false var autoBuyChest = 0 var autoReady = 0 var maskWarning = false + var witherShieldDisplay = 0 + var terminatorCps = 0 var cancelInteractions = false var closeSecretChests = false var ignoreCarpet = false + var melodyBlockMisclicks = false + var melodyAnnouncement = "Meowlody on me!" + var throttledAnnouncement = "Hi! This is Hypixel Support. We noticed that your runs are actually efficient so we’re throttling this menu. Enjoy slower runs, dipshit. Hope Goldor kills you. Meow." init { + category("Misc") { + switch( + ::kuudraReady, + name = "Automatically ready in Kuudra", + description = "Automatically clicks the ready pane when the ready GUI is opened." + ) + } + + category("Highlights") { + subcategory("Bat highlight") { + selector( + ::batHighlight, + name = "Bat highlight", + description = "Show bat secrets", + options = listOf("Off", "Highlight", "ESP") + ) + color( + ::batColor, + name = "Bat highlight color", + description = "Color of bat secrets", + ) + } + subcategory("Shadow assassin highlight") { + selector( + ::saHighlight, + name = "Shadow assassin highlight", + description = "Show shadow assassins (without this, they will not be highlighted even when starred.)", + options = listOf("Off", "Highlight", "ESP") + ) + color( + ::saColor, + name = "Shadow assassin highlight color", + description = "Color of shadow assassins", + ) + } + subcategory("Starred mob highlight") { + selector( + ::starredHighlight, + name = "Starred mob highlight", + description = "Show bat secrets", + options = listOf("Off", "Highlight", "ESP") + ) + color( + ::starredColor, + name = "Starred mob highlight color", + description = "Color of starred mobs", + ) + } + subcategory("Bestiary highlight") { + selector( + ::bestiaryHighlight, + name = "Bestiary highlight", + description = "Show cave spiders and snipers. Disabled automatically when idkmansry is nearby.", + options = listOf("Off", "Highlight", "ESP") + ) + color( + ::bestiaryColor, + name = "Bestiary highlight color", + description = "Color of bestiary mobs.", + ) + } + } + + category("Pre/Post Dungeon") { subcategory("Chest QOL") { switch( @@ -43,7 +126,7 @@ object Config : Vigilant( ) } - category("Displays") { + category("Notifications") { switch( ::maskWarning, name = "Mask proc warning", @@ -51,6 +134,15 @@ object Config : Vigilant( ) } + category("Displays") { + selector( + ::witherShieldDisplay, + name = "Wither shield display", + description = "Displays remaining wither shield duration", + options = listOf("Off", "Default", "Shadow", "Outline") + ) + } + category("Dungeon") { subcategory("Miscellaneous QOL") { slider( @@ -73,6 +165,21 @@ object Config : Vigilant( switch( ::ignoreCarpet, name = "Ignore carpet hitboxes", description = "Removes all carpet hitboxes" ) + switch( + ::melodyBlockMisclicks, + name = "Block misclicks on Melody terminal", + description = "Prevents clicking Melody terminal when not aligned." + ) + text( + ::melodyAnnouncement, + name = "Melody terminal announcement", + description = "Announces that Melody terminal was opened in party chat; leave empty to disable." + ) + text( + ::throttledAnnouncement, + name = "Throttled terminal announcement", + description = "Announces that a terminal was throttled in party chat; leave empty to disable." + ) } } } diff --git a/src/main/kotlin/com/ambientaddons/features/display/WitherShieldOverlay.kt b/src/main/kotlin/com/ambientaddons/features/display/WitherShieldOverlay.kt new file mode 100644 index 0000000..fa210aa --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/display/WitherShieldOverlay.kt @@ -0,0 +1,41 @@ +package com.ambientaddons.features.display + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Alignment +import com.ambientaddons.utils.render.OverlayUtils +import com.ambientaddons.utils.SkyBlock +import com.ambientaddons.utils.dungeon.TextStyle +import net.minecraft.client.gui.ScaledResolution +import net.minecraftforge.client.event.ClientChatReceivedEvent +import net.minecraftforge.client.event.RenderGameOverlayEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.math.ceil +import kotlin.math.roundToInt + +object WitherShieldOverlay { + private var witherImpactEndTime = 0L + + @SubscribeEvent + fun onRenderOverlay(event: RenderGameOverlayEvent) { + if (event.type != RenderGameOverlayEvent.ElementType.TEXT) return + if (!SkyBlock.inSkyblock || config.witherShieldDisplay == 0) return + val diff = ((witherImpactEndTime - System.currentTimeMillis()) / 1000.0).takeIf { it >= 0 } ?: return + val display = ceil(diff).roundToInt().toString() + val resolution = ScaledResolution(mc) + val x = resolution.scaledWidth / 2 + 1 + val y = resolution.scaledHeight / 2 + 10 + val style = TextStyle.fromInt(config.witherShieldDisplay - 1) ?: return + OverlayUtils.drawString(x, y, display, style, Alignment.Center) + } + + @SubscribeEvent + fun onChat(event: ClientChatReceivedEvent) { + if (!SkyBlock.inSkyblock || config.witherShieldDisplay == 0) return + if (event.type == 2.toByte() && event.message.unformattedText.contains("Wither Impact")) { + if (((witherImpactEndTime - System.currentTimeMillis()) / 1000.0) < 0) { + witherImpactEndTime = System.currentTimeMillis() + 5000 + } + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/AutoBuyChest.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/AutoBuyChest.kt index 7c66e1f..279402d 100644 --- a/src/main/kotlin/com/ambientaddons/features/dungeon/AutoBuyChest.kt +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/AutoBuyChest.kt @@ -84,8 +84,8 @@ object AutoBuyChest { fun onGuiDraw(event: GuiScreenEvent.DrawScreenEvent) { if (SkyBlock.area != Area.Dungeon || config.autoBuyChest != 2 || rewardChest == null || hasLookedAtChest) return val chest = event.gui?.chest ?: return - if (rewardChest == RewardChest.Wood && !hasOpenedChest) { - openChest(chest) + if (rewardChest == RewardChest.Wood) { + if (!hasOpenedChest) openChest(chest) } else { val items = chest.lowerChestInventory.items if (items.last() != null) { diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonHighlights.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonHighlights.kt new file mode 100644 index 0000000..50cc00a --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonHighlights.kt @@ -0,0 +1,121 @@ +package com.ambientaddons.features.dungeon + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.Extensions.skyblockID +import com.ambientaddons.utils.SkyBlock +import com.ambientaddons.utils.render.EntityUtils +import gg.essential.universal.UChat +import net.minecraft.entity.Entity +import net.minecraft.entity.boss.EntityWither +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.EntityCaveSpider +import net.minecraft.entity.monster.EntityEnderman +import net.minecraft.entity.monster.EntitySkeleton +import net.minecraft.entity.passive.EntityBat +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemArmor +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.* + +// modified from Harry282/Skyblock-Client +object DungeonHighlights { + private val markedArmorStands = mutableSetOf<EntityArmorStand>() + private val starredMobs = mutableSetOf<Entity>() + private var nearIdkmansry = false + + private val idkmansry = UUID.fromString("93ce1cad-833f-46ff-a124-b66d2b99c4fd") + + + @SubscribeEvent + fun onRenderWorld(event: RenderWorldLastEvent) { + if (SkyBlock.area != Area.Dungeon) return + nearIdkmansry = false + mc.theWorld.loadedEntityList.forEach { entity -> + if (entity is EntityArmorStand && entity.customNameTag.contains("✯") && !markedArmorStands.contains(entity)) { + if (config.starredHighlight == 0) return@forEach + mc.theWorld.getEntitiesInAABBexcluding( + entity, entity.entityBoundingBox.offset(0.0, -1.0, 0.0) + ) { isValidEntity(it) }.also { + if (it.isNotEmpty()) markedArmorStands.add(entity) + }.forEach { + starredMobs.add(it) + } + } else if (entity is EntityPlayer) { + if (entity.uniqueID == idkmansry) { + nearIdkmansry = true + } + } + } + mc.theWorld.loadedEntityList.forEach { + if (it is EntityArmorStand) return@forEach + val wasStarred = renderStarredHighlight(it, event.partialTicks) + if (!wasStarred) { + when (it) { + is EntityBat -> renderBatHighlight(it, event.partialTicks) + is EntityCaveSpider -> renderCellarHighlight(it, event.partialTicks) + is EntitySkeleton -> renderSniperHighlight(it, event.partialTicks) + is EntityPlayer -> renderShadowHighlight(it, event.partialTicks) + } + } + + } + } + + private fun renderStarredHighlight(entity: Entity, partialTicks: Float): Boolean { + if (config.starredHighlight == 0) return false + if (starredMobs.contains(entity)) { + EntityUtils.drawEntityBox( + entity, config.starredColor, outline = true, fill = false, config.starredHighlight == 2, partialTicks + ) + return true + } + return false + } + + private fun renderShadowHighlight(entity: EntityPlayer, partialTicks: Float) { + if (config.saHighlight == 0) return + val boots = entity.getCurrentArmor(0) + if (entity.heldItem?.skyblockID != "SILENT DEATH" && (boots?.item as? ItemArmor)?.getColor(boots) != 6029470) return + UChat.chat("SA held item: ${entity.heldItem?.skyblockID}") + EntityUtils.drawEntityBox( + entity, config.saColor, outline = true, fill = false, config.saHighlight == 2, partialTicks + ) + } + + + private fun renderCellarHighlight(entity: EntityCaveSpider, partialTicks: Float) { + if (config.bestiaryHighlight == 0 || nearIdkmansry) return + EntityUtils.drawEntityBox( + entity, config.bestiaryColor, outline = true, fill = false, config.bestiaryHighlight == 2, partialTicks + ) + } + + private fun renderSniperHighlight(entity: EntitySkeleton, partialTicks: Float) { + if (config.bestiaryHighlight == 0 || nearIdkmansry) return + if (entity.getCurrentArmor(3)?.skyblockID != "SNIPER_HELMET") return + EntityUtils.drawEntityBox( + entity, config.bestiaryColor, outline = true, fill = false, config.bestiaryHighlight == 2, partialTicks + ) + } + + private fun renderBatHighlight(entity: EntityBat, partialTicks: Float) { + if (config.batHighlight == 0) return + if (!listOf(100F, 200F, 400F, 800F).contains(entity.maxHealth)) return + EntityUtils.drawEntityBox( + entity, config.batColor, outline = true, fill = false, config.batHighlight == 2, partialTicks + ) + } + + private fun isValidEntity(entity: Entity?): Boolean { + return when (entity) { + is EntityEnderman -> !entity.isInvisible || (config.starredHighlight == 2) + is EntityArmorStand -> false + is EntityWither -> false + is EntityPlayer -> entity.uniqueID.version() == 2 && entity != mc.thePlayer + else -> true + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt index 7c3c286..3defe7c 100644 --- a/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt @@ -8,6 +8,7 @@ import com.ambientaddons.utils.Extensions.stripControlCodes import com.ambientaddons.utils.Area import com.ambientaddons.utils.SkyBlock import com.ambientaddons.utils.dungeon.DungeonPlayers +import gg.essential.universal.UChat import net.minecraftforge.client.event.GuiScreenEvent import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt new file mode 100644 index 0000000..468a6a9 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt @@ -0,0 +1,67 @@ +package com.ambientaddons.features.dungeon.terminals + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.events.GuiContainerEvent +import com.ambientaddons.utils.Extensions.chest +import com.ambientaddons.utils.Extensions.items +import com.ambientaddons.utils.Extensions.stripControlCodes +import com.ambientaddons.utils.SkyBlock +import net.minecraftforge.client.event.ClientChatReceivedEvent +import net.minecraftforge.client.event.GuiOpenEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object MelodyHelper { + private val completedStageRegex = Regex("/^[A-za-z0-9_]{3,16} (?:completed|activated) a (?:lever|terminal|device)! \\((?:[07]\\/7|[08]\\/8)\\)/") + private var hasSaidMeowlody = false + private var hasSaidThrottled = false + private var isThrottled = false + + @SubscribeEvent + fun onChat(event: ClientChatReceivedEvent) { + if (SkyBlock.dungeonFloor?.floor != 7) return + val unformatted = event.message.unformattedText.stripControlCodes() + if (completedStageRegex.matches(unformatted)) { + hasSaidMeowlody = false + hasSaidThrottled = false + isThrottled = false + } else if (unformatted.startsWith("This menu has been throttled!")) { + isThrottled = true + if (!hasSaidThrottled && config.throttledAnnouncement.isNotBlank()) { + mc.thePlayer.sendChatMessage("/pc ${config.throttledAnnouncement}") + hasSaidThrottled = true + } + } + } + + @SubscribeEvent + fun onGuiOpen(event: GuiOpenEvent) { + if (SkyBlock.dungeonFloor?.floor != 7) return + if (event.gui == null) return + if (event.gui.chest?.lowerChestInventory?.name == "Click the button on time!") { + if (!hasSaidMeowlody && config.melodyAnnouncement.isNotBlank()) { + mc.thePlayer.sendChatMessage("/pc ${config.melodyAnnouncement}") + hasSaidMeowlody = true + } + } + } + + @SubscribeEvent + fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { + if (SkyBlock.dungeonFloor?.floor != 7) return + val chest = event.gui.chest?.lowerChestInventory + if (chest?.name != "Click the button on time!" || isThrottled) return + val colors = chest.items.map { it?.itemDamage } + val targetPaneCol = colors.indexOf(10) + val movingPaneIndex = colors.indexOf(5) + val movingPaneCol = movingPaneIndex % 9 + val clickSlot = (movingPaneIndex / 9) * 9 + 7 + if (targetPaneCol != movingPaneCol) { + event.isCanceled = true + mc.thePlayer.playSound("random.pop", 1f, 0f) + } else if (clickSlot != event.slot?.slotIndex){ + event.isCanceled = true + mc.thePlayer.playSound("random.pop", 1f, 10f) + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt b/src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt index cbf4cd9..b7e5fad 100644 --- a/src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt +++ b/src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt @@ -14,7 +14,9 @@ object SendLastMessageKeybind { fun onSendChat(event: MessageSentEvent) { if (!SkyBlock.onHypixel) return if (event.message.startsWith("/pc", ignoreCase = true)) { - lastMessage = event.message.substring(4 until event.message.length) + lastMessage = event.message.runCatching { + substring(4 until event.message.length) + }.getOrNull() } else if (!event.message.startsWith("/")) { lastMessage = event.message } diff --git a/src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt b/src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt index db45e93..b0689c4 100644 --- a/src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt +++ b/src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt @@ -6,7 +6,7 @@ import com.ambientaddons.events.ItemOverlayEvent import com.ambientaddons.utils.Extensions.skyblockID import com.ambientaddons.utils.Extensions.stripControlCodes import com.ambientaddons.utils.SkyBlock -import com.ambientaddons.utils.RenderUtils +import com.ambientaddons.utils.render.OverlayUtils import net.minecraftforge.client.event.ClientChatReceivedEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -52,7 +52,7 @@ object BonzoMask { else -> 1.0 } if (durability < 1.0) { - RenderUtils.renderDurabilityBar(event.x, event.y, durability) + OverlayUtils.renderDurabilityBar(event.x, event.y, durability) } } diff --git a/src/main/kotlin/com/ambientaddons/features/misc/KuudraReady.kt b/src/main/kotlin/com/ambientaddons/features/misc/KuudraReady.kt new file mode 100644 index 0000000..469d6fe --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/misc/KuudraReady.kt @@ -0,0 +1,37 @@ +package com.ambientaddons.features.misc + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.Extensions.chest +import com.ambientaddons.utils.Extensions.items +import com.ambientaddons.utils.Extensions.lore +import com.ambientaddons.utils.Extensions.stripControlCodes +import com.ambientaddons.utils.SkyBlock +import com.ambientaddons.utils.dungeon.DungeonPlayers +import net.minecraftforge.client.event.GuiScreenEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object KuudraReady { + private var hasClickedReady = false + + @SubscribeEvent + fun onWorldUnload(event: WorldEvent.Unload) { + hasClickedReady = false + } + + @SubscribeEvent + fun onGuiDraw(event: GuiScreenEvent.DrawScreenEvent) { + if (!config.kuudraReady || SkyBlock.area != Area.Kuudra) return + val chest = event.gui?.chest ?: return + val chestName = chest.lowerChestInventory.name + if (chestName == "Ready Up" && !hasClickedReady) { + val clickIndex = chest.lowerChestInventory.items.takeIf { it.last() != null }?.indexOfFirst { + it?.lore?.getOrNull(0)?.stripControlCodes()?.startsWith("Click to mark yourself") == true + } ?: return + hasClickedReady = true + mc.playerController.windowClick(chest.windowId, clickIndex, 2, 3, mc.thePlayer) + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/Alignment.kt b/src/main/kotlin/com/ambientaddons/utils/Alignment.kt new file mode 100644 index 0000000..2b83309 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/Alignment.kt @@ -0,0 +1,5 @@ +package com.ambientaddons.utils + +enum class Alignment { + Left, Center, Right +}
\ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/Area.kt b/src/main/kotlin/com/ambientaddons/utils/Area.kt index 8366a05..86065a3 100644 --- a/src/main/kotlin/com/ambientaddons/utils/Area.kt +++ b/src/main/kotlin/com/ambientaddons/utils/Area.kt @@ -12,10 +12,11 @@ enum class Area { CrimsonIsle, End, Park, - FarmingIslands; + FarmingIslands, + Kuudra; companion object { - fun fromString(str: String?): Area? = when (str?.lowercase()) { + fun fromString(str: String?): Area? = when (str) { "Crimson Isle" -> CrimsonIsle "Catacombs" -> Dungeon "Private Island" -> PrivateIsland @@ -28,6 +29,7 @@ enum class Area { "The Park" -> Park "The End" -> End "The Farming Islands" -> FarmingIslands + "Instanced" -> Kuudra else -> null } } diff --git a/src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt b/src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt index cb108ee..a6bbd57 100644 --- a/src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt +++ b/src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt @@ -6,6 +6,7 @@ import com.ambientaddons.utils.Extensions.cleanSB import com.ambientaddons.utils.Extensions.stripControlCodes import com.ambientaddons.utils.Extensions.substringBetween import com.ambientaddons.utils.TabListUtils.fetchTabEntries +import gg.essential.universal.UChat import net.minecraft.scoreboard.Score import net.minecraft.scoreboard.ScorePlayerTeam import net.minecraftforge.event.world.WorldEvent @@ -18,6 +19,7 @@ object SkyBlock { var onHypixel = false var inSkyblock = false var area: Area? = null + private var areaString: String? = null var dungeonFloor: DungeonFloor? = null var ticks = 0 @@ -64,12 +66,12 @@ object SkyBlock { inSkyblock = title?.contains("SKYBLOCK") == true } if (inSkyblock) { - if (area == null) { + if (areaString == null) { val tab = fetchTabEntries() - val locationString = tab.firstNotNullOfOrNull { areaRegex.find(it.text.stripControlCodes()) }?.let { + val areaString = tab.firstNotNullOfOrNull { areaRegex.find(it.text.stripControlCodes()) }?.let { it.groupValues.getOrNull(1) } - area = Area.fromString(locationString) + area = Area.fromString(areaString) } if (area == Area.Dungeon && dungeonFloor == null) { val dungeonLine = fetchScoreboardLines().find { diff --git a/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt index ba21a04..e57443d 100644 --- a/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt +++ b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt @@ -21,7 +21,7 @@ object DungeonPlayers { val rawPlayers = TabListUtils.fetchTabEntries().let { tabEntries -> playerSlots.map { tabEntries[it].text.stripControlCodes() } } - playerCount = rawPlayers.size + playerCount = rawPlayers.filter { it.isNotBlank() }.size } ticks++ } diff --git a/src/main/kotlin/com/ambientaddons/utils/dungeon/TextStyle.kt b/src/main/kotlin/com/ambientaddons/utils/dungeon/TextStyle.kt new file mode 100644 index 0000000..b1a5dce --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/dungeon/TextStyle.kt @@ -0,0 +1,14 @@ +package com.ambientaddons.utils.dungeon + +enum class TextStyle { + Default, Shadow, Outline; + + companion object { + fun fromInt(number: Int): TextStyle? = when (number) { + 0 -> Default + 1 -> Shadow + 2 -> Outline + else -> null + } + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/render/EntityUtils.kt b/src/main/kotlin/com/ambientaddons/utils/render/EntityUtils.kt new file mode 100644 index 0000000..b3abbcf --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/render/EntityUtils.kt @@ -0,0 +1,195 @@ +package com.ambientaddons.utils.render + +import AmbientAddons.Companion.mc +import net.minecraft.client.renderer.Tessellator +import net.minecraft.client.renderer.vertex.DefaultVertexFormats +import net.minecraft.entity.Entity +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.util.AxisAlignedBB +import net.minecraft.util.BlockPos +import org.lwjgl.opengl.GL11.* +import java.awt.Color + +// diretly stolen from Harry282/Skyblock-Client +object EntityUtils { + private fun drawFilledAABB(aabb: AxisAlignedBB, color: Color, alpha: Float = 0.5f) { + val tessellator = Tessellator.getInstance() + val worldRenderer = tessellator.worldRenderer + glColor4f(color.red / 255f, color.green / 255f, color.blue / 255f, alpha) + + worldRenderer.begin(GL_QUADS, DefaultVertexFormats.POSITION) + + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + tessellator.draw() + } + + private fun drawOutlinedAABB(aabb: AxisAlignedBB, color: Color, alpha: Float = 1.0f) { + val tessellator = Tessellator.getInstance() + val worldRenderer = tessellator.worldRenderer + glColor4f(color.red / 255f, color.green / 255f, color.blue / 255f, alpha) + + worldRenderer.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION) + + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() + + worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() + worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() + + tessellator.draw() + } + + fun drawBlockBox(blockPos: BlockPos, color: Color, outline: Boolean, fill: Boolean, partialTicks: Float) { + if (!outline && !fill) return + val renderManager = mc.renderManager + val x = blockPos.x - renderManager.viewerPosX + val y = blockPos.y - renderManager.viewerPosY + val z = blockPos.z - renderManager.viewerPosZ + + var axisAlignedBB = AxisAlignedBB(x, y, z, x + 1.0, y + 1.0, z + 1.0) + val block = mc.theWorld.getBlockState(blockPos).block + if (block != null) { + val player: EntityPlayer = mc.thePlayer + val posX = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks + val posY = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks + val posZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks + block.setBlockBoundsBasedOnState(mc.theWorld, blockPos) + axisAlignedBB = block.getSelectedBoundingBox(mc.theWorld, blockPos) + .expand(0.0020000000949949026, 0.0020000000949949026, 0.0020000000949949026) + .offset(-posX, -posY, -posZ) + } + + glPushMatrix() + glPushAttrib(GL_ALL_ATTRIB_BITS) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + glDisable(GL_TEXTURE_2D) + glDisable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + glDepthMask(false) + + if (outline) { + glLineWidth(1.5f) + drawOutlinedAABB(axisAlignedBB, color) + } + if (fill) { + drawFilledAABB(axisAlignedBB, color) + } + + glDepthMask(true) + glPopAttrib() + glPopMatrix() + } + + fun drawEntityBox(entity: Entity, color: Color, outline: Boolean, fill: Boolean, esp: Boolean, partialTicks: Float) { + if (!outline && !fill) return + val renderManager = mc.renderManager + val x = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks - renderManager.viewerPosX + val y = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks - renderManager.viewerPosY + val z = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks - renderManager.viewerPosZ + + var axisAlignedBB: AxisAlignedBB + entity.entityBoundingBox.run { + axisAlignedBB = AxisAlignedBB( + minX - entity.posX, + minY - entity.posY, + minZ - entity.posZ, + maxX - entity.posX, + maxY - entity.posY, + maxZ - entity.posZ + ).offset(x, y, z) + } + + glPushMatrix() + glPushAttrib(GL_ALL_ATTRIB_BITS) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_BLEND) + glEnable(GL_LINE_SMOOTH) + glDisable(GL_TEXTURE_2D) + if (esp) { + glDisable(GL_DEPTH_TEST) + } + glDisable(GL_LIGHTING) + glDepthMask(false) + + if (outline) { + glLineWidth(2.0f) + drawOutlinedAABB(axisAlignedBB, color) + } + if (fill) { + drawFilledAABB(axisAlignedBB, color) + } + + if (esp) { + glEnable(GL_DEPTH_TEST) + } + + glDepthMask(true) + glPopAttrib() + glPopMatrix() + } +}
\ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/RenderUtils.kt b/src/main/kotlin/com/ambientaddons/utils/render/OverlayUtils.kt index f10a711..69f3c99 100644 --- a/src/main/kotlin/com/ambientaddons/utils/RenderUtils.kt +++ b/src/main/kotlin/com/ambientaddons/utils/render/OverlayUtils.kt @@ -1,12 +1,17 @@ -package com.ambientaddons.utils +package com.ambientaddons.utils.render +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Alignment +import com.ambientaddons.utils.dungeon.TextStyle 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 kotlin.math.roundToInt -object RenderUtils { +object OverlayUtils { + + private val removeColorCodesRegex = Regex("§[0-9a-f]") // from Mojang fun renderDurabilityBar(x: Int, y: Int, percentFilled: Double) { @@ -30,7 +35,9 @@ object RenderUtils { GlStateManager.enableDepth() } - private fun draw(renderer: WorldRenderer, x: Int, y: Int, width: Int, height: Int, red: Int, green: Int, blue: Int, alpha: Int) { + private fun draw( + renderer: WorldRenderer, x: Int, y: Int, width: Int, height: Int, red: Int, green: Int, blue: Int, alpha: Int + ) { renderer.begin(7, DefaultVertexFormats.POSITION_COLOR) renderer.pos((x + 0).toDouble(), (y + 0).toDouble(), 0.0).color(red, green, blue, alpha).endVertex() renderer.pos((x + 0).toDouble(), (y + height).toDouble(), 0.0).color(red, green, blue, alpha).endVertex() @@ -39,4 +46,29 @@ object RenderUtils { Tessellator.getInstance().draw() } + fun drawString(x: Int, y: Int, str: String, textStyle: TextStyle, alignment: Alignment) { + val text = "§r$str" + val startX = when (alignment) { + Alignment.Left -> x + Alignment.Center -> x - mc.fontRendererObj.getStringWidth(str) / 2 + Alignment.Right -> x - mc.fontRendererObj.getStringWidth(str) + } + when (textStyle) { + TextStyle.Default -> mc.fontRendererObj.drawString( + text, startX.toFloat(), y.toFloat(), -1, false + ) + TextStyle.Shadow -> mc.fontRendererObj.drawString( + text, startX.toFloat(), y.toFloat(), -1, true + ) + TextStyle.Outline -> { + val rawString = text.replace(removeColorCodesRegex, "") + mc.fontRendererObj.drawString(rawString, startX - 1, y, -16777216) + mc.fontRendererObj.drawString(rawString, startX + 1, y, -16777216) + mc.fontRendererObj.drawString(rawString, startX, y - 1, -16777216) + mc.fontRendererObj.drawString(rawString, startX, y + 1, -16777216) + mc.fontRendererObj.drawString(text, startX, y, -1) + } + } + } + }
\ No newline at end of file |