aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAppability <appable@icloud.com>2022-10-13 18:58:00 -0700
committerAppability <appable@icloud.com>2022-10-13 18:58:00 -0700
commitd0cbc11018c8126575117aaeb2b861957386fa9a (patch)
treec5419fb1f00b147604bded231c1388d6b391d27e /src
parentc599ee0d78ed8bc17488636f2d9b9b1d5b6dd4a8 (diff)
downloadAmbientAddons-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')
-rw-r--r--src/main/kotlin/com/ambientaddons/AmbientAddons.kt11
-rw-r--r--src/main/kotlin/com/ambientaddons/config/Config.kt109
-rw-r--r--src/main/kotlin/com/ambientaddons/features/display/WitherShieldOverlay.kt41
-rw-r--r--src/main/kotlin/com/ambientaddons/features/dungeon/AutoBuyChest.kt4
-rw-r--r--src/main/kotlin/com/ambientaddons/features/dungeon/DungeonHighlights.kt121
-rw-r--r--src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt1
-rw-r--r--src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt67
-rw-r--r--src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt4
-rw-r--r--src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt4
-rw-r--r--src/main/kotlin/com/ambientaddons/features/misc/KuudraReady.kt37
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/Alignment.kt5
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/Area.kt6
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt8
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt2
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/dungeon/TextStyle.kt14
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/render/EntityUtils.kt195
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/render/OverlayUtils.kt (renamed from src/main/kotlin/com/ambientaddons/utils/RenderUtils.kt)38
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