From 1b6bd76b7e5c2f462bf55f0753ef459b445dcfb6 Mon Sep 17 00:00:00 2001 From: Appability Date: Tue, 18 Oct 2022 00:31:32 -0700 Subject: crimson features! --- src/main/kotlin/com/ambientaddons/AmbientAddons.kt | 8 +- src/main/kotlin/com/ambientaddons/config/Config.kt | 22 +++++ .../kotlin/com/ambientaddons/features/Trapper.kt | 71 ---------------- .../features/dungeon/terminals/MelodyHelper.kt | 2 +- .../ambientaddons/features/misc/CrimsonFishing.kt | 95 ++++++++++++++++++++++ .../com/ambientaddons/features/misc/Trapper.kt | 71 ++++++++++++++++ .../com/ambientaddons/utils/render/EntityUtils.kt | 16 +++- 7 files changed, 205 insertions(+), 80 deletions(-) delete mode 100644 src/main/kotlin/com/ambientaddons/features/Trapper.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/misc/CrimsonFishing.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/misc/Trapper.kt (limited to 'src/main/kotlin/com') diff --git a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt index f0ecfcf..8f0bcef 100644 --- a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt +++ b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt @@ -1,15 +1,12 @@ import com.ambientaddons.commands.AmbientCommand import com.ambientaddons.config.Config import com.ambientaddons.config.PersistentData -import com.ambientaddons.features.Trapper 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.features.misc.* import com.ambientaddons.utils.SBLocation import com.ambientaddons.utils.dungeon.DungeonPlayers import net.minecraft.client.Minecraft @@ -65,7 +62,8 @@ class AmbientAddons { WitherShieldOverlay, KuudraReady, DungeonHighlights, - Trapper + Trapper, + CrimsonFishing ).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 9035f6e..e81d89a 100644 --- a/src/main/kotlin/com/ambientaddons/config/Config.kt +++ b/src/main/kotlin/com/ambientaddons/config/Config.kt @@ -13,6 +13,10 @@ object Config : Vigilant( var autoTrapper = false var trapperEsp = false + var crimsonNotify = false + var crimsonColor = Color.CYAN + var crimsonHighlight = 0 + var batHighlight = 0 var batColor = Color.CYAN var saHighlight = 0 @@ -60,6 +64,24 @@ object Config : Vigilant( description = "Highlights trapper quests with a beacon beam and box. Legal, as Hypixel uses the glowing status effect for clients that support it." ) } + subcategory("Fishing features") { + switch( + ::crimsonNotify, + name = "Crimson sea creature alert", + description = "Sends a message in chat when a rare sea creature is fished (within render distance).", + ) + selector( + ::crimsonHighlight, + name = "Crimson highlight", + description = "Highlight rare Crimson sea creatures and Thunder sparks.", + options = listOf("Off", "Highlight", "ESP") + ) + color( + ::crimsonColor, + name = "Crimson highlight color", + description = "Color of rare Crimson fishing highlight.", + ) + } } category("Highlights") { diff --git a/src/main/kotlin/com/ambientaddons/features/Trapper.kt b/src/main/kotlin/com/ambientaddons/features/Trapper.kt deleted file mode 100644 index 184358a..0000000 --- a/src/main/kotlin/com/ambientaddons/features/Trapper.kt +++ /dev/null @@ -1,71 +0,0 @@ -package com.ambientaddons.features - -import AmbientAddons.Companion.config -import AmbientAddons.Companion.mc -import com.ambientaddons.utils.Area -import com.ambientaddons.utils.SBLocation -import com.ambientaddons.utils.render.EntityUtils -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLiving -import net.minecraft.entity.passive.* -import net.minecraftforge.client.event.ClientChatReceivedEvent -import net.minecraftforge.client.event.RenderWorldLastEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.awt.Color - -object Trapper { - private var color: Color? = null - private val trapperRegex = - Regex("^§e\\[NPC\\] Trevor The Trapper§f: §rYou can find your §(?[0-9a-f])\\w+ §fanimal near the §(?[0-9a-f])(?[\\w ]+)§f.§r$") - private val animals = - listOf(EntityCow::class, EntityPig::class, EntitySheep::class, EntityCow::class, EntityChicken::class, EntityRabbit::class) - private val animalHp: List = listOf(100F, 200F, 500F, 1000F, 1024F, 2048F) - - fun isTrapperAnimal(entity: Entity): Boolean = - entity.ticksExisted >= 10 && (entity::class in animals) && animalHp.contains((entity as? EntityLiving)?.maxHealth) - - @SubscribeEvent - fun onChat(event: ClientChatReceivedEvent) { - if (SBLocation.area != Area.FarmingIslands || event.message == null || event.type == 2.toByte()) return - if (config.autoTrapper) { - val siblings = event.message.siblings ?: return - if (siblings.getOrNull(0)?.unformattedText == "Accept the trapper's task to hunt the animal?") { - val command = siblings.getOrNull(3)?.chatStyle?.chatClickEvent?.value ?: return - mc.thePlayer.sendChatMessage(command) - } - } - val matchResult = event.message.formattedText.let { trapperRegex.find(it) } - if (matchResult != null) { - val colorCode = (matchResult.groups as? MatchNamedGroupCollection)?.get("color")?.value ?: return - color = Color(mc.fontRendererObj.getColorCode(colorCode.single())) - } else if ( - event.message.formattedText.startsWith("§r§aKilling the animal rewarded you ") || - event.message.formattedText.startsWith("§r§aYour mob died randomly, you are rewarded ") - ) { - color = null - } - } - - @SubscribeEvent - fun onRenderWorld(event: RenderWorldLastEvent) { - if (SBLocation.area != Area.FarmingIslands || !config.trapperEsp) return - mc.theWorld.loadedEntityList.forEach { - if (color != null && isTrapperAnimal(it)) { - val renderManager = mc.renderManager - val x = it.lastTickPosX + (it.posX - it.lastTickPosX) * event.partialTicks - renderManager.viewerPosX - 0.5 - val y = it.lastTickPosY + (it.posY - it.lastTickPosY) * event.partialTicks - renderManager.viewerPosY - val z = it.lastTickPosZ + (it.posZ - it.lastTickPosZ) * event.partialTicks - renderManager.viewerPosZ - 0.5 - val entityHeight = it.entityBoundingBox.maxY - it.entityBoundingBox.minY - EntityUtils.drawEntityBox( - it, - color!!, - outline = true, - fill = true, - partialTicks = event.partialTicks, - esp = true - ) - EntityUtils.renderBeaconBeam(x, y + entityHeight, z, color!!, 1F, event.partialTicks, true) - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt index f867b3f..612ae1b 100644 --- a/src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/terminals/MelodyHelper.kt @@ -13,7 +13,7 @@ import net.minecraftforge.event.world.WorldEvent 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 val completedStageRegex = Regex("/^[\\w]{2,16} (?:completed|activated) a (?:lever|terminal|device)! \\((?:[07]/7|[08]/8)\\)") private var hasSaidMeowlody = false private var hasSaidThrottled = false private var isThrottled = false diff --git a/src/main/kotlin/com/ambientaddons/features/misc/CrimsonFishing.kt b/src/main/kotlin/com/ambientaddons/features/misc/CrimsonFishing.kt new file mode 100644 index 0000000..6ed1d1b --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/misc/CrimsonFishing.kt @@ -0,0 +1,95 @@ +package com.ambientaddons.features.misc + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.SBLocation +import com.ambientaddons.utils.render.EntityUtils +import gg.essential.universal.UChat +import net.minecraft.entity.Entity +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.EntityGuardian +import net.minecraft.entity.monster.EntityIronGolem +import net.minecraft.entity.passive.EntityMooshroom +import net.minecraft.item.ItemSkull +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.math.pow +import kotlin.math.roundToInt +import kotlin.math.sqrt + +object CrimsonFishing { + private const val sparkTexture = + "ewogICJ0aW1lc3RhbXAiIDogMTY0MzUwNDM3MjI1NiwKICAicHJvZmlsZUlkIiA6ICI2MzMyMDgwZTY3YTI0Y2MxYjE3ZGJhNzZmM2MwMGYxZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJUZWFtSHlkcmEiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2IzMzI4ZDNlOWQ3MTA0MjAzMjI1NTViMTcyMzkzMDdmMTIyNzBhZGY4MWJmNjNhZmM1MGZhYTA0YjVjMDZlMSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9" + private val knownEntities = mutableSetOf() + + fun isSpark(entity: Entity): Boolean { + return (entity is EntityArmorStand) && run { + entity.heldItem?.let { + if (it.item !is ItemSkull) return false + val nbt = it.tagCompound ?: return false + if (!nbt.hasKey("SkullOwner", 10)) return false + sparkTexture == nbt + .getCompoundTag("SkullOwner") + .getCompoundTag("Properties") + .getTagList("textures", 10) + .getCompoundTagAt(0) + .getString("Value") + } ?: false + } + } + + @SubscribeEvent + fun onWorldUnload(event: WorldEvent.Unload) { + knownEntities.clear() + } + + @SubscribeEvent + fun onRenderWorld(event: RenderWorldLastEvent) { + if (SBLocation.area != Area.CrimsonIsle) return + mc.theWorld.loadedEntityList.forEach { + if (it is EntityIronGolem || it is EntityGuardian) { + if (config.crimsonHighlight != 0) { + EntityUtils.drawEntityBox( + entity = it, + color = config.crimsonColor, + outline = true, + fill = false, + esp = config.crimsonHighlight == 2, + partialTicks = event.partialTicks + ) + } + if (config.crimsonNotify && !knownEntities.contains(it)) { + val distance = sqrt((it.posX - mc.thePlayer.posX).pow(2) + + (it.posY - mc.thePlayer.posY).pow(2) + + (it.posZ - mc.thePlayer.posZ).pow(2) + ) + if (it is EntityIronGolem) { + UChat.chat("\n§c§lA legendary creature has been spotted nearby... Lord Jawbus has arrived.") + mc.thePlayer.playSound("random.orb", 1f, 0.5f) + } else { + UChat.chat("\n§c§lYou hear a massive rumble as a Thunder emerges nearby.") + mc.thePlayer.playSound("random.orb", 1f, 0.5f) + } + UChat.chat("§cSpotted §6§l${distance.roundToInt()} §cblocks away.\n") + + } + knownEntities.add(it) + } else if (isSpark(it) && config.crimsonHighlight != 0) { + EntityUtils.drawEntityBox( + entity = it, + color = config.crimsonColor, + outline = true, + fill = true, + esp = config.crimsonHighlight == 2, + partialTicks = event.partialTicks, + offset = Triple(-0.2F, -0.5F, -0.1F), + expansion = Triple(-0.1, -0.85, -0.1) + ) + } + } + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/misc/Trapper.kt b/src/main/kotlin/com/ambientaddons/features/misc/Trapper.kt new file mode 100644 index 0000000..3d7b585 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/misc/Trapper.kt @@ -0,0 +1,71 @@ +package com.ambientaddons.features.misc + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.SBLocation +import com.ambientaddons.utils.render.EntityUtils +import net.minecraft.entity.Entity +import net.minecraft.entity.EntityLiving +import net.minecraft.entity.passive.* +import net.minecraftforge.client.event.ClientChatReceivedEvent +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.awt.Color + +object Trapper { + private var color: Color? = null + private val trapperRegex = + Regex("^§e\\[NPC\\] Trevor The Trapper§f: §rYou can find your §(?[0-9a-f])\\w+ §fanimal near the §(?[0-9a-f])(?[\\w ]+)§f.§r$") + private val animals = + listOf(EntityCow::class, EntityPig::class, EntitySheep::class, EntityCow::class, EntityChicken::class, EntityRabbit::class) + private val animalHp: List = listOf(100F, 200F, 500F, 1000F, 1024F, 2048F) + + fun isTrapperAnimal(entity: Entity): Boolean = + entity.ticksExisted >= 10 && (entity::class in animals) && animalHp.contains((entity as? EntityLiving)?.maxHealth) + + @SubscribeEvent + fun onChat(event: ClientChatReceivedEvent) { + if (SBLocation.area != Area.FarmingIslands || event.message == null || event.type == 2.toByte()) return + if (config.autoTrapper) { + val siblings = event.message.siblings ?: return + if (siblings.getOrNull(0)?.unformattedText == "Accept the trapper's task to hunt the animal?") { + val command = siblings.getOrNull(3)?.chatStyle?.chatClickEvent?.value ?: return + mc.thePlayer.sendChatMessage(command) + } + } + val matchResult = event.message.formattedText.let { trapperRegex.find(it) } + if (matchResult != null) { + val colorCode = (matchResult.groups as? MatchNamedGroupCollection)?.get("color")?.value ?: return + color = Color(mc.fontRendererObj.getColorCode(colorCode.single())) + } else if ( + event.message.formattedText.startsWith("§r§aKilling the animal rewarded you ") || + event.message.formattedText.startsWith("§r§aYour mob died randomly, you are rewarded ") + ) { + color = null + } + } + + @SubscribeEvent + fun onRenderWorld(event: RenderWorldLastEvent) { + if (SBLocation.area != Area.FarmingIslands || !config.trapperEsp) return + mc.theWorld.loadedEntityList.forEach { + if (color != null && isTrapperAnimal(it)) { + val renderManager = mc.renderManager + val x = it.lastTickPosX + (it.posX - it.lastTickPosX) * event.partialTicks - renderManager.viewerPosX + val y = it.lastTickPosY + (it.posY - it.lastTickPosY) * event.partialTicks - renderManager.viewerPosY + val z = it.lastTickPosZ + (it.posZ - it.lastTickPosZ) * event.partialTicks - renderManager.viewerPosZ + val entityHeight = it.entityBoundingBox.maxY - it.entityBoundingBox.minY + EntityUtils.drawEntityBox( + it, + color!!, + outline = true, + fill = true, + partialTicks = event.partialTicks, + esp = true + ) + EntityUtils.renderBeaconBeam(x - 0.5, y + entityHeight, z - 0.5, color!!, 1F, event.partialTicks, true) + } + } + } +} \ 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 index c5bc2e9..333ace4 100644 --- a/src/main/kotlin/com/ambientaddons/utils/render/EntityUtils.kt +++ b/src/main/kotlin/com/ambientaddons/utils/render/EntityUtils.kt @@ -17,7 +17,7 @@ import kotlin.math.cos import kotlin.math.sin -// diretly stolen from Harry282/Skyblock-Client +// directly stolen from Harry282/Skyblock-Client object EntityUtils { private fun drawFilledAABB(aabb: AxisAlignedBB, color: Color, alpha: Float = 0.5f) { val tessellator = Tessellator.getInstance() @@ -239,7 +239,16 @@ object EntityUtils { } } - fun drawEntityBox(entity: Entity, color: Color, outline: Boolean, fill: Boolean, esp: Boolean, partialTicks: Float) { + fun drawEntityBox( + entity: Entity, + color: Color, + outline: Boolean, + fill: Boolean, + esp: Boolean, + partialTicks: Float, + offset: Triple = Triple(0F, 0F, 0F), + expansion: Triple = Triple(0.0, 0.0, 0.0), + ) { if (!outline && !fill) return val renderManager = mc.renderManager val x = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks - renderManager.viewerPosX @@ -255,7 +264,8 @@ object EntityUtils { maxX - entity.posX, maxY - entity.posY, maxZ - entity.posZ - ).offset(x, y, z) + ).offset(x + offset.first, y + offset.second, z + offset.third) + .expand(expansion.first, expansion.second, expansion.third) } glPushMatrix() -- cgit