From c599ee0d78ed8bc17488636f2d9b9b1d5b6dd4a8 Mon Sep 17 00:00:00 2001 From: Appability Date: Wed, 12 Oct 2022 20:48:51 -0700 Subject: uh a lot of things --- .../com/ambientaddons/mixin/MixinGuiContainer.java | 2 +- .../com/ambientaddons/mixin/MixinGuiScreen.java | 21 ++++++ .../com/ambientaddons/mixin/MixinRenderItem.java | 22 ++++++ src/main/kotlin/com/ambientaddons/AmbientAddons.kt | 33 ++++++-- .../com/ambientaddons/commands/AmbientCommand.kt | 4 +- src/main/kotlin/com/ambientaddons/config/Config.kt | 36 +++++++-- .../com/ambientaddons/events/ItemOverlayEvent.kt | 6 ++ .../com/ambientaddons/events/MessageSentEvent.kt | 5 ++ .../ambientaddons/features/dungeon/AutoBuyChest.kt | 14 ++-- .../features/dungeon/CancelInteractions.kt | 20 ----- .../ambientaddons/features/dungeon/CloseChest.kt | 5 +- .../ambientaddons/features/dungeon/DungeonReady.kt | 46 +++++++++++ .../ambientaddons/features/dungeon/IgnoreCarpet.kt | 8 +- .../features/dungeon/ShortbowClicker.kt | 32 ++++++++ .../features/keybinds/PerspectiveKeybind.kt | 18 +++++ .../features/keybinds/SendLastMessageKeybind.kt | 30 ++++++++ .../com/ambientaddons/features/misc/BonzoMask.kt | 60 +++++++++++++++ .../features/misc/CancelInteractions.kt | 22 ++++++ src/main/kotlin/com/ambientaddons/utils/Area.kt | 34 +++++++++ .../com/ambientaddons/utils/LocationUtils.kt | 87 --------------------- .../kotlin/com/ambientaddons/utils/RenderUtils.kt | 42 +++++++++++ .../kotlin/com/ambientaddons/utils/SkyBlock.kt | 88 ++++++++++++++++++++++ .../ambientaddons/utils/dungeon/DungeonClass.kt | 16 ++++ .../ambientaddons/utils/dungeon/DungeonPlayer.kt | 6 ++ .../ambientaddons/utils/dungeon/DungeonPlayers.kt | 28 +++++++ src/main/resources/mixins.ambientaddons.json | 8 +- 26 files changed, 554 insertions(+), 139 deletions(-) create mode 100644 src/main/java/com/ambientaddons/mixin/MixinGuiScreen.java create mode 100644 src/main/java/com/ambientaddons/mixin/MixinRenderItem.java create mode 100644 src/main/kotlin/com/ambientaddons/events/ItemOverlayEvent.kt create mode 100644 src/main/kotlin/com/ambientaddons/events/MessageSentEvent.kt delete mode 100644 src/main/kotlin/com/ambientaddons/features/dungeon/CancelInteractions.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/dungeon/ShortbowClicker.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/keybinds/PerspectiveKeybind.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt create mode 100644 src/main/kotlin/com/ambientaddons/features/misc/CancelInteractions.kt create mode 100644 src/main/kotlin/com/ambientaddons/utils/Area.kt delete mode 100644 src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt create mode 100644 src/main/kotlin/com/ambientaddons/utils/RenderUtils.kt create mode 100644 src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt create mode 100644 src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonClass.kt create mode 100644 src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayer.kt create mode 100644 src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt (limited to 'src') diff --git a/src/main/java/com/ambientaddons/mixin/MixinGuiContainer.java b/src/main/java/com/ambientaddons/mixin/MixinGuiContainer.java index ee4b432..88e9048 100644 --- a/src/main/java/com/ambientaddons/mixin/MixinGuiContainer.java +++ b/src/main/java/com/ambientaddons/mixin/MixinGuiContainer.java @@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; // credit Harry282/Skyblock-Client, under AGPL 3.0 @Mixin(GuiContainer.class) -public class MixinGuiContainer extends GuiScreen { +public abstract class MixinGuiContainer extends GuiScreen { private final GuiContainer gui = (GuiContainer) (Object) this; @Shadow diff --git a/src/main/java/com/ambientaddons/mixin/MixinGuiScreen.java b/src/main/java/com/ambientaddons/mixin/MixinGuiScreen.java new file mode 100644 index 0000000..8a9aa6c --- /dev/null +++ b/src/main/java/com/ambientaddons/mixin/MixinGuiScreen.java @@ -0,0 +1,21 @@ +package com.ambientaddons.mixin; + +import com.ambientaddons.events.GuiContainerEvent; +import com.ambientaddons.events.MessageSentEvent; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.common.MinecraftForge; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(GuiScreen.class) +public abstract class MixinGuiScreen { + + @Inject(method = "sendChatMessage(Ljava/lang/String;)V", at = @At("HEAD"), cancellable = true) + public void sendChatMessage(String msg, CallbackInfo ci) { + if (MinecraftForge.EVENT_BUS.post(new MessageSentEvent(msg))) { + ci.cancel(); + } + } +} diff --git a/src/main/java/com/ambientaddons/mixin/MixinRenderItem.java b/src/main/java/com/ambientaddons/mixin/MixinRenderItem.java new file mode 100644 index 0000000..8068291 --- /dev/null +++ b/src/main/java/com/ambientaddons/mixin/MixinRenderItem.java @@ -0,0 +1,22 @@ +package com.ambientaddons.mixin; + +import com.ambientaddons.events.GuiContainerEvent; +import com.ambientaddons.events.ItemOverlayEvent; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.MinecraftForge; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(RenderItem.class) +public abstract class MixinRenderItem { + @Inject(method = "renderItemOverlayIntoGUI", at = @At("HEAD"),cancellable = true) + public void renderItemOverlayIntoGui(FontRenderer fr, ItemStack stack, int xPosition, int yPosition, String text, CallbackInfo ci) { + if (MinecraftForge.EVENT_BUS.post(new ItemOverlayEvent(stack, xPosition, yPosition))) { + ci.cancel(); + } + } +} diff --git a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt index b24aa5c..b87b28b 100644 --- a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt +++ b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt @@ -1,20 +1,25 @@ import com.ambientaddons.commands.AmbientCommand import com.ambientaddons.config.Config import com.ambientaddons.config.PersistentData -import com.ambientaddons.features.dungeon.AutoBuyChest -import com.ambientaddons.features.dungeon.CancelInteractions -import com.ambientaddons.features.dungeon.CloseChest -import com.ambientaddons.utils.LocationUtils +import com.ambientaddons.features.dungeon.* +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.utils.SkyBlock import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiScreen +import net.minecraft.client.settings.KeyBinding import net.minecraftforge.client.ClientCommandHandler import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.fml.client.registry.ClientRegistry import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.ModMetadata import net.minecraftforge.fml.common.event.FMLInitializationEvent import net.minecraftforge.fml.common.event.FMLPreInitializationEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent +import org.lwjgl.input.Keyboard import java.io.File @Mod( @@ -41,11 +46,17 @@ class AmbientAddons { ClientCommandHandler.instance.registerCommand(AmbientCommand()) listOf( this, - LocationUtils, + SkyBlock, AutoBuyChest, CloseChest, - CancelInteractions + CancelInteractions, + DungeonReady, + ShortbowClicker, + BonzoMask, + PerspectiveKeybind, + SendLastMessageKeybind ).forEach(MinecraftForge.EVENT_BUS::register) + keyBinds.values.forEach(ClientRegistry::registerKeyBinding) } @SubscribeEvent @@ -61,6 +72,13 @@ class AmbientAddons { } val mc: Minecraft = Minecraft.getMinecraft() + + val keyBinds = mapOf( + "thirdPersonKey" to KeyBinding("Toggle third-person perspective", Keyboard.KEY_NONE, "AmbientAddons"), + "secondPersonKey" to KeyBinding("Toggle second-person perspective", Keyboard.KEY_NONE, "AmbientAddons"), + "spamKey" to KeyBinding("Send last message in party chat", Keyboard.KEY_NONE, "AmbientAddons"), + ) + var currentGui: GuiScreen? = null lateinit var configDirectory: File @@ -69,4 +87,7 @@ class AmbientAddons { lateinit var metadata: ModMetadata } + + + } \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/commands/AmbientCommand.kt b/src/main/kotlin/com/ambientaddons/commands/AmbientCommand.kt index 5bfd92b..c09998e 100644 --- a/src/main/kotlin/com/ambientaddons/commands/AmbientCommand.kt +++ b/src/main/kotlin/com/ambientaddons/commands/AmbientCommand.kt @@ -3,7 +3,7 @@ package com.ambientaddons.commands import AmbientAddons import com.ambientaddons.config.Config import com.ambientaddons.utils.Extensions.withModPrefix -import com.ambientaddons.utils.LocationUtils +import com.ambientaddons.utils.SkyBlock import gg.essential.universal.UChat import net.minecraft.command.CommandBase import net.minecraft.command.ICommandSender @@ -20,7 +20,7 @@ class AmbientCommand : CommandBase() { override fun processCommand(sender: ICommandSender?, args: Array) { when (args.getOrNull(0)) { null -> AmbientAddons.currentGui = Config.gui() - "location" -> UChat.chat(LocationUtils.toString().withModPrefix()) + "location" -> UChat.chat(SkyBlock.toString().withModPrefix()) "buy" -> AutoBuyCommand.processCommand(args.drop(1)) else -> UChat.chat("§cUnknown argument!") } diff --git a/src/main/kotlin/com/ambientaddons/config/Config.kt b/src/main/kotlin/com/ambientaddons/config/Config.kt index d62ff8f..722a853 100644 --- a/src/main/kotlin/com/ambientaddons/config/Config.kt +++ b/src/main/kotlin/com/ambientaddons/config/Config.kt @@ -6,21 +6,24 @@ import java.io.File object Config : Vigilant( - File(AmbientAddons.configDirectory, "config.toml"), - AmbientAddons.metadata.name + File(AmbientAddons.configDirectory, "config.toml"), AmbientAddons.metadata.name ) { var blockLowReroll = false var autoBuyChest = 0 + var autoReady = 0 + var maskWarning = false + + var terminatorCps = 0 var cancelInteractions = false var closeSecretChests = false var ignoreCarpet = false init { - category("Pre/Post Dungeon") { + category("Pre/Post Dungeon") { subcategory("Chest QOL") { - switch ( + switch( ::blockLowReroll, name = "Block rerolling low chests", description = "Prevents rerolling non-Bedrock chests (or Obsidian on M4)." @@ -32,10 +35,31 @@ object Config : Vigilant( options = listOf("Off", "Block Reroll", "Autobuy") ) } + selector( + ::autoReady, + name = "Ready at the start of a dungeon", + description = "Can be enabled always or only when 5 players are in the dungeon.", + options = listOf("Off", "5 Players", "All") + ) + } + + category("Displays") { + switch( + ::maskWarning, + name = "Mask proc warning", + description = "Displays a title when a spirit mask or bonzo mask procs." + ) } category("Dungeon") { subcategory("Miscellaneous QOL") { + slider( + ::terminatorCps, + name = "Set terminator autoclick CPS", + description = "Set to 0 to disable the feature", + min = 0, + max = 50 + ) switch( ::cancelInteractions, name = "Cancel block interactions", @@ -47,9 +71,7 @@ object Config : Vigilant( description = "Cancels opening chests containing secrets." ) switch( - ::ignoreCarpet, - name = "Ignore carpet hitboxes", - description = "Removes all carpet hitboxes" + ::ignoreCarpet, name = "Ignore carpet hitboxes", description = "Removes all carpet hitboxes" ) } } diff --git a/src/main/kotlin/com/ambientaddons/events/ItemOverlayEvent.kt b/src/main/kotlin/com/ambientaddons/events/ItemOverlayEvent.kt new file mode 100644 index 0000000..19cefde --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/events/ItemOverlayEvent.kt @@ -0,0 +1,6 @@ +package com.ambientaddons.events + +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.Event + +class ItemOverlayEvent(val item: ItemStack?, val x: Int, val y: Int) : Event() \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/events/MessageSentEvent.kt b/src/main/kotlin/com/ambientaddons/events/MessageSentEvent.kt new file mode 100644 index 0000000..38af972 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/events/MessageSentEvent.kt @@ -0,0 +1,5 @@ +package com.ambientaddons.events + +import net.minecraftforge.fml.common.eventhandler.Event + +class MessageSentEvent(val message: String) : Event() \ 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 3c67c4d..7c66e1f 100644 --- a/src/main/kotlin/com/ambientaddons/features/dungeon/AutoBuyChest.kt +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/AutoBuyChest.kt @@ -4,7 +4,6 @@ import AmbientAddons.Companion.config import AmbientAddons.Companion.mc import AmbientAddons.Companion.persistentData import com.ambientaddons.events.GuiContainerEvent -import com.ambientaddons.events.ReceivePacketEvent import com.ambientaddons.utils.Extensions.chest import com.ambientaddons.utils.Extensions.enchants import com.ambientaddons.utils.Extensions.items @@ -12,12 +11,11 @@ import com.ambientaddons.utils.Extensions.lore import com.ambientaddons.utils.Extensions.skyblockID import com.ambientaddons.utils.Extensions.stripControlCodes import com.ambientaddons.utils.Extensions.withModPrefix -import com.ambientaddons.utils.LocationUtils +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.SkyBlock import gg.essential.universal.UChat import net.minecraft.inventory.ContainerChest import net.minecraft.item.ItemStack -import net.minecraft.network.play.client.C0DPacketCloseWindow -import net.minecraft.network.play.server.S2DPacketOpenWindow import net.minecraftforge.client.event.GuiOpenEvent import net.minecraftforge.client.event.GuiScreenEvent import net.minecraftforge.event.world.WorldEvent @@ -37,7 +35,7 @@ object AutoBuyChest { @SubscribeEvent fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { - if (LocationUtils.location != "Catacombs" || rewardChest == null) return + if (SkyBlock.area != Area.Dungeon || rewardChest == null) return if (event.slotId == BUY_SLOT_INDEX) { hasOpenedChest = true if (rewardChest == RewardChest.Wood) { @@ -45,7 +43,7 @@ object AutoBuyChest { event.isCanceled = true } } else if (event.slotId == KISMET_SLOT_INDEX) { - if (config.blockLowReroll && rewardChest != RewardChest.Bedrock && (rewardChest != RewardChest.Obsidian || LocationUtils.dungeonFloor.toString() != "M4")) { + if (config.blockLowReroll && rewardChest != RewardChest.Bedrock && (rewardChest != RewardChest.Obsidian || SkyBlock.dungeonFloor.toString() != "M4")) { UChat.chat("§cBlocked reroll! This low-tier chest should not be rerolled.".withModPrefix()) event.isCanceled = true return @@ -64,7 +62,7 @@ object AutoBuyChest { @SubscribeEvent fun onGuiOpen(event: GuiOpenEvent) { - if (LocationUtils.location != "Catacombs") return + if (SkyBlock.area != Area.Dungeon) return if (event.gui == null) return val chest = event.gui.chest val chestName = chest?.lowerChestInventory?.name @@ -84,7 +82,7 @@ object AutoBuyChest { @SubscribeEvent fun onGuiDraw(event: GuiScreenEvent.DrawScreenEvent) { - if (LocationUtils.location != "Catacombs" || config.autoBuyChest != 2 || rewardChest == null || hasLookedAtChest) return + 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) diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/CancelInteractions.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/CancelInteractions.kt deleted file mode 100644 index 94626f8..0000000 --- a/src/main/kotlin/com/ambientaddons/features/dungeon/CancelInteractions.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.ambientaddons.features.dungeon - -import AmbientAddons.Companion.config -import AmbientAddons.Companion.mc -import com.ambientaddons.utils.LocationUtils -import net.minecraft.init.Blocks -import net.minecraftforge.event.entity.player.PlayerInteractEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -object CancelInteractions { - @SubscribeEvent - fun onPlayerInteract(event: PlayerInteractEvent) { - if (!config.cancelInteractions || LocationUtils.location == "Private Island") return - if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { - if (mc.theWorld?.getBlockState(event.pos)?.block == Blocks.hopper) { - event.isCanceled = true - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/CloseChest.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/CloseChest.kt index ffaab8d..571cd7f 100644 --- a/src/main/kotlin/com/ambientaddons/features/dungeon/CloseChest.kt +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/CloseChest.kt @@ -3,7 +3,8 @@ package com.ambientaddons.features.dungeon import AmbientAddons.Companion.config import AmbientAddons.Companion.mc import com.ambientaddons.events.ReceivePacketEvent -import com.ambientaddons.utils.LocationUtils +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.SkyBlock import net.minecraft.network.play.client.C0DPacketCloseWindow import net.minecraft.network.play.server.S2DPacketOpenWindow import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -11,7 +12,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object CloseChest { @SubscribeEvent fun onOpenWindow(event: ReceivePacketEvent) { - if (!config.closeSecretChests || LocationUtils.location != "Catacombs") return + if (!config.closeSecretChests || SkyBlock.area != Area.Dungeon) return if (event.packet !is S2DPacketOpenWindow) return if (event.packet.windowTitle.unformattedText == "Chest") { mc.netHandler.networkManager.sendPacket(C0DPacketCloseWindow(event.packet.windowId)) diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt new file mode 100644 index 0000000..7c3c286 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/DungeonReady.kt @@ -0,0 +1,46 @@ +package com.ambientaddons.features.dungeon + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Extensions.chest +import com.ambientaddons.utils.Extensions.items +import com.ambientaddons.utils.Extensions.stripControlCodes +import com.ambientaddons.utils.Area +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 DungeonReady { + private const val START_SLOT_INDEX = 13 + private val READY_SLOTS = listOf(2, 3, 4, 5, 6) + + private var hasClickedReady = false + private var hasClickedStart = false + + @SubscribeEvent + fun onWorldUnload(event: WorldEvent.Unload) { + hasClickedReady = false + hasClickedStart = false + } + + @SubscribeEvent + fun onGuiDraw(event: GuiScreenEvent.DrawScreenEvent) { + if (config.autoReady == 0 || SkyBlock.area != Area.Dungeon) return + val chest = event.gui?.chest ?: return + val chestName = chest.lowerChestInventory.name + if (chestName == "Start Dungeon?" && !hasClickedStart) { + if (config.autoReady == 1 && DungeonPlayers.playerCount != 5) return + hasClickedStart = true + mc.playerController.windowClick(chest.windowId, START_SLOT_INDEX, 2, 3, mc.thePlayer) + } else if (chestName.startsWith("Catacombs - ") && !hasClickedReady) { + val username = mc.thePlayer.name + val clickIndex = chest.lowerChestInventory.items.takeIf { it.last() != null }?.indexOfFirst { + username == it?.displayName?.stripControlCodes()?.substringAfter(" ") + }.takeIf { it != -1 } ?: return + hasClickedReady = true + mc.playerController.windowClick(chest.windowId, clickIndex + 9, 2, 3, mc.thePlayer) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/IgnoreCarpet.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/IgnoreCarpet.kt index 6283b9c..6f2281e 100644 --- a/src/main/kotlin/com/ambientaddons/features/dungeon/IgnoreCarpet.kt +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/IgnoreCarpet.kt @@ -1,9 +1,11 @@ package com.ambientaddons.features.dungeon import AmbientAddons.Companion.config +import com.ambientaddons.utils.SkyBlock object IgnoreCarpet { - fun shouldIgnoreCarpet(): Boolean = if (AmbientAddons.isInitialized()) { - config.ignoreCarpet - } else false + fun shouldIgnoreCarpet(): Boolean { + if (!SkyBlock.inSkyblock) return false + return if (AmbientAddons.isInitialized()) config.ignoreCarpet else false + } } \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/dungeon/ShortbowClicker.kt b/src/main/kotlin/com/ambientaddons/features/dungeon/ShortbowClicker.kt new file mode 100644 index 0000000..9ff5d48 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/dungeon/ShortbowClicker.kt @@ -0,0 +1,32 @@ +package com.ambientaddons.features.dungeon + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Extensions.skyblockID +import com.ambientaddons.utils.SkyBlock +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.math.roundToLong + +// credit Floppa +object ShortbowClicker { + private var lastClickTime = System.currentTimeMillis() + private val shortbows = listOf("TERMINATOR", "JUJU_SHORTBOW", "ITEM_SPIRIT_BOW") + + @SubscribeEvent + fun onRender(event: RenderWorldLastEvent) { + if (!SkyBlock.inSkyblock) return + if (config.terminatorCps == 0) return + if (!mc.gameSettings.keyBindUseItem.isKeyDown) return + val itemStack = mc.thePlayer?.inventory?.getCurrentItem() + if (itemStack?.skyblockID?.let { shortbows.contains(it) } != true) return + val delay = (1000.0 / config.terminatorCps).roundToLong() + val currentTime = System.currentTimeMillis() + if ((currentTime - lastClickTime) >= delay) { + lastClickTime = currentTime - (currentTime - lastClickTime) % delay + if (mc.playerController.sendUseItem(mc.thePlayer, mc.theWorld, itemStack)) { + mc.entityRenderer.itemRenderer.resetEquippedProgress2() + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/keybinds/PerspectiveKeybind.kt b/src/main/kotlin/com/ambientaddons/features/keybinds/PerspectiveKeybind.kt new file mode 100644 index 0000000..3ee1564 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/keybinds/PerspectiveKeybind.kt @@ -0,0 +1,18 @@ +package com.ambientaddons.features.keybinds + +import AmbientAddons.Companion.keyBinds +import AmbientAddons.Companion.mc +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent + +object PerspectiveKeybind { + @SubscribeEvent + fun onKey(event: KeyInputEvent) { + val settings = mc.gameSettings + if (keyBinds["thirdPersonKey"]!!.isPressed) { + settings.thirdPersonView = if (settings.thirdPersonView == 0) 1 else 0 + } else if (keyBinds["secondPersonKey"]!!.isPressed) { + settings.thirdPersonView = if (settings.thirdPersonView == 0) 2 else 0 + } + } +} diff --git a/src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt b/src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt new file mode 100644 index 0000000..cbf4cd9 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/keybinds/SendLastMessageKeybind.kt @@ -0,0 +1,30 @@ +package com.ambientaddons.features.keybinds + +import AmbientAddons.Companion.keyBinds +import AmbientAddons.Companion.mc +import com.ambientaddons.events.MessageSentEvent +import com.ambientaddons.utils.SkyBlock +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.InputEvent + +object SendLastMessageKeybind { + var lastMessage: String? = null + + @SubscribeEvent + fun onSendChat(event: MessageSentEvent) { + if (!SkyBlock.onHypixel) return + if (event.message.startsWith("/pc", ignoreCase = true)) { + lastMessage = event.message.substring(4 until event.message.length) + } else if (!event.message.startsWith("/")) { + lastMessage = event.message + } + } + + @SubscribeEvent + fun onKey(event: InputEvent.KeyInputEvent) { + if (!SkyBlock.onHypixel) return + if (keyBinds["spamKey"]!!.isPressed && lastMessage != null) { + mc.thePlayer.sendChatMessage("/pc $lastMessage") + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt b/src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt new file mode 100644 index 0000000..db45e93 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/misc/BonzoMask.kt @@ -0,0 +1,60 @@ +package com.ambientaddons.features.misc + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +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 net.minecraftforge.client.event.ClientChatReceivedEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object BonzoMask { + private var spiritMaskProc = 0L + private var bonzoMaskProc = 0L + private var fraggedBonzoMaskProc = 0L + + private const val secondWindString = "Second Wind Activated! Your Spirit Mask saved your life!" + private const val bonzoString = "Your Bonzo's Mask saved your life!" + private const val fraggedBonzoString = "Your ⚚ Bonzo's Mask saved your life!" + + @SubscribeEvent + fun onChat(event: ClientChatReceivedEvent) { + if (!SkyBlock.inSkyblock) return + val didMaskProc = when (event.message.unformattedText.stripControlCodes()) { + secondWindString -> { + spiritMaskProc = System.currentTimeMillis() + true + } + bonzoString -> { + bonzoMaskProc = System.currentTimeMillis() + true + } + fraggedBonzoString -> { + fraggedBonzoMaskProc = System.currentTimeMillis() + true + } + else -> false + } + if (config.maskWarning && didMaskProc) { + mc.ingameGUI.displayTitle("§cMask!", null, 5, 20, 5) + } + } + + @SubscribeEvent + fun onRenderItemOverlay(event: ItemOverlayEvent) { + if (!SkyBlock.inSkyblock) return + val durability = when (event.item?.skyblockID) { + "BONZO_MASK" -> (System.currentTimeMillis() - bonzoMaskProc) / 180000.0 + "STARRED_BONZO_MASK" -> (System.currentTimeMillis() - fraggedBonzoMaskProc) / 180000.0 + "SPIRIT_MASK" -> (System.currentTimeMillis() - spiritMaskProc) / 30000.0 + else -> 1.0 + } + if (durability < 1.0) { + RenderUtils.renderDurabilityBar(event.x, event.y, durability) + } + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/features/misc/CancelInteractions.kt b/src/main/kotlin/com/ambientaddons/features/misc/CancelInteractions.kt new file mode 100644 index 0000000..60f0f8f --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/features/misc/CancelInteractions.kt @@ -0,0 +1,22 @@ +package com.ambientaddons.features.misc + +import AmbientAddons.Companion.config +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.SkyBlock +import net.minecraft.init.Blocks +import net.minecraftforge.event.entity.player.PlayerInteractEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object CancelInteractions { + @SubscribeEvent + fun onPlayerInteract(event: PlayerInteractEvent) { + if (!SkyBlock.inSkyblock) return + if (!config.cancelInteractions || SkyBlock.area == Area.PrivateIsland) return + if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { + if (mc.theWorld?.getBlockState(event.pos)?.block == Blocks.hopper) { + event.isCanceled = true + } + } + } +} \ 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 new file mode 100644 index 0000000..8366a05 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/Area.kt @@ -0,0 +1,34 @@ +package com.ambientaddons.utils + +enum class Area { + Dungeon, + PrivateIsland, + DungeonHub, + GoldMine, + DeepCaverns, + DwarvenMines, + CrystalHollows, + SpiderDen, + CrimsonIsle, + End, + Park, + FarmingIslands; + + companion object { + fun fromString(str: String?): Area? = when (str?.lowercase()) { + "Crimson Isle" -> CrimsonIsle + "Catacombs" -> Dungeon + "Private Island" -> PrivateIsland + "Dungeon Hub" -> DungeonHub + "Gold Mine" -> GoldMine + "Deep Caverns" -> DeepCaverns + "Dwarven Mines" -> DwarvenMines + "Crystal Hollows" -> CrystalHollows + "Spider's Den" -> SpiderDen + "The Park" -> Park + "The End" -> End + "The Farming Islands" -> FarmingIslands + else -> null + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt b/src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt deleted file mode 100644 index d185a08..0000000 --- a/src/main/kotlin/com/ambientaddons/utils/LocationUtils.kt +++ /dev/null @@ -1,87 +0,0 @@ -package com.ambientaddons.utils - -import AmbientAddons.Companion.mc -import com.ambientaddons.utils.DungeonFloor.Companion.toDungeonFloor -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 net.minecraft.scoreboard.Score -import net.minecraft.scoreboard.ScorePlayerTeam -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent -import net.minecraftforge.fml.common.network.FMLNetworkEvent - -object LocationUtils { - private var areaRegex = Regex("^(?:Area|Dungeon): ([\\w ].+)\$") - private var onHypixel = false - var inSkyblock = false - var location: String? = null - var dungeonFloor: DungeonFloor? = null - var ticks = 0 - - @SubscribeEvent - fun onWorldUnload(event: WorldEvent.Unload) { - inSkyblock = false - dungeonFloor = null - location = null - } - - @SubscribeEvent - fun onConnect(event: FMLNetworkEvent.ClientConnectedToServerEvent) { - onHypixel = mc.runCatching { - !event.isLocal && ((thePlayer?.clientBrand?.lowercase()?.contains("hypixel") - ?: currentServerData?.serverIP?.lowercase()?.contains("hypixel")) == true) - }.getOrDefault(false) - } - - @SubscribeEvent - fun onDisconnect(event: FMLNetworkEvent.ClientDisconnectionFromServerEvent) { - onHypixel = false - } - - // from Skytils, under AGPL 3.0 - fun fetchScoreboardLines(): List { - val scoreboard = mc.theWorld?.scoreboard ?: return emptyList() - val objective = scoreboard.getObjectiveInDisplaySlot(1) ?: return emptyList() - val scores = scoreboard.getSortedScores(objective).filter { input: Score? -> - input != null && input.playerName != null && !input.playerName - .startsWith("#") - }.take(15) - return scores.map { - ScorePlayerTeam.formatPlayerName(scoreboard.getPlayersTeam(it.playerName), it.playerName).cleanSB() - }.asReversed() - } - - // modified from Harry282/Skyblock-Client, under AGPL 3.0 - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!onHypixel || event.phase != TickEvent.Phase.START) return - if (ticks % 10 == 0) { - val title = mc.theWorld?.scoreboard?.getObjectiveInDisplaySlot(1)?.displayName?.cleanSB() - if (!inSkyblock) { - inSkyblock = title?.contains("SKYBLOCK") == true - } - if (inSkyblock) { - if (location == null) { - val tab = fetchTabEntries() - location = tab.firstNotNullOfOrNull { areaRegex.find(it.text.stripControlCodes()) }?.let { - it.groupValues.getOrNull(1) - } - } - if (location == "Catacombs" && dungeonFloor == null) { - val dungeonLine = fetchScoreboardLines().find { - it.run { contains("The Catacombs (") && !contains("Queue") } - } - dungeonFloor = dungeonLine?.substringBetween("(", ")")?.toDungeonFloor() - } - } - } - ticks++ - } - - override fun toString(): String = - "onHypixel: $onHypixel, inSkyblock: $inSkyblock, location: $location, floor: $dungeonFloor" - -} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/RenderUtils.kt b/src/main/kotlin/com/ambientaddons/utils/RenderUtils.kt new file mode 100644 index 0000000..f10a711 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/RenderUtils.kt @@ -0,0 +1,42 @@ +package com.ambientaddons.utils + +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 { + + // from Mojang + fun renderDurabilityBar(x: Int, y: Int, percentFilled: Double) { + val percent = percentFilled.coerceIn(0.0, 1.0) + if (percent == 0.0) return + val barWidth = (percentFilled * 13.0).roundToInt() + val barColorIndex = (percentFilled * 255.0).roundToInt() + GlStateManager.disableLighting() + GlStateManager.disableDepth() + GlStateManager.disableTexture2D() + GlStateManager.disableAlpha() + GlStateManager.disableBlend() + val tessellator = Tessellator.getInstance() + val worldrenderer = tessellator.worldRenderer + draw(worldrenderer, x + 2, y + 13, 13, 2, 0, 0, 0, 255) + draw(worldrenderer, x + 2, y + 13, 12, 1, (255 - barColorIndex) / 4, 64, 0, 255) + draw(worldrenderer, x + 2, y + 13, barWidth, 1, 255 - barColorIndex, barColorIndex, 0, 255) + GlStateManager.enableAlpha() + GlStateManager.enableTexture2D() + GlStateManager.enableLighting() + GlStateManager.enableDepth() + } + + 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() + renderer.pos((x + width).toDouble(), (y + height).toDouble(), 0.0).color(red, green, blue, alpha).endVertex() + renderer.pos((x + width).toDouble(), (y + 0).toDouble(), 0.0).color(red, green, blue, alpha).endVertex() + Tessellator.getInstance().draw() + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt b/src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt new file mode 100644 index 0000000..cb108ee --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/SkyBlock.kt @@ -0,0 +1,88 @@ +package com.ambientaddons.utils + +import AmbientAddons.Companion.mc +import com.ambientaddons.utils.DungeonFloor.Companion.toDungeonFloor +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 net.minecraft.scoreboard.Score +import net.minecraft.scoreboard.ScorePlayerTeam +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import net.minecraftforge.fml.common.network.FMLNetworkEvent + +object SkyBlock { + private var areaRegex = Regex("^(?:Area|Dungeon): ([\\w ].+)\$") + var onHypixel = false + var inSkyblock = false + var area: Area? = null + var dungeonFloor: DungeonFloor? = null + var ticks = 0 + + @SubscribeEvent + fun onWorldUnload(event: WorldEvent.Unload) { + inSkyblock = false + dungeonFloor = null + area = null + } + + @SubscribeEvent + fun onConnect(event: FMLNetworkEvent.ClientConnectedToServerEvent) { + onHypixel = mc.runCatching { + !event.isLocal && ((thePlayer?.clientBrand?.lowercase()?.contains("hypixel") + ?: currentServerData?.serverIP?.lowercase()?.contains("hypixel")) == true) + }.getOrDefault(false) + } + + @SubscribeEvent + fun onDisconnect(event: FMLNetworkEvent.ClientDisconnectionFromServerEvent) { + onHypixel = false + } + + // from Skytils, under AGPL 3.0 + fun fetchScoreboardLines(): List { + val scoreboard = mc.theWorld?.scoreboard ?: return emptyList() + val objective = scoreboard.getObjectiveInDisplaySlot(1) ?: return emptyList() + val scores = scoreboard.getSortedScores(objective).filter { input: Score? -> + input != null && input.playerName != null && !input.playerName + .startsWith("#") + }.take(15) + return scores.map { + ScorePlayerTeam.formatPlayerName(scoreboard.getPlayersTeam(it.playerName), it.playerName).cleanSB() + }.asReversed() + } + + // modified from Harry282/Skyblock-Client, under AGPL 3.0 + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!onHypixel || event.phase != TickEvent.Phase.START) return + if (ticks % 10 == 0) { + val title = mc.theWorld?.scoreboard?.getObjectiveInDisplaySlot(1)?.displayName?.cleanSB() + if (!inSkyblock) { + inSkyblock = title?.contains("SKYBLOCK") == true + } + if (inSkyblock) { + if (area == null) { + val tab = fetchTabEntries() + val locationString = tab.firstNotNullOfOrNull { areaRegex.find(it.text.stripControlCodes()) }?.let { + it.groupValues.getOrNull(1) + } + area = Area.fromString(locationString) + } + if (area == Area.Dungeon && dungeonFloor == null) { + val dungeonLine = fetchScoreboardLines().find { + it.run { contains("The Catacombs (") && !contains("Queue") } + } + dungeonFloor = dungeonLine?.substringBetween("(", ")")?.toDungeonFloor() + } + } + } + ticks++ + } + + override fun toString(): String = + "onHypixel: $onHypixel, inSkyblock: $inSkyblock, location: $area, floor: $dungeonFloor" + +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonClass.kt b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonClass.kt new file mode 100644 index 0000000..75442d0 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonClass.kt @@ -0,0 +1,16 @@ +package com.ambientaddons.utils.dungeon + +enum class DungeonClass { + Healer, Tank, Mage, Archer, Berserk; + + companion object { + fun fromString(str: String?): DungeonClass? = when (str?.lowercase()) { + "healer" -> Healer + "tank" -> Tank + "mage" -> Mage + "archer" -> Archer + "berserk" -> Berserk + else -> null + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayer.kt b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayer.kt new file mode 100644 index 0000000..b7903f5 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayer.kt @@ -0,0 +1,6 @@ +package com.ambientaddons.utils.dungeon + +data class DungeonPlayer(val name: String) { + var dungeonClass: DungeonClass? = null + var isAlive: Boolean = true +} diff --git a/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt new file mode 100644 index 0000000..ba21a04 --- /dev/null +++ b/src/main/kotlin/com/ambientaddons/utils/dungeon/DungeonPlayers.kt @@ -0,0 +1,28 @@ +package com.ambientaddons.utils.dungeon + +import com.ambientaddons.utils.Extensions.stripControlCodes +import com.ambientaddons.utils.Area +import com.ambientaddons.utils.SkyBlock +import com.ambientaddons.utils.TabListUtils +import com.ambientaddons.utils.text +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent + +object DungeonPlayers { + private val playerRegex = Regex("^\\[\\d{1,3}] (?[\\w]{3,16}) (?:.*)*\\((?:(?Healer|Tank|Berserk|Mage|Archer) (?[XVIL0]+)|(?DEAD|EMPTY))\\)") + var playerCount = 0 + private val playerSlots = listOf(5, 9, 13, 17, 1) + private var ticks = 0 + + @SubscribeEvent + fun onTick(event: ClientTickEvent) { + if (SkyBlock.area != Area.Dungeon) return + if (ticks % 10 == 0) { + val rawPlayers = TabListUtils.fetchTabEntries().let { tabEntries -> + playerSlots.map { tabEntries[it].text.stripControlCodes() } + } + playerCount = rawPlayers.size + } + ticks++ + } +} \ No newline at end of file diff --git a/src/main/resources/mixins.ambientaddons.json b/src/main/resources/mixins.ambientaddons.json index e8367a6..ca3aa8e 100644 --- a/src/main/resources/mixins.ambientaddons.json +++ b/src/main/resources/mixins.ambientaddons.json @@ -4,9 +4,11 @@ "minVersion": "0.7", "compatibilityLevel": "JAVA_8", "client": [ - "MixinGuiContainer", - "MixinNetworkManager", "MixinBlock", - "MixinCarpet" + "MixinCarpet", + "MixinGuiContainer", + "MixinNetworkManager", + "MixinRenderItem", + "MixinGuiScreen" ] } -- cgit