From 28ced338af0e1efbbbece1b6418f2bca5187cbe4 Mon Sep 17 00:00:00 2001 From: Lorenz Date: Mon, 11 Jul 2022 23:41:39 +0200 Subject: moved features in category and package order around --- .../java/at/lorenz/mod/HideNotClickableItems.kt | 449 -------------------- .../at/lorenz/mod/ItemDisplayOverlayFeatures.kt | 120 ------ src/main/java/at/lorenz/mod/LorenzMod.java | 4 +- src/main/java/at/lorenz/mod/config/Features.java | 30 +- .../at/lorenz/mod/items/HideNotClickableItems.kt | 450 +++++++++++++++++++++ .../at/lorenz/mod/items/ItemAbilityCooldown.kt | 288 ------------- .../lorenz/mod/items/ItemDisplayOverlayFeatures.kt | 121 ++++++ .../at/lorenz/mod/items/WitherImpactDetection.kt | 65 --- .../items/abilitycooldown/ItemAbilityCooldown.kt | 288 +++++++++++++ .../items/abilitycooldown/WitherImpactDetection.kt | 65 +++ 10 files changed, 945 insertions(+), 935 deletions(-) delete mode 100644 src/main/java/at/lorenz/mod/HideNotClickableItems.kt delete mode 100644 src/main/java/at/lorenz/mod/ItemDisplayOverlayFeatures.kt create mode 100644 src/main/java/at/lorenz/mod/items/HideNotClickableItems.kt delete mode 100644 src/main/java/at/lorenz/mod/items/ItemAbilityCooldown.kt create mode 100644 src/main/java/at/lorenz/mod/items/ItemDisplayOverlayFeatures.kt delete mode 100644 src/main/java/at/lorenz/mod/items/WitherImpactDetection.kt create mode 100644 src/main/java/at/lorenz/mod/items/abilitycooldown/ItemAbilityCooldown.kt create mode 100644 src/main/java/at/lorenz/mod/items/abilitycooldown/WitherImpactDetection.kt diff --git a/src/main/java/at/lorenz/mod/HideNotClickableItems.kt b/src/main/java/at/lorenz/mod/HideNotClickableItems.kt deleted file mode 100644 index 325eb32af..000000000 --- a/src/main/java/at/lorenz/mod/HideNotClickableItems.kt +++ /dev/null @@ -1,449 +0,0 @@ -package at.lorenz.mod - -import at.lorenz.mod.bazaar.BazaarApi -import at.lorenz.mod.events.GuiContainerEvent -import at.lorenz.mod.utils.ItemUtils -import at.lorenz.mod.utils.ItemUtils.cleanName -import at.lorenz.mod.utils.ItemUtils.getLore -import at.lorenz.mod.utils.LorenzColor -import at.lorenz.mod.utils.LorenzUtils -import at.lorenz.mod.utils.LorenzUtils.removeColorCodes -import at.lorenz.mod.utils.RenderUtils.highlight -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.inventory.GuiChest -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.inventory.ContainerChest -import net.minecraft.item.ItemStack -import net.minecraftforge.event.entity.player.ItemTooltipEvent -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import org.lwjgl.opengl.GL11 - -class HideNotClickableItems { - - private var hideReason = "" - - private var lastClickTime = 0L - private var bypassUntil = 0L - - @SubscribeEvent - fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { - if (!LorenzUtils.inSkyblock) return - if (isDisabled()) return - if (event.gui !is GuiChest) return - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - val lightingState = GL11.glIsEnabled(GL11.GL_LIGHTING) - GlStateManager.disableLighting() - GlStateManager.color(1f, 1f, 1f, 1f) - - for (slot in chest.inventorySlots) { - if (slot == null) continue - - if (slot.slotNumber == slot.slotIndex) continue - if (slot.stack == null) continue - - if (hide(chestName, slot.stack)) { - slot highlight LorenzColor.GRAY - } - } - - if (lightingState) GlStateManager.enableLighting() - } - - @SubscribeEvent - fun onDrawSlot(event: GuiContainerEvent.DrawSlotEvent.Pre) { - if (isDisabled()) return - if (event.gui !is GuiChest) return - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - val slot = event.slot - if (slot.slotNumber == slot.slotIndex) return - if (slot.stack == null) return - - val stack = slot.stack - - if (hide(chestName, stack)) { - event.isCanceled = true - } - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - fun onTooltip(event: ItemTooltipEvent) { - if (isDisabled()) return - if (event.toolTip == null) return - val guiChest = Minecraft.getMinecraft().currentScreen - if (guiChest !is GuiChest) return - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - val stack = event.itemStack - if (ItemUtils.getItemsInOpenChest().contains(stack)) return - - if (hide(chestName, stack)) { - val first = event.toolTip[0] - event.toolTip.clear() - event.toolTip.add("§7" + first.removeColorCodes()) - event.toolTip.add("") - if (hideReason == "") { - event.toolTip.add("§4No hide reason!") - LorenzUtils.warning("Not hide reason for not clickable item!") - } else { - event.toolTip.add("§c$hideReason") - } - } - } - - @SubscribeEvent - fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { - if (isDisabled()) return - if (event.gui !is GuiChest) return - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - val slot = event.slot ?: return - - if (slot.slotNumber == slot.slotIndex) return - if (slot.stack == null) return - - val stack = slot.stack - - if (hide(chestName, stack)) { - event.isCanceled = true -// SoundQueue.addToQueue("note.bass", 0.5f, 1f) - - if (System.currentTimeMillis() > lastClickTime + 5_000) { - lastClickTime = System.currentTimeMillis() -// EssentialAPI.getNotifications() -// .push( -// "§cThis item cannot be moved!", -// "§eClick here §fto disable this feature for 10 seconds!\n" + -// "§fOr disable it forever: §6/st §f+ '§6Hide Not Clickable Items§f'.", -// 5f, -// action = { -// bypassUntil = System.currentTimeMillis() + 10_000 -// }) - } - return - } - } - - private fun isDisabled(): Boolean { - if (bypassUntil > System.currentTimeMillis()) return true - - return !LorenzMod.feature.items.hideNotClickableItems - } - - private fun hide(chestName: String, stack: ItemStack): Boolean { - hideReason = "" - return when { - hideNpcSell(chestName, stack) -> true - hideChestBackpack(chestName, stack) -> true - hideSalvage(chestName, stack) -> true - hideTrade(chestName, stack) -> true - hideBazaarOrAH(chestName, stack) -> true - hideAccessoryBag(chestName, stack) -> true - hideSackOfSacks(chestName, stack) -> true - hideFishingBag(chestName, stack) -> true - hidePotionBag(chestName, stack) -> true - - else -> false - } - } - - private fun hidePotionBag(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Potion Bag")) return false - - val name = stack.cleanName() - if (isSkyBlockMenuItem(name)) { - hideReason = "The SkyBlock Menu cannot be put into the potion bag!" - return true - } - - if (stack.cleanName().endsWith(" Potion")) return false - - hideReason = "This item is not a potion!" - return true - } - - private fun hideFishingBag(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Fishing Bag")) return false - - val name = stack.cleanName() - if (isSkyBlockMenuItem(name)) { - hideReason = "The SkyBlock Menu cannot be put into the fishing bag!" - return true - } - - if (stack.cleanName().endsWith(" Bait")) return false - - hideReason = "This item is not a fishing bait!" - return true - } - - private fun hideSackOfSacks(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Sack of Sacks")) return false - - val name = stack.cleanName() - if (ItemUtils.isSack(name)) return false - if (isSkyBlockMenuItem(name)) return false - - hideReason = "This item is not a sack!" - return true - } - - private fun hideAccessoryBag(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Accessory Bag")) return false - - if (stack.getLore().any { it.contains("ACCESSORY") }) return false - if (isSkyBlockMenuItem(stack.cleanName())) return false - - hideReason = "This item is not an accessory!" - return true - } - - private fun hideTrade(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("You ")) return false - - if (ItemUtils.isCoOpSoulBound(stack)) { - hideReason = "Coop-Soulbound items cannot be traded!" - return true - } - - val name = stack.cleanName() - - if (ItemUtils.isSack(name)) { - hideReason = "Sacks cannot be traded!" - return true - } - - if (isSkyBlockMenuItem(name)) { - hideReason = "The SkyBlock Menu cannot be traded!" - return true - } - - val result = when { - name.contains("Personal Deletor") -> true - name.contains("Day Crystal") -> true - name.contains("Night Crystal") -> true - name.contains("Cat Talisman") -> true - name.contains("Lynx Talisman") -> true - name.contains("Cheetah Talisman") -> true - else -> false - } - - if (result) hideReason = "This item cannot be traded!" - return result - } - - private fun hideNpcSell(chestName: String, stack: ItemStack): Boolean { - if (chestName != "Trades" && chestName != "Ophelia") return false - - var name = stack.cleanName() - val size = stack.stackSize - val amountText = " x$size" - if (name.endsWith(amountText)) { - name = name.substring(0, name.length - amountText.length) - } - - if (isSkyBlockMenuItem(name)) { - hideReason = "The SkyBlock Menu cannot be sold at the NPC!" - return true - } - - if (!ItemUtils.isRecombobulated(stack)) { - when (name) { - "Health Potion VIII Splash Potion" -> return false - "Stone Button" -> return false - "Revive Stone" -> return false - "Premium Flesh" -> return false - "Defuse Kit" -> return false - "White Wool" -> return false - "Enchanted Wool" -> return false - "Training Weights" -> return false - "Journal Entry" -> return false - "Twilight Arrow Poison" -> return false - "Lever" -> return false - - "Fairy's Galoshes" -> return false - } - if (name.endsWith("Gem Rune I")) return false - - if (name.startsWith("Music Disc")) return false - } - - hideReason = "This item should not be sold at the NPC!" - return true - } - - private fun hideChestBackpack(chestName: String, stack: ItemStack): Boolean { - if (!chestName.contains("Ender Chest") && !chestName.contains("Backpack")) return false - - val name = stack.cleanName() - - if (isSkyBlockMenuItem(name)) { - hideReason = "The SkyBlock Menu cannot be put into the storage!" - return true - } - if (ItemUtils.isSack(name)) { - hideReason = "Sacks cannot be put into the storage!" - return true - } - - val result = when { - name.endsWith(" New Year Cake Bag") -> true - name == "Nether Wart Pouch" -> true - name == "Basket of Seeds" -> true - name == "Builder's Wand" -> true - - else -> false - } - - if (result) hideReason = "Bags cannot be put into the storage!" - return result - } - - private fun hideSalvage(chestName: String, stack: ItemStack): Boolean { - if (chestName != "Salvage Item") return false - - if (ItemUtils.isRecombobulated(stack)) { - hideReason = "This item should not be salvaged! (Recombobulated)" - return true - } - for (line in stack.getLore()) { - if (line.contains("LEGENDARY DUNGEON")) { - hideReason = "This item should not be salvaged! (Legendary)" - return true - } - } - - val name = stack.cleanName() - - val armorSets = listOf( - "Zombie Knight", - "Heavy", - "Zombie Soldier", - "Skeleton Grunt", - "Skeleton Soldier", - "Zombie Commander", - "Skeleton Master", - "Sniper", - "Skeletor", - "Rotten", - ) - - val items = mutableListOf() - for (armor in armorSets) { - items.add("$armor Helmet") - items.add("$armor Chestplate") - items.add("$armor Leggings") - items.add("$armor Boots") - } - - items.add("Zombie Soldier Cutlass") - items.add("Silent Death") - items.add("Zombie Knight Sword") - items.add("Conjuring") - items.add("Dreadlord Sword") - items.add("Soulstealer Bow") - items.add("Machine Gun Bow") - items.add("Earth Shard") - items.add("Zombie Commander Whip") - items.add("Sniper Bow") - - for (item in items) { - if (name.endsWith(" $item")) { - return false - } - } - - if (isSkyBlockMenuItem(name)) { - hideReason = "The SkyBlock Menu cannot be salvaged!" - return true - } - - hideReason = "This item cannot be salvaged!" - return true - } - - private fun hideBazaarOrAH(chestName: String, stack: ItemStack): Boolean { - val bazaarInventory = BazaarApi.isBazaarInventory(chestName) - - val auctionHouseInventory = - chestName == "Co-op Auction House" || chestName == "Auction House" || chestName == "Create BIN Auction" || chestName == "Create Auction" - if (!bazaarInventory && !auctionHouseInventory) return false - - - val displayName = stack.displayName - - if (isSkyBlockMenuItem(displayName.removeColorCodes())) { - if (bazaarInventory) hideReason = "The SkyBlock Menu is not a Bazaar Product!" - if (auctionHouseInventory) hideReason = "The SkyBlock Menu cannot be auctioned!" - return true - } - - if (bazaarInventory != BazaarApi.isBazaarItem(displayName)) { - if (bazaarInventory) hideReason = "This item is not a Bazaar Product!" - if (auctionHouseInventory) hideReason = "Bazaar Products cannot be auctioned!" - - return true - } - - if (isNotAuctionable(stack)) return true - - return false - } - - private fun isNotAuctionable(stack: ItemStack): Boolean { - if (ItemUtils.isCoOpSoulBound(stack)) { - hideReason = "Coop-Soulbound items cannot be auctioned!" - return true - } - - val name = stack.cleanName() - - if (ItemUtils.isSack(name)) { - hideReason = "Sacks cannot be auctioned!" - return true - } - - val result = when { - name.contains("Personal Deletor") -> true - name.contains("Day Crystal") -> true - name.contains("Night Crystal") -> true - - name.contains("Cat Talisman") -> true - name.contains("Lynx Talisman") -> true - name.contains("Cheetah Talisman") -> true - - name.contains("Hoe of Great Tilling") -> true - name.contains("Hoe of Greater Tilling") -> true - name.contains("InfiniDirt") -> true - name.contains("Prismapump") -> true - name.contains("Mathematical Hoe Blueprint") -> true - name.contains("Basket of Seeds") -> true - name.contains("Nether Wart Pouch") -> true - - name.contains("Carrot Hoe") -> true - name.contains("Sugar Cane Hoe") -> true - name.contains("Nether Warts Hoe") -> true - name.contains("Potato Hoe") -> true - name.contains("Melon Dicer") -> true - name.contains("Pumpkin Dicer") -> true - name.contains("Coco Chopper") -> true - name.contains("Wheat Hoe") -> true - - else -> false - } - - if (result) hideReason = "This item cannot be auctioned!" - return result - } - - private fun isSkyBlockMenuItem(name: String): Boolean = name == "SkyBlock Menu (Right Click)" -} diff --git a/src/main/java/at/lorenz/mod/ItemDisplayOverlayFeatures.kt b/src/main/java/at/lorenz/mod/ItemDisplayOverlayFeatures.kt deleted file mode 100644 index 3efd35dd5..000000000 --- a/src/main/java/at/lorenz/mod/ItemDisplayOverlayFeatures.kt +++ /dev/null @@ -1,120 +0,0 @@ -package at.lorenz.mod - -import at.lorenz.mod.events.GuiRenderItemEvent -import at.lorenz.mod.utils.ItemUtils -import at.lorenz.mod.utils.ItemUtils.cleanName -import at.lorenz.mod.utils.LorenzDebug -import at.lorenz.mod.utils.LorenzUtils -import at.lorenz.mod.utils.LorenzUtils.between -import at.lorenz.mod.utils.LorenzUtils.matchRegex -import at.lorenz.mod.utils.NumberUtil.romanToDecimal -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.item.ItemStack -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ItemDisplayOverlayFeatures { - - @SubscribeEvent - fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { - - val item = event.stack ?: return - - if (!LorenzUtils.inSkyblock || item.stackSize != 1 || item.tagCompound?.hasKey("SkytilsNoItemOverlay") == true) return - - val stackTip = getStackTip(item) - - if (stackTip.isNotEmpty()) { - GlStateManager.disableLighting() - GlStateManager.disableDepth() - GlStateManager.disableBlend() - event.fr.drawStringWithShadow( - stackTip, - (event.x + 17 - event.fr.getStringWidth(stackTip)).toFloat(), - (event.y + 9).toFloat(), - 16777215 - ) - GlStateManager.enableLighting() - GlStateManager.enableDepth() - } - - } - - private fun getStackTip(item: ItemStack): String { - val name = item.cleanName() - - if (LorenzMod.feature.items.displayMasterStarNumber) { - when (name) { - "First Master Star" -> return "1" - "Second Master Star" -> return "2" - "Third Master Star" -> return "3" - "Fourth Master Star" -> return "4" - "Fifth Master Star" -> return "5" - } - } - - if (LorenzMod.feature.items.displayMasterSkullNumber) { - if (name.matchRegex("(.*)Master Skull - Tier .")) { - return name.substring(name.length - 1) - } - } - - if (LorenzMod.feature.items.displayDungeonHeadFloor) { - if (name.contains("Golden ") || name.contains("Diamond ")) { - when { - name.contains("Bonzo") -> return "1" - name.contains("Scarf") -> return "2" - name.contains("Professor") -> return "3" - name.contains("Thorn") -> return "4" - name.contains("Livid") -> return "5" - name.contains("Sadan") -> return "6" - name.contains("Necron") -> return "7" - } - } - } - - if (LorenzMod.feature.items.displayNewYearCakeNumber) { - if (name.startsWith("New Year Cake (")) { - try { - return "§b" + name.between("(Year ", ")") - } catch (e: IndexOutOfBoundsException) { - val message = "New Year Cake error in string: '$name': ${e.message}" - LorenzDebug.log(message) - LorenzUtils.error(message) - } - } - } - - if (LorenzMod.feature.items.displayPetLevel) { - if (ItemUtils.isPet(name)) { - try { - val level = name.between("Lvl ", "] ").toInt() - if (level != ItemUtils.maxPetLevel(name)) { - return "$level" - } - } catch (e: java.lang.NumberFormatException) { - e.printStackTrace() - LorenzDebug.log("name: '$name'") - LorenzUtils.warning("NumberFormatException at lorenzItemDisplayPetLevel") - } - } - } - - if (LorenzMod.feature.items.displaySackName) { - if (ItemUtils.isSack(name)) { - val split = name.split(" ") - val sackName = split[split.size - 2] - return (if (name.contains("Enchanted")) "§5" else "") + sackName.substring(0, 2) - } - } - - if (LorenzMod.feature.items.displayMinionTier) { - if (name.contains(" Minion ")) { - val array = name.split(" ") - val last = array[array.size - 1] - return last.romanToDecimal().toString() - } - } - - return "" - } -} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/LorenzMod.java b/src/main/java/at/lorenz/mod/LorenzMod.java index 1dd6edaa4..4d70626e5 100644 --- a/src/main/java/at/lorenz/mod/LorenzMod.java +++ b/src/main/java/at/lorenz/mod/LorenzMod.java @@ -10,7 +10,9 @@ import at.lorenz.mod.dungeon.DungeonChatFilter; import at.lorenz.mod.dungeon.DungeonData; import at.lorenz.mod.dungeon.DungeonHighlightClickedBlocks; import at.lorenz.mod.dungeon.damageindicator.DungeonBossDamageIndicator; -import at.lorenz.mod.items.ItemAbilityCooldown; +import at.lorenz.mod.items.HideNotClickableItems; +import at.lorenz.mod.items.abilitycooldown.ItemAbilityCooldown; +import at.lorenz.mod.items.ItemDisplayOverlayFeatures; import at.lorenz.mod.misc.*; import at.lorenz.mod.test.LorenzTest; import com.google.gson.Gson; diff --git a/src/main/java/at/lorenz/mod/config/Features.java b/src/main/java/at/lorenz/mod/config/Features.java index 25c36d310..f1a1a0a21 100644 --- a/src/main/java/at/lorenz/mod/config/Features.java +++ b/src/main/java/at/lorenz/mod/config/Features.java @@ -63,10 +63,6 @@ public class Features { @Category(name = "Debug", desc = "Debug and test stuff.") public Debug debug = new Debug(); - @Expose - @Category(name = "Abilities", desc = "Stuff about abilities.") - public Abilities abilities = new Abilities(); - public static class Chat { @Expose @@ -131,45 +127,63 @@ public class Features { public static class Items { + @Expose + @ConfigOption(name = "Item Number as Stack", desc = "") + @ConfigEditorAccordion(id = 2) + public boolean filterTypes = false; + @Expose @ConfigOption(name = "Not Clickable Items", desc = "Hide items that are not clickable in " + "the current inventory: ah, bz, accessory bag, etc") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean hideNotClickableItems = false; @Expose @ConfigOption(name = "Master Star Number", desc = "Shows the Tier of the Master Star.") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean displayMasterStarNumber = false; @Expose @ConfigOption(name = "Master Skull Number", desc = "Shows the tier of the Master Skull accessory.") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean displayMasterSkullNumber = false; @Expose @ConfigOption(name = "Dungeon Head Floor", desc = "Shows the correct floor for golden and diamond heads.") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean displayDungeonHeadFloor = false; @Expose @ConfigOption(name = "New Year Cake", desc = "Shows the Number of the Year of New Year Cakes.") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean displayNewYearCakeNumber = false; @Expose @ConfigOption(name = "Pet Level", desc = "Shows the level of the pet when not maxed.") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean displayPetLevel = false; @Expose @ConfigOption(name = "Sack Name", desc = "Shows an abbreviation of the Sack name.") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean displaySackName = false; @Expose @ConfigOption(name = "Minion Tier", desc = "Shows the Minion Tier over Items.") @ConfigEditorBoolean + @ConfigAccordionId(id = 2) public boolean displayMinionTier = false; + + @Expose + @ConfigOption(name = "Ability Cooldown", desc = "Shows the cooldown of item abilities.") + @ConfigEditorBoolean + public boolean itemAbilityCooldown = false; } public static class Bazaar { @@ -215,12 +229,4 @@ public class Features { @ConfigEditorButton(runnableId = "testPos", buttonText = "Edit") public Position testPos = new Position(10, 10, false, true); } - - public static class Abilities { - - @Expose - @ConfigOption(name = "Item Cooldown", desc = "Shows the cooldown of item abilities.") - @ConfigEditorBoolean - public boolean itemAbilityCooldown = false; - } } diff --git a/src/main/java/at/lorenz/mod/items/HideNotClickableItems.kt b/src/main/java/at/lorenz/mod/items/HideNotClickableItems.kt new file mode 100644 index 000000000..75a49b578 --- /dev/null +++ b/src/main/java/at/lorenz/mod/items/HideNotClickableItems.kt @@ -0,0 +1,450 @@ +package at.lorenz.mod.items + +import at.lorenz.mod.LorenzMod +import at.lorenz.mod.bazaar.BazaarApi +import at.lorenz.mod.events.GuiContainerEvent +import at.lorenz.mod.utils.ItemUtils +import at.lorenz.mod.utils.ItemUtils.cleanName +import at.lorenz.mod.utils.ItemUtils.getLore +import at.lorenz.mod.utils.LorenzColor +import at.lorenz.mod.utils.LorenzUtils +import at.lorenz.mod.utils.LorenzUtils.removeColorCodes +import at.lorenz.mod.utils.RenderUtils.highlight +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.inventory.ContainerChest +import net.minecraft.item.ItemStack +import net.minecraftforge.event.entity.player.ItemTooltipEvent +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import org.lwjgl.opengl.GL11 + +class HideNotClickableItems { + + private var hideReason = "" + + private var lastClickTime = 0L + private var bypassUntil = 0L + + @SubscribeEvent + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!LorenzUtils.inSkyblock) return + if (isDisabled()) return + if (event.gui !is GuiChest) return + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + val lightingState = GL11.glIsEnabled(GL11.GL_LIGHTING) + GlStateManager.disableLighting() + GlStateManager.color(1f, 1f, 1f, 1f) + + for (slot in chest.inventorySlots) { + if (slot == null) continue + + if (slot.slotNumber == slot.slotIndex) continue + if (slot.stack == null) continue + + if (hide(chestName, slot.stack)) { + slot highlight LorenzColor.GRAY + } + } + + if (lightingState) GlStateManager.enableLighting() + } + + @SubscribeEvent + fun onDrawSlot(event: GuiContainerEvent.DrawSlotEvent.Pre) { + if (isDisabled()) return + if (event.gui !is GuiChest) return + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + val slot = event.slot + if (slot.slotNumber == slot.slotIndex) return + if (slot.stack == null) return + + val stack = slot.stack + + if (hide(chestName, stack)) { + event.isCanceled = true + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + fun onTooltip(event: ItemTooltipEvent) { + if (isDisabled()) return + if (event.toolTip == null) return + val guiChest = Minecraft.getMinecraft().currentScreen + if (guiChest !is GuiChest) return + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + val stack = event.itemStack + if (ItemUtils.getItemsInOpenChest().contains(stack)) return + + if (hide(chestName, stack)) { + val first = event.toolTip[0] + event.toolTip.clear() + event.toolTip.add("§7" + first.removeColorCodes()) + event.toolTip.add("") + if (hideReason == "") { + event.toolTip.add("§4No hide reason!") + LorenzUtils.warning("Not hide reason for not clickable item!") + } else { + event.toolTip.add("§c$hideReason") + } + } + } + + @SubscribeEvent + fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { + if (isDisabled()) return + if (event.gui !is GuiChest) return + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + val slot = event.slot ?: return + + if (slot.slotNumber == slot.slotIndex) return + if (slot.stack == null) return + + val stack = slot.stack + + if (hide(chestName, stack)) { + event.isCanceled = true +// SoundQueue.addToQueue("note.bass", 0.5f, 1f) + + if (System.currentTimeMillis() > lastClickTime + 5_000) { + lastClickTime = System.currentTimeMillis() +// EssentialAPI.getNotifications() +// .push( +// "§cThis item cannot be moved!", +// "§eClick here §fto disable this feature for 10 seconds!\n" + +// "§fOr disable it forever: §6/st §f+ '§6Hide Not Clickable Items§f'.", +// 5f, +// action = { +// bypassUntil = System.currentTimeMillis() + 10_000 +// }) + } + return + } + } + + private fun isDisabled(): Boolean { + if (bypassUntil > System.currentTimeMillis()) return true + + return !LorenzMod.feature.items.hideNotClickableItems + } + + private fun hide(chestName: String, stack: ItemStack): Boolean { + hideReason = "" + return when { + hideNpcSell(chestName, stack) -> true + hideChestBackpack(chestName, stack) -> true + hideSalvage(chestName, stack) -> true + hideTrade(chestName, stack) -> true + hideBazaarOrAH(chestName, stack) -> true + hideAccessoryBag(chestName, stack) -> true + hideSackOfSacks(chestName, stack) -> true + hideFishingBag(chestName, stack) -> true + hidePotionBag(chestName, stack) -> true + + else -> false + } + } + + private fun hidePotionBag(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Potion Bag")) return false + + val name = stack.cleanName() + if (isSkyBlockMenuItem(name)) { + hideReason = "The SkyBlock Menu cannot be put into the potion bag!" + return true + } + + if (stack.cleanName().endsWith(" Potion")) return false + + hideReason = "This item is not a potion!" + return true + } + + private fun hideFishingBag(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Fishing Bag")) return false + + val name = stack.cleanName() + if (isSkyBlockMenuItem(name)) { + hideReason = "The SkyBlock Menu cannot be put into the fishing bag!" + return true + } + + if (stack.cleanName().endsWith(" Bait")) return false + + hideReason = "This item is not a fishing bait!" + return true + } + + private fun hideSackOfSacks(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Sack of Sacks")) return false + + val name = stack.cleanName() + if (ItemUtils.isSack(name)) return false + if (isSkyBlockMenuItem(name)) return false + + hideReason = "This item is not a sack!" + return true + } + + private fun hideAccessoryBag(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Accessory Bag")) return false + + if (stack.getLore().any { it.contains("ACCESSORY") }) return false + if (isSkyBlockMenuItem(stack.cleanName())) return false + + hideReason = "This item is not an accessory!" + return true + } + + private fun hideTrade(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("You ")) return false + + if (ItemUtils.isCoOpSoulBound(stack)) { + hideReason = "Coop-Soulbound items cannot be traded!" + return true + } + + val name = stack.cleanName() + + if (ItemUtils.isSack(name)) { + hideReason = "Sacks cannot be traded!" + return true + } + + if (isSkyBlockMenuItem(name)) { + hideReason = "The SkyBlock Menu cannot be traded!" + return true + } + + val result = when { + name.contains("Personal Deletor") -> true + name.contains("Day Crystal") -> true + name.contains("Night Crystal") -> true + name.contains("Cat Talisman") -> true + name.contains("Lynx Talisman") -> true + name.contains("Cheetah Talisman") -> true + else -> false + } + + if (result) hideReason = "This item cannot be traded!" + return result + } + + private fun hideNpcSell(chestName: String, stack: ItemStack): Boolean { + if (chestName != "Trades" && chestName != "Ophelia") return false + + var name = stack.cleanName() + val size = stack.stackSize + val amountText = " x$size" + if (name.endsWith(amountText)) { + name = name.substring(0, name.length - amountText.length) + } + + if (isSkyBlockMenuItem(name)) { + hideReason = "The SkyBlock Menu cannot be sold at the NPC!" + return true + } + + if (!ItemUtils.isRecombobulated(stack)) { + when (name) { + "Health Potion VIII Splash Potion" -> return false + "Stone Button" -> return false + "Revive Stone" -> return false + "Premium Flesh" -> return false + "Defuse Kit" -> return false + "White Wool" -> return false + "Enchanted Wool" -> return false + "Training Weights" -> return false + "Journal Entry" -> return false + "Twilight Arrow Poison" -> return false + "Lever" -> return false + + "Fairy's Galoshes" -> return false + } + if (name.endsWith("Gem Rune I")) return false + + if (name.startsWith("Music Disc")) return false + } + + hideReason = "This item should not be sold at the NPC!" + return true + } + + private fun hideChestBackpack(chestName: String, stack: ItemStack): Boolean { + if (!chestName.contains("Ender Chest") && !chestName.contains("Backpack")) return false + + val name = stack.cleanName() + + if (isSkyBlockMenuItem(name)) { + hideReason = "The SkyBlock Menu cannot be put into the storage!" + return true + } + if (ItemUtils.isSack(name)) { + hideReason = "Sacks cannot be put into the storage!" + return true + } + + val result = when { + name.endsWith(" New Year Cake Bag") -> true + name == "Nether Wart Pouch" -> true + name == "Basket of Seeds" -> true + name == "Builder's Wand" -> true + + else -> false + } + + if (result) hideReason = "Bags cannot be put into the storage!" + return result + } + + private fun hideSalvage(chestName: String, stack: ItemStack): Boolean { + if (chestName != "Salvage Item") return false + + if (ItemUtils.isRecombobulated(stack)) { + hideReason = "This item should not be salvaged! (Recombobulated)" + return true + } + for (line in stack.getLore()) { + if (line.contains("LEGENDARY DUNGEON")) { + hideReason = "This item should not be salvaged! (Legendary)" + return true + } + } + + val name = stack.cleanName() + + val armorSets = listOf( + "Zombie Knight", + "Heavy", + "Zombie Soldier", + "Skeleton Grunt", + "Skeleton Soldier", + "Zombie Commander", + "Skeleton Master", + "Sniper", + "Skeletor", + "Rotten", + ) + + val items = mutableListOf() + for (armor in armorSets) { + items.add("$armor Helmet") + items.add("$armor Chestplate") + items.add("$armor Leggings") + items.add("$armor Boots") + } + + items.add("Zombie Soldier Cutlass") + items.add("Silent Death") + items.add("Zombie Knight Sword") + items.add("Conjuring") + items.add("Dreadlord Sword") + items.add("Soulstealer Bow") + items.add("Machine Gun Bow") + items.add("Earth Shard") + items.add("Zombie Commander Whip") + items.add("Sniper Bow") + + for (item in items) { + if (name.endsWith(" $item")) { + return false + } + } + + if (isSkyBlockMenuItem(name)) { + hideReason = "The SkyBlock Menu cannot be salvaged!" + return true + } + + hideReason = "This item cannot be salvaged!" + return true + } + + private fun hideBazaarOrAH(chestName: String, stack: ItemStack): Boolean { + val bazaarInventory = BazaarApi.isBazaarInventory(chestName) + + val auctionHouseInventory = + chestName == "Co-op Auction House" || chestName == "Auction House" || chestName == "Create BIN Auction" || chestName == "Create Auction" + if (!bazaarInventory && !auctionHouseInventory) return false + + + val displayName = stack.displayName + + if (isSkyBlockMenuItem(displayName.removeColorCodes())) { + if (bazaarInventory) hideReason = "The SkyBlock Menu is not a Bazaar Product!" + if (auctionHouseInventory) hideReason = "The SkyBlock Menu cannot be auctioned!" + return true + } + + if (bazaarInventory != BazaarApi.isBazaarItem(displayName)) { + if (bazaarInventory) hideReason = "This item is not a Bazaar Product!" + if (auctionHouseInventory) hideReason = "Bazaar Products cannot be auctioned!" + + return true + } + + if (isNotAuctionable(stack)) return true + + return false + } + + private fun isNotAuctionable(stack: ItemStack): Boolean { + if (ItemUtils.isCoOpSoulBound(stack)) { + hideReason = "Coop-Soulbound items cannot be auctioned!" + return true + } + + val name = stack.cleanName() + + if (ItemUtils.isSack(name)) { + hideReason = "Sacks cannot be auctioned!" + return true + } + + val result = when { + name.contains("Personal Deletor") -> true + name.contains("Day Crystal") -> true + name.contains("Night Crystal") -> true + + name.contains("Cat Talisman") -> true + name.contains("Lynx Talisman") -> true + name.contains("Cheetah Talisman") -> true + + name.contains("Hoe of Great Tilling") -> true + name.contains("Hoe of Greater Tilling") -> true + name.contains("InfiniDirt") -> true + name.contains("Prismapump") -> true + name.contains("Mathematical Hoe Blueprint") -> true + name.contains("Basket of Seeds") -> true + name.contains("Nether Wart Pouch") -> true + + name.contains("Carrot Hoe") -> true + name.contains("Sugar Cane Hoe") -> true + name.contains("Nether Warts Hoe") -> true + name.contains("Potato Hoe") -> true + name.contains("Melon Dicer") -> true + name.contains("Pumpkin Dicer") -> true + name.contains("Coco Chopper") -> true + name.contains("Wheat Hoe") -> true + + else -> false + } + + if (result) hideReason = "This item cannot be auctioned!" + return result + } + + private fun isSkyBlockMenuItem(name: String): Boolean = name == "SkyBlock Menu (Right Click)" +} diff --git a/src/main/java/at/lorenz/mod/items/ItemAbilityCooldown.kt b/src/main/java/at/lorenz/mod/items/ItemAbilityCooldown.kt deleted file mode 100644 index 84ab089dc..000000000 --- a/src/main/java/at/lorenz/mod/items/ItemAbilityCooldown.kt +++ /dev/null @@ -1,288 +0,0 @@ -package at.lorenz.mod.items - -import at.lorenz.mod.LorenzMod -import at.lorenz.mod.events.GuiRenderItemEvent -import at.lorenz.mod.events.LorenzActionBarEvent -import at.lorenz.mod.utils.ItemUtils -import at.lorenz.mod.utils.ItemUtils.cleanName -import at.lorenz.mod.utils.LorenzColor -import at.lorenz.mod.utils.LorenzUtils -import at.lorenz.mod.utils.LorenzUtils.between -import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.item.ItemStack -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent - -class ItemAbilityCooldown { - - var lastAbility = "" - var tick = 0 - val items = mutableMapOf() - val witherImpactDetection = WitherImpactDetection(this) - - init { - MinecraftForge.EVENT_BUS.register(witherImpactDetection) - } - - fun clickWitherImpact() { - Ability.WITHER_IMPACT.click() - } - - @SubscribeEvent - fun onActionBar(event: LorenzActionBarEvent) { - if (!isEnabled()) return - - val message: String = event.message - if (message.contains(" (§6")) { - if (message.contains("§b) ")) { - val name: String = message.between(" (§6", "§b) ") - if (name == lastAbility) return - lastAbility = name - for (ability in Ability.values()) { - if (ability.abilityName == name) { - click(ability) - return - } - } - return - } - } - lastAbility = "" - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && LorenzMod.feature.abilities.itemAbilityCooldown - } - - private fun click(ability: Ability) { -// if (ability.isActive()) return - if (!ability.actionBarDetection) return - ability.click() - } - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!isEnabled()) return - - tick++ - if (tick % 2 == 0) { - checkHotbar() - } - } - - private fun checkHotbar() { - items.clear() - for ((stack, slot) in ItemUtils.getItemsInInventoryWithSlots(true)) { -// val inHotbar = slot in 36..43 - - val itemName: String = stack.cleanName() - val ability = hasAbility(itemName) - if (ability != null) { - - if (ability.isOnCooldown()) { - val duration: Long = ability.lastClick + ability.getCooldown() - System.currentTimeMillis() - val color = if (duration < 600) LorenzColor.RED else LorenzColor.YELLOW - items[stack] = ItemText(color, ability.getDurationText(), true) - } else { - items[stack] = ItemText(LorenzColor.GREEN, "R", false) - } - } - } - - } - - @SubscribeEvent - fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { - if (!isEnabled()) return - - val item = event.stack ?: return -// if (item.stackSize != 1 || item.tagCompound?.hasKey("SkytilsNoItemOverlay") == true) return - if (item.stackSize != 1) return - - var stackTip = "" - - val guiOpen = Minecraft.getMinecraft().currentScreen != null - val itemText = items.filter { it.key == item } - .firstNotNullOfOrNull { it.value } ?: return - if (guiOpen && !itemText.onCooldown) return - - stackTip = itemText.color.getChatColor() + itemText.text - - if (stackTip.isNotEmpty()) { - GlStateManager.disableLighting() - GlStateManager.disableDepth() - GlStateManager.disableBlend() - event.fr.drawStringWithShadow( - stackTip, - (event.x + 17 - event.fr.getStringWidth(stackTip)).toFloat(), - (event.y + 9).toFloat(), - 16777215 - ) - GlStateManager.enableLighting() - GlStateManager.enableDepth() - } - } - -// @SubscribeEvent -// fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Pre) { -// if (!isEnabled()) return -// -// val item = event.stack ?: return -//// if (item.stackSize != 1 || item.tagCompound?.hasKey("SkytilsNoItemOverlay") == true) return -// if (item.stackSize != 1) return -// -// var stackTip = "" -// -// val isActive = Minecraft.getMinecraft().currentScreen == null -// val itemText = items.filter { it.key == item && it.value.active } -// .firstNotNullOfOrNull { it.value } -// -// if (itemText != null) return -//// if (!isActive && !itemText.active) return -// -// stackTip = "T" -// -//// items.filter { it.key == item } -//// .forEach { stackTip = it.value.color.getChatColor() + it.value.text } -// -// if (stackTip.isNotEmpty()) { -// GlStateManager.disableLighting() -// GlStateManager.disableDepth() -// GlStateManager.disableBlend() -// event.fr.drawStringWithShadow( -// stackTip, -// (event.x + 17 - event.fr.getStringWidth(stackTip)).toFloat(), -// (event.y + 9).toFloat(), -// 16777215 -// ) -// GlStateManager.enableLighting() -// GlStateManager.enableDepth() -// } -// } - -// @SubscribeEvent -// fun onGuiDrawEvent(event: GuiContainerEvent.BackgroundDrawnEvent) { -// if (!isEnabled()) -// -// val guiContainer: GuiContainer? = event.gui -// if (guiContainer != null && guiContainer !is GuiInventory) return -// val chest = guiContainer.inventorySlots -// -//// val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() -//// if (chestName != "Spirit Leap") return -// -// for (slot in chest.inventorySlots) { -// if (slot == null) continue -//// if (slot.slotNumber == slot.slotIndex) continue -// if (slot.stack == null) continue -// -// val stack = slot.stack -// -//// for ((item, text) in map) { -//// if (item == stack) { -//// slot highlight text.color -//// } -//// } -// map.filter { it.key == stack }.forEach { slot highlight it.value.color } -// -//// slot highlight LorenzColor.WHITE -// -//// val displayName = stack.displayName -//// if (displayName == " ") continue -// -//// val itemLore = stack.getLore() -//// if (itemLore.size == 1 && itemLore[0] == "§eClick to teleport!") { -//// -//// if (displayName.contains(witherDoorName)) { -//// if (lastWitherDoorOpened + 10_000 > System.currentTimeMillis()) { -//// slot highlight LorenzColor.YELLOW -//// return -//// } -//// } -//// if (displayName.contains(teleportName)) { -//// if (lastTeleport + 10_000 > System.currentTimeMillis()) { -//// slot highlight LorenzColor.AQUA -//// return -//// } -//// } -//// } else { -//// //TODO hide the item totally? -//// slot highlight LorenzColor.RED -//// } -// -// } -// } - - private fun hasAbility(itemName: String): Ability? { - for (ability in Ability.values()) { - for (name in ability.itemNames) { - if (itemName.contains(name)) { - return ability - } - } - } - return null - } - - enum class Ability( - val abilityName: String, - val cooldownInSeconds: Long, - vararg val itemNames: String, - var lastClick: Long = 0L, - val actionBarDetection: Boolean = true - ) { - ATOMSPLIT("Soulcry", 4, "Atomsplit Katana", "Vorpal Katana", "Voidedge Katana"), - WITHER_IMPACT("Wither Impact", 5, "Hyperion", "Scylla", "Valkyrie", "Astrea", actionBarDetection = false), - - HEAL_1("Small Heal", 7, "Wand of Healing"), - HEAL_2("Medium Heal", 7, "Wand of Mending"), - HEAL_3("Big Heal", 7, "Wand of Restoration"), - HEAL_4("Huge Heal", 7, "Wand of Atonement"), - - ICE_SPRAY("Ice Spray", 5, "Ice Spray Wand"), - GYRO("Gravity Storm", 30, "Gyrokinetic Wand"), - GIANTS_SWORD("Giant's Slam", 30, "Giant's Sword"), - - STAR_FALL("Starfall", 2, "Starlight Wand"), - VODOO_DOLL("Acupuncture", 5, "Voodoo Doll"), - INK_WAND("Ink Bomb", 30, "Ink Wand"), - GOLEM_SWORD("Iron Punch", 3, "Golem Sword"), - EMBER_ROD("Fire Blast", 30, "Ember Rod"), - ENDER_BOW("Ender Warp", 30, "Ender Bow"), - - LIVID_DAGGER("Throw", 5, "Livid Dagger"), - WEIRD_TUBA("Howl", 20, "Weird Tuba"), - - ENDSTONE_SWORD("Extreme Focus", 5, "End Stone Sword"), - PIGMAN_SWORD("Burning Souls", 5, "Pigman Sword"), - - SOULWARD("Soulward", 20, "Soul Esoward"); - - fun click() { - lastClick = System.currentTimeMillis() - } - - fun isOnCooldown(): Boolean = lastClick + getCooldown() > System.currentTimeMillis() - - fun getCooldown(): Long = cooldownInSeconds * 1000 - - fun getDurationText(): String { - var duration: Long = lastClick + getCooldown() - System.currentTimeMillis() - return if (duration < 1600) { - duration /= 100 - var d = duration.toDouble() - d /= 10.0 - LorenzUtils.formatDouble(d) - } else { - duration /= 1000 - duration++ - LorenzUtils.formatInteger(duration.toInt()) - } - } - - } - - class ItemText(val color: LorenzColor, val text: String, val onCooldown: Boolean) -} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/items/ItemDisplayOverlayFeatures.kt b/src/main/java/at/lorenz/mod/items/ItemDisplayOverlayFeatures.kt new file mode 100644 index 000000000..c07b2fff4 --- /dev/null +++ b/src/main/java/at/lorenz/mod/items/ItemDisplayOverlayFeatures.kt @@ -0,0 +1,121 @@ +package at.lorenz.mod.items + +import at.lorenz.mod.LorenzMod +import at.lorenz.mod.events.GuiRenderItemEvent +import at.lorenz.mod.utils.ItemUtils +import at.lorenz.mod.utils.ItemUtils.cleanName +import at.lorenz.mod.utils.LorenzDebug +import at.lorenz.mod.utils.LorenzUtils +import at.lorenz.mod.utils.LorenzUtils.between +import at.lorenz.mod.utils.LorenzUtils.matchRegex +import at.lorenz.mod.utils.NumberUtil.romanToDecimal +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ItemDisplayOverlayFeatures { + + @SubscribeEvent + fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { + + val item = event.stack ?: return + + if (!LorenzUtils.inSkyblock || item.stackSize != 1 || item.tagCompound?.hasKey("SkytilsNoItemOverlay") == true) return + + val stackTip = getStackTip(item) + + if (stackTip.isNotEmpty()) { + GlStateManager.disableLighting() + GlStateManager.disableDepth() + GlStateManager.disableBlend() + event.fr.drawStringWithShadow( + stackTip, + (event.x + 17 - event.fr.getStringWidth(stackTip)).toFloat(), + (event.y + 9).toFloat(), + 16777215 + ) + GlStateManager.enableLighting() + GlStateManager.enableDepth() + } + + } + + private fun getStackTip(item: ItemStack): String { + val name = item.cleanName() + + if (LorenzMod.feature.items.displayMasterStarNumber) { + when (name) { + "First Master Star" -> return "1" + "Second Master Star" -> return "2" + "Third Master Star" -> return "3" + "Fourth Master Star" -> return "4" + "Fifth Master Star" -> return "5" + } + } + + if (LorenzMod.feature.items.displayMasterSkullNumber) { + if (name.matchRegex("(.*)Master Skull - Tier .")) { + return name.substring(name.length - 1) + } + } + + if (LorenzMod.feature.items.displayDungeonHeadFloor) { + if (name.contains("Golden ") || name.contains("Diamond ")) { + when { + name.contains("Bonzo") -> return "1" + name.contains("Scarf") -> return "2" + name.contains("Professor") -> return "3" + name.contains("Thorn") -> return "4" + name.contains("Livid") -> return "5" + name.contains("Sadan") -> return "6" + name.contains("Necron") -> return "7" + } + } + } + + if (LorenzMod.feature.items.displayNewYearCakeNumber) { + if (name.startsWith("New Year Cake (")) { + try { + return "§b" + name.between("(Year ", ")") + } catch (e: IndexOutOfBoundsException) { + val message = "New Year Cake error in string: '$name': ${e.message}" + LorenzDebug.log(message) + LorenzUtils.error(message) + } + } + } + + if (LorenzMod.feature.items.displayPetLevel) { + if (ItemUtils.isPet(name)) { + try { + val level = name.between("Lvl ", "] ").toInt() + if (level != ItemUtils.maxPetLevel(name)) { + return "$level" + } + } catch (e: java.lang.NumberFormatException) { + e.printStackTrace() + LorenzDebug.log("name: '$name'") + LorenzUtils.warning("NumberFormatException at lorenzItemDisplayPetLevel") + } + } + } + + if (LorenzMod.feature.items.displaySackName) { + if (ItemUtils.isSack(name)) { + val split = name.split(" ") + val sackName = split[split.size - 2] + return (if (name.contains("Enchanted")) "§5" else "") + sackName.substring(0, 2) + } + } + + if (LorenzMod.feature.items.displayMinionTier) { + if (name.contains(" Minion ")) { + val array = name.split(" ") + val last = array[array.size - 1] + return last.romanToDecimal().toString() + } + } + + return "" + } +} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/items/WitherImpactDetection.kt b/src/main/java/at/lorenz/mod/items/WitherImpactDetection.kt deleted file mode 100644 index 5312e28a3..000000000 --- a/src/main/java/at/lorenz/mod/items/WitherImpactDetection.kt +++ /dev/null @@ -1,65 +0,0 @@ -package at.lorenz.mod.items - -import at.lorenz.mod.events.PacketEvent -import at.lorenz.mod.utils.ItemUtil.asStringSet -import at.lorenz.mod.utils.ItemUtil.getExtraAttributes -import at.lorenz.mod.utils.LorenzUtils -import net.minecraft.client.Minecraft -import net.minecraft.init.Items -import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement -import net.minecraft.network.play.server.S1CPacketEntityMetadata -import net.minecraft.network.play.server.S2APacketParticles -import net.minecraft.util.EnumParticleTypes -import net.minecraftforge.common.util.Constants -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent - -/** - * Taken from Skytils under AGPL 3.0 - * Modified - * https://github.com/Skytils/SkytilsMod/blob/1.x/LICENSE.md - * @author Skytils - */ -class WitherImpactDetection(private val itemAbilityCooldown: ItemAbilityCooldown) { - - val S2APacketParticles.type: EnumParticleTypes - get() = this.particleType - var lastShieldUse = -1L - var lastShieldClick = 0L - - @SubscribeEvent - fun onReceivePacket(event: PacketEvent.ReceiveEvent) { - val mc = Minecraft.getMinecraft() - if (!LorenzUtils.inSkyblock || mc.theWorld == null) return - - event.packet.apply { - - if (this is S1CPacketEntityMetadata && lastShieldClick != -1L && entityId == mc.thePlayer?.entityId && System.currentTimeMillis() - lastShieldClick <= 500 && func_149376_c()?.any { it.dataValueId == 17 } == true) { - lastShieldUse = System.currentTimeMillis() - lastShieldClick = -1 - itemAbilityCooldown.clickWitherImpact() - } - } - } - - @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { - val mc = Minecraft.getMinecraft() - if (!LorenzUtils.inSkyblock || lastShieldUse != -1L || mc.thePlayer?.heldItem == null) return - if (event.packet is C08PacketPlayerBlockPlacement && mc.thePlayer.heldItem.item == Items.iron_sword && getExtraAttributes( - mc.thePlayer.heldItem - )?.getTagList("ability_scroll", Constants.NBT.TAG_STRING)?.asStringSet() - ?.contains("WITHER_SHIELD_SCROLL") == true - ) { - lastShieldClick = System.currentTimeMillis() - } - } - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (lastShieldUse != -1L) { - val diff = ((lastShieldUse + 5000 - System.currentTimeMillis()) / 1000f) - if (diff < 0) lastShieldUse = -1 - } - } -} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/items/abilitycooldown/ItemAbilityCooldown.kt b/src/main/java/at/lorenz/mod/items/abilitycooldown/ItemAbilityCooldown.kt new file mode 100644 index 000000000..2a0c215ab --- /dev/null +++ b/src/main/java/at/lorenz/mod/items/abilitycooldown/ItemAbilityCooldown.kt @@ -0,0 +1,288 @@ +package at.lorenz.mod.items.abilitycooldown + +import at.lorenz.mod.LorenzMod +import at.lorenz.mod.events.GuiRenderItemEvent +import at.lorenz.mod.events.LorenzActionBarEvent +import at.lorenz.mod.utils.ItemUtils +import at.lorenz.mod.utils.ItemUtils.cleanName +import at.lorenz.mod.utils.LorenzColor +import at.lorenz.mod.utils.LorenzUtils +import at.lorenz.mod.utils.LorenzUtils.between +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.item.ItemStack +import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +class ItemAbilityCooldown { + + var lastAbility = "" + var tick = 0 + val items = mutableMapOf() + val witherImpactDetection = WitherImpactDetection(this) + + init { + MinecraftForge.EVENT_BUS.register(witherImpactDetection) + } + + fun clickWitherImpact() { + Ability.WITHER_IMPACT.click() + } + + @SubscribeEvent + fun onActionBar(event: LorenzActionBarEvent) { + if (!isEnabled()) return + + val message: String = event.message + if (message.contains(" (§6")) { + if (message.contains("§b) ")) { + val name: String = message.between(" (§6", "§b) ") + if (name == lastAbility) return + lastAbility = name + for (ability in Ability.values()) { + if (ability.abilityName == name) { + click(ability) + return + } + } + return + } + } + lastAbility = "" + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inSkyblock && LorenzMod.feature.items.itemAbilityCooldown + } + + private fun click(ability: Ability) { +// if (ability.isActive()) return + if (!ability.actionBarDetection) return + ability.click() + } + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!isEnabled()) return + + tick++ + if (tick % 2 == 0) { + checkHotbar() + } + } + + private fun checkHotbar() { + items.clear() + for ((stack, slot) in ItemUtils.getItemsInInventoryWithSlots(true)) { +// val inHotbar = slot in 36..43 + + val itemName: String = stack.cleanName() + val ability = hasAbility(itemName) + if (ability != null) { + + if (ability.isOnCooldown()) { + val duration: Long = ability.lastClick + ability.getCooldown() - System.currentTimeMillis() + val color = if (duration < 600) LorenzColor.RED else LorenzColor.YELLOW + items[stack] = ItemText(color, ability.getDurationText(), true) + } else { + items[stack] = ItemText(LorenzColor.GREEN, "R", false) + } + } + } + + } + + @SubscribeEvent + fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { + if (!isEnabled()) return + + val item = event.stack ?: return +// if (item.stackSize != 1 || item.tagCompound?.hasKey("SkytilsNoItemOverlay") == true) return + if (item.stackSize != 1) return + + var stackTip = "" + + val guiOpen = Minecraft.getMinecraft().currentScreen != null + val itemText = items.filter { it.key == item } + .firstNotNullOfOrNull { it.value } ?: return + if (guiOpen && !itemText.onCooldown) return + + stackTip = itemText.color.getChatColor() + itemText.text + + if (stackTip.isNotEmpty()) { + GlStateManager.disableLighting() + GlStateManager.disableDepth() + GlStateManager.disableBlend() + event.fr.drawStringWithShadow( + stackTip, + (event.x + 17 - event.fr.getStringWidth(stackTip)).toFloat(), + (event.y + 9).toFloat(), + 16777215 + ) + GlStateManager.enableLighting() + GlStateManager.enableDepth() + } + } + +// @SubscribeEvent +// fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Pre) { +// if (!isEnabled()) return +// +// val item = event.stack ?: return +//// if (item.stackSize != 1 || item.tagCompound?.hasKey("SkytilsNoItemOverlay") == true) return +// if (item.stackSize != 1) return +// +// var stackTip = "" +// +// val isActive = Minecraft.getMinecraft().currentScreen == null +// val itemText = items.filter { it.key == item && it.value.active } +// .firstNotNullOfOrNull { it.value } +// +// if (itemText != null) return +//// if (!isActive && !itemText.active) return +// +// stackTip = "T" +// +//// items.filter { it.key == item } +//// .forEach { stackTip = it.value.color.getChatColor() + it.value.text } +// +// if (stackTip.isNotEmpty()) { +// GlStateManager.disableLighting() +// GlStateManager.disableDepth() +// GlStateManager.disableBlend() +// event.fr.drawStringWithShadow( +// stackTip, +// (event.x + 17 - event.fr.getStringWidth(stackTip)).toFloat(), +// (event.y + 9).toFloat(), +// 16777215 +// ) +// GlStateManager.enableLighting() +// GlStateManager.enableDepth() +// } +// } + +// @SubscribeEvent +// fun onGuiDrawEvent(event: GuiContainerEvent.BackgroundDrawnEvent) { +// if (!isEnabled()) +// +// val guiContainer: GuiContainer? = event.gui +// if (guiContainer != null && guiContainer !is GuiInventory) return +// val chest = guiContainer.inventorySlots +// +//// val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() +//// if (chestName != "Spirit Leap") return +// +// for (slot in chest.inventorySlots) { +// if (slot == null) continue +//// if (slot.slotNumber == slot.slotIndex) continue +// if (slot.stack == null) continue +// +// val stack = slot.stack +// +//// for ((item, text) in map) { +//// if (item == stack) { +//// slot highlight text.color +//// } +//// } +// map.filter { it.key == stack }.forEach { slot highlight it.value.color } +// +//// slot highlight LorenzColor.WHITE +// +//// val displayName = stack.displayName +//// if (displayName == " ") continue +// +//// val itemLore = stack.getLore() +//// if (itemLore.size == 1 && itemLore[0] == "§eClick to teleport!") { +//// +//// if (displayName.contains(witherDoorName)) { +//// if (lastWitherDoorOpened + 10_000 > System.currentTimeMillis()) { +//// slot highlight LorenzColor.YELLOW +//// return +//// } +//// } +//// if (displayName.contains(teleportName)) { +//// if (lastTeleport + 10_000 > System.currentTimeMillis()) { +//// slot highlight LorenzColor.AQUA +//// return +//// } +//// } +//// } else { +//// //TODO hide the item totally? +//// slot highlight LorenzColor.RED +//// } +// +// } +// } + + private fun hasAbility(itemName: String): Ability? { + for (ability in Ability.values()) { + for (name in ability.itemNames) { + if (itemName.contains(name)) { + return ability + } + } + } + return null + } + + enum class Ability( + val abilityName: String, + val cooldownInSeconds: Long, + vararg val itemNames: String, + var lastClick: Long = 0L, + val actionBarDetection: Boolean = true + ) { + ATOMSPLIT("Soulcry", 4, "Atomsplit Katana", "Vorpal Katana", "Voidedge Katana"), + WITHER_IMPACT("Wither Impact", 5, "Hyperion", "Scylla", "Valkyrie", "Astrea", actionBarDetection = false), + + HEAL_1("Small Heal", 7, "Wand of Healing"), + HEAL_2("Medium Heal", 7, "Wand of Mending"), + HEAL_3("Big Heal", 7, "Wand of Restoration"), + HEAL_4("Huge Heal", 7, "Wand of Atonement"), + + ICE_SPRAY("Ice Spray", 5, "Ice Spray Wand"), + GYRO("Gravity Storm", 30, "Gyrokinetic Wand"), + GIANTS_SWORD("Giant's Slam", 30, "Giant's Sword"), + + STAR_FALL("Starfall", 2, "Starlight Wand"), + VODOO_DOLL("Acupuncture", 5, "Voodoo Doll"), + INK_WAND("Ink Bomb", 30, "Ink Wand"), + GOLEM_SWORD("Iron Punch", 3, "Golem Sword"), + EMBER_ROD("Fire Blast", 30, "Ember Rod"), + ENDER_BOW("Ender Warp", 30, "Ender Bow"), + + LIVID_DAGGER("Throw", 5, "Livid Dagger"), + WEIRD_TUBA("Howl", 20, "Weird Tuba"), + + ENDSTONE_SWORD("Extreme Focus", 5, "End Stone Sword"), + PIGMAN_SWORD("Burning Souls", 5, "Pigman Sword"), + + SOULWARD("Soulward", 20, "Soul Esoward"); + + fun click() { + lastClick = System.currentTimeMillis() + } + + fun isOnCooldown(): Boolean = lastClick + getCooldown() > System.currentTimeMillis() + + fun getCooldown(): Long = cooldownInSeconds * 1000 + + fun getDurationText(): String { + var duration: Long = lastClick + getCooldown() - System.currentTimeMillis() + return if (duration < 1600) { + duration /= 100 + var d = duration.toDouble() + d /= 10.0 + LorenzUtils.formatDouble(d) + } else { + duration /= 1000 + duration++ + LorenzUtils.formatInteger(duration.toInt()) + } + } + + } + + class ItemText(val color: LorenzColor, val text: String, val onCooldown: Boolean) +} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/items/abilitycooldown/WitherImpactDetection.kt b/src/main/java/at/lorenz/mod/items/abilitycooldown/WitherImpactDetection.kt new file mode 100644 index 000000000..e9f1d7eed --- /dev/null +++ b/src/main/java/at/lorenz/mod/items/abilitycooldown/WitherImpactDetection.kt @@ -0,0 +1,65 @@ +package at.lorenz.mod.items.abilitycooldown + +import at.lorenz.mod.events.PacketEvent +import at.lorenz.mod.utils.ItemUtil.asStringSet +import at.lorenz.mod.utils.ItemUtil.getExtraAttributes +import at.lorenz.mod.utils.LorenzUtils +import net.minecraft.client.Minecraft +import net.minecraft.init.Items +import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement +import net.minecraft.network.play.server.S1CPacketEntityMetadata +import net.minecraft.network.play.server.S2APacketParticles +import net.minecraft.util.EnumParticleTypes +import net.minecraftforge.common.util.Constants +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +/** + * Taken from Skytils under AGPL 3.0 + * Modified + * https://github.com/Skytils/SkytilsMod/blob/1.x/LICENSE.md + * @author Skytils + */ +class WitherImpactDetection(private val itemAbilityCooldown: ItemAbilityCooldown) { + + val S2APacketParticles.type: EnumParticleTypes + get() = this.particleType + var lastShieldUse = -1L + var lastShieldClick = 0L + + @SubscribeEvent + fun onReceivePacket(event: PacketEvent.ReceiveEvent) { + val mc = Minecraft.getMinecraft() + if (!LorenzUtils.inSkyblock || mc.theWorld == null) return + + event.packet.apply { + + if (this is S1CPacketEntityMetadata && lastShieldClick != -1L && entityId == mc.thePlayer?.entityId && System.currentTimeMillis() - lastShieldClick <= 500 && func_149376_c()?.any { it.dataValueId == 17 } == true) { + lastShieldUse = System.currentTimeMillis() + lastShieldClick = -1 + itemAbilityCooldown.clickWitherImpact() + } + } + } + + @SubscribeEvent + fun onSendPacket(event: PacketEvent.SendEvent) { + val mc = Minecraft.getMinecraft() + if (!LorenzUtils.inSkyblock || lastShieldUse != -1L || mc.thePlayer?.heldItem == null) return + if (event.packet is C08PacketPlayerBlockPlacement && mc.thePlayer.heldItem.item == Items.iron_sword && getExtraAttributes( + mc.thePlayer.heldItem + )?.getTagList("ability_scroll", Constants.NBT.TAG_STRING)?.asStringSet() + ?.contains("WITHER_SHIELD_SCROLL") == true + ) { + lastShieldClick = System.currentTimeMillis() + } + } + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (lastShieldUse != -1L) { + val diff = ((lastShieldUse + 5000 - System.currentTimeMillis()) / 1000f) + if (diff < 0) lastShieldUse = -1 + } + } +} \ No newline at end of file -- cgit