diff options
Diffstat (limited to 'src')
17 files changed, 631 insertions, 16 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 4e4cbc68d..c2cf5a25d 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -220,6 +220,7 @@ import at.hannibal2.skyhanni.features.misc.trevor.TrevorFeatures import at.hannibal2.skyhanni.features.misc.trevor.TrevorSolver import at.hannibal2.skyhanni.features.misc.trevor.TrevorTracker import at.hannibal2.skyhanni.features.misc.update.UpdateManager +import at.hannibal2.skyhanni.features.misc.visualwords.ModifyVisualWords import at.hannibal2.skyhanni.features.mobs.AreaMiniBossFeatures import at.hannibal2.skyhanni.features.mobs.AshfangMinisNametagHider import at.hannibal2.skyhanni.features.mobs.MobHighlight @@ -585,6 +586,7 @@ class SkyHanniMod { loadModule(CosmeticFollowingLine()) loadModule(SuperpairsClicksAlert()) loadModule(PowderTracker()) + loadModule(ModifyVisualWords) loadModule(TabListReader) loadModule(TabListRenderer) loadModule(GlowingDroppedItems()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java index a80211e3a..9f1455605 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java @@ -13,6 +13,7 @@ import at.hannibal2.skyhanni.features.misc.FrozenTreasure; import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData; import at.hannibal2.skyhanni.features.misc.powdertracker.PowderChestReward; import at.hannibal2.skyhanni.features.misc.trevor.TrevorTracker; +import at.hannibal2.skyhanni.features.misc.visualwords.VisualWord; import at.hannibal2.skyhanni.features.rift.area.westvillage.KloonTerminal; import at.hannibal2.skyhanni.utils.LorenzVec; import at.hannibal2.skyhanni.utils.NEUInternalName; @@ -37,6 +38,9 @@ public class Storage { public Map<Long, List<CropType>> gardenJacobFarmingContestTimes = new HashMap<>(); @Expose + public List<VisualWord> modifiedWords = new ArrayList<>(); + + @Expose public Boolean contestSendingAsked = false; @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt index 7d21fa92e..57f95b56b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -28,6 +28,7 @@ import at.hannibal2.skyhanni.features.misc.MarkedPlayerManager import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil import at.hannibal2.skyhanni.features.misc.massconfiguration.DefaultConfigFeatures +import at.hannibal2.skyhanni.features.misc.visualwords.VisualWordGui import at.hannibal2.skyhanni.features.slayer.SlayerItemProfitTracker import at.hannibal2.skyhanni.test.PacketTest import at.hannibal2.skyhanni.test.SkyHanniConfigSearchResetCommand @@ -277,6 +278,7 @@ object Commands { // "shsendtranslation", // "Respond with a translation of the message that the user clicks" // ) { Translator.toEnglish(it) } + registerCommand("shwords", "Opens the config list for modifying visual words") { openVisualWords() } } private fun commandHelp(args: Array<String>) { @@ -325,6 +327,15 @@ object Commands { } } + @JvmStatic + fun openVisualWords() { + if (!LorenzUtils.onHypixel) { + LorenzUtils.chat("§cYou need to join Hypixel to use this feature!") + } else { + SkyHanniMod.screenToOpen = VisualWordGui() + } + } + private fun clearFarmingItems() { val config = GardenAPI.config?.fortune ?: return LorenzUtils.chat("§e[SkyHanni] clearing farming items") diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java index ed365809c..47b62e9e5 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/GUIConfig.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.features; import at.hannibal2.skyhanni.config.FeatureToggle; +import at.hannibal2.skyhanni.config.commands.Commands; import at.hannibal2.skyhanni.config.core.config.Position; import at.hannibal2.skyhanni.data.GuiEditManager; import com.google.gson.annotations.Expose; @@ -30,6 +31,32 @@ public class GUIConfig { @ConfigEditorSlider(minValue = 0.1F, maxValue = 10, minStep = 0.05F) public float globalScale = 1F; + + @Expose + @ConfigOption(name = "Modify Visual Words", desc = "") + @Accordion + public ModifyWords modifyWords = new ModifyWords(); + + public static class ModifyWords { + + @Expose + @ConfigOption(name = "Enabled", desc = "Enables replacing all instances of a word or phrase with another word or phrase.") + @ConfigEditorBoolean + @FeatureToggle + public boolean enabled = true; + + @Expose + @ConfigOption(name = "Work Outside SkyBlock", desc = "Allows modifying visual words anywhere on Hypixel.") + @ConfigEditorBoolean + @FeatureToggle + public boolean workOutside = false; + + @ConfigOption(name = "Open Config", desc = "Opens the menu to setup the visual words.\n§eCommand: /shwords") + @ConfigEditorButton(buttonText = "Open") + public Runnable open = Commands::openVisualWords; + + } + @Expose @ConfigOption(name = "Custom Text Box", desc = "") @Accordion diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java index 2bb959f44..a74895a7f 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/GardenConfig.java @@ -1270,7 +1270,7 @@ public class GardenConfig { @ConfigOption(name = "Farming Fortune Guide", desc = "Opens a guide that breaks down your Farming Fortune.\n§eCommand: /ff") @ConfigEditorButton(buttonText = "Open") - public Runnable positions = Commands::openFortuneGuide; + public Runnable open = Commands::openFortuneGuide; @Expose public Position farmingFortunePos = new Position(5, -180, false, true); diff --git a/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt b/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt index 9688add2c..0137c4491 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/RenderData.kt @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests +import at.hannibal2.skyhanni.features.misc.visualwords.VisualWordGui import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.client.gui.inventory.GuiInventory @@ -19,7 +20,7 @@ class RenderData { fun onRenderOverlay(event: RenderGameOverlayEvent.Pre) { if (event.type != RenderGameOverlayEvent.ElementType.HOTBAR) return if (!SkyHanniDebugsAndTests.globalRender) return - if (GuiEditManager.isInGui() || FFGuideGUI.isInGui()) return + if (GuiEditManager.isInGui() || FFGuideGUI.isInGui() || VisualWordGui.isInGui()) return GuiRenderEvent.GuiOverlayRenderEvent().postAndCatch() } @@ -27,7 +28,7 @@ class RenderData { @SubscribeEvent fun onBackgroundDraw(event: GuiScreenEvent.BackgroundDrawnEvent) { if (!SkyHanniDebugsAndTests.globalRender) return - if (GuiEditManager.isInGui() || FFGuideGUI.isInGui()) return + if (GuiEditManager.isInGui() || FFGuideGUI.isInGui() || VisualWordGui.isInGui()) return val currentScreen = Minecraft.getMinecraft().currentScreen ?: return if (currentScreen !is GuiInventory && currentScreen !is GuiChest) return diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt index 65c6c54b2..b7e103be1 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt @@ -97,96 +97,120 @@ open class FFGuideGUI : GuiScreen() { GuiRenderUtils.drawStringCentered("§7SkyHanni", guiLeft + 325, guiTop + 170) if (currentCrop == null) { GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.HELMET.getItem(), guiLeft + 142, guiTop + 5, mouseX, mouseY, if (currentArmor == 1) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.CHESTPLATE.getItem(), guiLeft + 162, guiTop + 5, mouseX, mouseY, if (currentArmor == 2) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.LEGGINGS.getItem(), guiLeft + 182, guiTop + 5, mouseX, mouseY, if (currentArmor == 3) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BOOTS.getItem(), guiLeft + 202, guiTop + 5, mouseX, mouseY, if (currentArmor == 4) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.NECKLACE.getItem(), guiLeft + 262, guiTop + 5, mouseX, mouseY, if (currentEquipment == 1) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.CLOAK.getItem(), guiLeft + 282, guiTop + 5, mouseX, mouseY, if (currentEquipment == 2) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BELT.getItem(), guiLeft + 302, guiTop + 5, mouseX, mouseY, if (currentEquipment == 3) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BRACELET.getItem(), guiLeft + 322, guiTop + 5, mouseX, mouseY, if (currentEquipment == 4) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.ELEPHANT.getItem(), guiLeft + 142, guiTop + 130, mouseX, mouseY, if (currentPet == FarmingItems.ELEPHANT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.MOOSHROOM_COW.getItem(), guiLeft + 162, guiTop + 130, mouseX, mouseY, if (currentPet == FarmingItems.MOOSHROOM_COW) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.RABBIT.getItem(), guiLeft + 182, guiTop + 130, mouseX, mouseY, if (currentPet == FarmingItems.RABBIT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BEE.getItem(), guiLeft + 202, guiTop + 130, mouseX, mouseY, if (currentPet == FarmingItems.BEE) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) } else { GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.ELEPHANT.getItem(), guiLeft + 142, guiTop + 160, mouseX, mouseY, if (currentPet == FarmingItems.ELEPHANT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.MOOSHROOM_COW.getItem(), guiLeft + 162, guiTop + 160, mouseX, mouseY, if (currentPet == FarmingItems.MOOSHROOM_COW) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.RABBIT.getItem(), guiLeft + 182, guiTop + 160, mouseX, mouseY, if (currentPet == FarmingItems.RABBIT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BEE.getItem(), guiLeft + 202, guiTop + 160, mouseX, mouseY, if (currentPet == FarmingItems.BEE) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt() ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.HELMET.getItem(), guiLeft + 162, guiTop + 80, mouseX, mouseY ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.CHESTPLATE.getItem(), guiLeft + 162, guiTop + 100, mouseX, mouseY ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.LEGGINGS.getItem(), guiLeft + 162, guiTop + 120, mouseX, mouseY ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BOOTS.getItem(), guiLeft + 162, guiTop + 140, mouseX, mouseY ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.NECKLACE.getItem(), guiLeft + 182, guiTop + 80, mouseX, mouseY ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.CLOAK.getItem(), guiLeft + 182, guiTop + 100, mouseX, mouseY ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BELT.getItem(), guiLeft + 182, guiTop + 120, mouseX, mouseY ) GuiRenderUtils.renderItemAndTip( + tooltipToDisplay, FarmingItems.BRACELET.getItem(), guiLeft + 182, guiTop + 140, mouseX, mouseY ) } @@ -443,4 +467,4 @@ open class FFGuideGUI : GuiScreen() { abstract class FFGuidePage { abstract fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float) } -} +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt index 7a5435393..cb20cc86a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt @@ -12,7 +12,7 @@ class CropPage: FFGuideGUI.FFGuidePage() { override fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float) { for (item in FarmingItems.entries) { if (item.name == FFGuideGUI.currentCrop?.name) { - GuiRenderUtils.renderItemAndTip(item.getItem(), FFGuideGUI.guiLeft + 172, FFGuideGUI.guiTop + 60, mouseX, mouseY) + GuiRenderUtils.renderItemAndTip(FFGuideGUI.tooltipToDisplay, item.getItem(), FFGuideGUI.guiLeft + 172, FFGuideGUI.guiTop + 60, mouseX, mouseY) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt index 27dfc6a33..bef201bc7 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt @@ -23,10 +23,10 @@ class UpgradePage: FFGuideGUI.FFGuidePage() { GlStateManager.scale(0.75f, 0.75f, 1f) GuiRenderUtils.drawString("Upgrade", (FFGuideGUI.guiLeft + 45) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale) + GuiRenderUtils.drawString("Item", (FFGuideGUI.guiLeft + 190) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale) GuiRenderUtils.drawString("FF increase", (FFGuideGUI.guiLeft + 240) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale) GuiRenderUtils.drawString("Cost/FF", (FFGuideGUI.guiLeft + 290) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale) GuiRenderUtils.drawString("Total", (FFGuideGUI.guiLeft + 330) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale) - GuiRenderUtils.drawString("Item", (FFGuideGUI.guiLeft + 190) * inverseScale, (FFGuideGUI.guiTop + 5) * inverseScale) val upgradeList = if (FFGuideGUI.currentCrop == null) FortuneUpgrades.genericUpgrades else FortuneUpgrades.cropSpecificUpgrades listLength = upgradeList.size @@ -43,12 +43,12 @@ class UpgradePage: FFGuideGUI.FFGuidePage() { formattedUpgrade = "$formattedUpgrade §fx${upgrade.itemQuantity}" } GuiRenderUtils.drawTwoLineString(upgrade.description, (FFGuideGUI.guiLeft + 15) * inverseScale, (adjustedY + 25 * index) * inverseScale) + GuiRenderUtils.renderItemAndTip(FFGuideGUI.tooltipToDisplay, upgradeItem, (FFGuideGUI.guiLeft + 155) * inverseScale, (adjustedY + 25 * index - 5) * inverseScale, + mouseX * inverseScale, mouseY * inverseScale, 0x00FFFFFF) + GuiRenderUtils.drawString(formattedUpgrade, (FFGuideGUI.guiLeft + 180) * inverseScale, (adjustedY + 25 * index) * inverseScale) GuiRenderUtils.drawString("§a${DecimalFormat("0.##").format(upgrade.fortuneIncrease)}", (FFGuideGUI.guiLeft + 270) * inverseScale, (adjustedY + 25 * index) * inverseScale) GuiRenderUtils.drawString("§6" + upgrade.costPerFF?.let { NumberUtil.format(it) }, (FFGuideGUI.guiLeft + 300) * inverseScale, (adjustedY + 25 * index) * inverseScale) GuiRenderUtils.drawString(("§6" + upgrade.cost?.let { NumberUtil.format(it) }), (FFGuideGUI.guiLeft + 335) * inverseScale, (adjustedY + 25 * index) * inverseScale) - GuiRenderUtils.drawString(formattedUpgrade, (FFGuideGUI.guiLeft + 180) * inverseScale, (adjustedY + 25 * index) * inverseScale) - GuiRenderUtils.renderItemAndTip(upgradeItem, (FFGuideGUI.guiLeft + 155) * inverseScale, (adjustedY + 25 * index - 5) * inverseScale, - mouseX * inverseScale, mouseY * inverseScale, 0x00FFFFFF) } GlStateManager.scale(inverseScale, inverseScale, 1f) scrollScreen() diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt index eb9b49a78..b92375f10 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt @@ -1,7 +1,10 @@ package at.hannibal2.skyhanni.features.misc import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld +import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI +import at.hannibal2.skyhanni.features.misc.visualwords.VisualWordGui import at.hannibal2.skyhanni.utils.NEUItems import io.github.moulberry.moulconfig.gui.GuiScreenElementWrapper import net.minecraft.client.Minecraft @@ -20,6 +23,7 @@ object ChatPeek { if (Minecraft.getMinecraft().currentScreen is GuiScreenElementWrapper) return false if (NEUItems.neuHasFocus()) return false + if (GuiEditManager.isInGui() || FFGuideGUI.isInGui() || VisualWordGui.isInGui()) return false return key.isKeyHeld() } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/ModifyVisualWords.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/ModifyVisualWords.kt new file mode 100644 index 000000000..6b39b3885 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/ModifyVisualWords.kt @@ -0,0 +1,47 @@ +package at.hannibal2.skyhanni.features.misc.visualwords + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.StringUtils.convertToFormatted +import com.google.common.cache.Cache +import com.google.common.cache.CacheBuilder +import java.util.concurrent.TimeUnit + +object ModifyVisualWords { + private val config get() = SkyHanniMod.feature.gui.modifyWords + var textCache: Cache<String, String> = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build() + + var modifiedWords = mutableListOf<VisualWord>() + + fun modifyText(originalText: String?): String? { + var modifiedText = originalText ?: return null + if (!LorenzUtils.onHypixel) return originalText + if (!config.enabled) return originalText + if (!LorenzUtils.inSkyBlock && !config.workOutside) return originalText + if (VisualWordGui.isInGui()) return originalText + + if (modifiedWords.isEmpty()) { + modifiedWords = SkyHanniMod.feature.storage.modifiedWords + } + + val cachedResult = textCache.getIfPresent(originalText) + if (cachedResult != null) { + return cachedResult + } + + var replacements = 0 + + for (modifiedWord in modifiedWords) { + if (!modifiedWord.enabled) continue + val phrase = modifiedWord.phrase.convertToFormatted() + + if (phrase.isEmpty()) continue + + replacements += 1 + modifiedText = modifiedText.replace(phrase, modifiedWord.replacement.convertToFormatted()) + } + // if not many are done it is better to not cache it + if (replacements > 2) textCache.put(originalText, modifiedText) + return modifiedText + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWord.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWord.kt new file mode 100644 index 000000000..fa8e0fa97 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWord.kt @@ -0,0 +1,9 @@ +package at.hannibal2.skyhanni.features.misc.visualwords + +import com.google.gson.annotations.Expose + +data class VisualWord( + @Expose var phrase: String, + @Expose var replacement: String, + @Expose var enabled: Boolean + )
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt new file mode 100644 index 000000000..b3492663d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/visualwords/VisualWordGui.kt @@ -0,0 +1,408 @@ +package at.hannibal2.skyhanni.features.misc.visualwords + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.StringUtils.convertToFormatted +import kotlinx.coroutines.launch +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiScreen +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.init.Blocks +import net.minecraft.item.ItemStack +import net.minecraft.util.MathHelper +import org.lwjgl.input.Keyboard +import org.lwjgl.input.Mouse +import java.io.IOException + +open class VisualWordGui : GuiScreen() { + private var guiLeft = 0 + private var guiTop = 0 + private var screenHeight = 0 + private val sizeX = 360 + private val sizeY = 180 + private val maxTextLength = 75 + + private var mouseX = 0 + private var mouseY = 0 + private var lastMouseScroll = 0 + private var noMouseScrollFrames = 0 + + private var pageScroll = 0 + private var scrollVelocity = 0.0 + private val maxNoInputFrames = 100 + + private var lastClickedHeight = 0 + private var lastClickedWidth = 0 + private var changedIndex = -1 + private var changedAction = "" + + private var currentlyEditing = false + private var currentIndex = -1 + + private var currentTextBox = "" + private var currentText = "" + + private var modifiedWords = mutableListOf<VisualWord>() + + companion object { + fun isInGui() = Minecraft.getMinecraft().currentScreen is VisualWordGui + } + + override fun drawScreen(unusedX: Int, unusedY: Int, partialTicks: Float) { + super.drawScreen(unusedX, unusedY, partialTicks) + drawDefaultBackground() + screenHeight = height + guiLeft = (width - sizeX) / 2 + guiTop = (height - sizeY) / 2 + + mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth + mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1 + + GlStateManager.pushMatrix() + drawRect(guiLeft, guiTop, guiLeft + sizeX, guiTop + sizeY, 0x50000000) + val scale = 0.75f + val inverseScale = 1 / scale + + if (!currentlyEditing) { + val adjustedY = guiTop + 30 + pageScroll + var toRemove = -1 + + val x = guiLeft + 180 + val y = guiTop + 170 + + GuiRenderUtils.drawStringCentered("§aAdd New", x, y) + val colour = + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030 + drawRect(x - 30, y - 10, x + 30, y + 10, colour) + + GlStateManager.scale(scale, scale, 1f) + + GuiRenderUtils.drawStringCentered( + "§7Modify Words. Replaces the top with the bottom", + (guiLeft + 180) * inverseScale, + (guiTop + 9) * inverseScale + ) + GuiRenderUtils.drawString("§bPhrase", (guiLeft + 30) * inverseScale, (guiTop + 5) * inverseScale) + GuiRenderUtils.drawString("§1Status", (guiLeft + 310) * inverseScale, (guiTop + 5) * inverseScale) + + for ((index, phrase) in modifiedWords.withIndex()) { + if (adjustedY + 30 * index < guiTop + 20) continue + if (adjustedY + 30 * index > guiTop + 125) continue + + if (phrase.phrase == "" && phrase.replacement == "") { + toRemove = index + } + + var inBox = false + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, adjustedY + 30 * index, sizeX, 30)) inBox = true + + GuiRenderUtils.drawString("${index + 1}.", (guiLeft + 5) * inverseScale, (adjustedY + 10 + 30 * index) * inverseScale) + + if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft + 335, adjustedY + 30 * index + 7, 16, 16)) { + lastClickedWidth = 0 + lastClickedHeight = 0 + phrase.enabled = !phrase.enabled + saveChanges() + SoundUtils.playClickSound() + } else if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft + 295, + adjustedY + 30 * index + 7, 16, 16) && index != 0) { + lastClickedWidth = 0 + lastClickedHeight = 0 + SoundUtils.playClickSound() + changedIndex = index + changedAction = "up" + } else if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft + 315, + adjustedY + 30 * index + 7, 16, 16) && index != modifiedWords.size - 1) { + lastClickedWidth = 0 + lastClickedHeight = 0 + SoundUtils.playClickSound() + changedIndex = index + changedAction = "down" + } else if (GuiRenderUtils.isPointInRect(lastClickedWidth, lastClickedHeight, guiLeft, adjustedY + 30 * index, sizeX, 30)) { + lastClickedWidth = 0 + lastClickedHeight = 0 + SoundUtils.playClickSound() + currentlyEditing = true + currentIndex = index + } + + if (inBox) { + GuiRenderUtils.drawScaledRec(guiLeft, adjustedY + 30 * index, guiLeft + sizeX, adjustedY + 30 * index + 30, 0x50303030, inverseScale) + } + + val statusBlock = if (phrase.enabled) { + ItemStack(Blocks.stained_hardened_clay, 1, 13) + } else { + ItemStack(Blocks.stained_hardened_clay, 1, 14) + } + + GlStateManager.scale(inverseScale, inverseScale, 1f) + + if (index != 0) { + val skullItem = ItemUtils.createSkull("Up", "7f68dd73-1ff6-4193-b246-820975d6fab1", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzczMzRjZGRmYWI0NWQ3NWFkMjhlMWE0N2JmOGNmNTAxN2QyZjA5ODJmNjczN2RhMjJkNDk3Mjk1MjUxMDY2MSJ9fX0=") + GuiRenderUtils.renderItemAndBackground(skullItem, guiLeft + 295, adjustedY + 30 * index + 7, 0x50828282) + } + if (index != modifiedWords.size - 1) { + val skullItem = ItemUtils.createSkull("Down", "e4ace6de-0629-4719-aea3-3e113314dd3f", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTc3NDIwMzRmNTlkYjg5MGM4MDA0MTU2YjcyN2M3N2NhNjk1YzQzOTlkOGUwZGE1Y2U5MjI3Y2Y4MzZiYjhlMiJ9fX0=") + GuiRenderUtils.renderItemAndBackground(skullItem, guiLeft + 315, adjustedY + 30 * index + 7, 0x50828282) + } + + GuiRenderUtils.renderItemAndBackground(statusBlock, guiLeft + 335, adjustedY + 30 * index + 7, 0x50828282) + + GlStateManager.scale(scale, scale, 1f) + + if (inBox) { + GuiRenderUtils.drawString(phrase.phrase, (guiLeft + 15) * inverseScale, (adjustedY + 5 + 30 * index) * inverseScale) + GuiRenderUtils.drawString(phrase.replacement, (guiLeft + 15) * inverseScale, (adjustedY + 15 + 30 * index) * inverseScale) + } else { + GuiRenderUtils.drawString(phrase.phrase.convertToFormatted(), (guiLeft + 15) * inverseScale, (adjustedY + 5 + 30 * index) * inverseScale) + GuiRenderUtils.drawString(phrase.replacement.convertToFormatted(), (guiLeft + 15) * inverseScale, (adjustedY + 15 + 30 * index) * inverseScale) + } + } + + if (modifiedWords.size < 1) { + modifiedWords = SkyHanniMod.feature.storage.modifiedWords + } + + if (toRemove != -1) { + modifiedWords.removeAt(toRemove) + saveChanges() + } + + GlStateManager.scale(inverseScale, inverseScale, 1f) + + scrollScreen() + } + else { + val x = guiLeft + 180 + var y = guiTop + 140 + GuiRenderUtils.drawStringCentered("§cDelete", x, y) + var colour = if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030 + drawRect(x - 30, y - 10, x + 30, y + 10, colour) + y += 30 + GuiRenderUtils.drawStringCentered("§eBack", x, y) + colour = if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030 + drawRect(x - 30, y - 10, x + 30, y + 10, colour) + + if (currentIndex < modifiedWords.size && currentIndex != -1) { + y -= 150 + val currentPhrase = modifiedWords[currentIndex] + val status = if (currentPhrase.enabled) "§2Enabled" else "§4Disabled" + GuiRenderUtils.drawStringCentered(status, x, y) + colour = if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) 0x50828282 else 0x50303030 + drawRect(x - 30, y - 10, x + 30, y + 10, colour) + + GuiRenderUtils.drawString("§bIs replaced by:", guiLeft + 30, guiTop + 75) + + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 35, sizeX, 30)) { + drawRect(guiLeft, guiTop + 35, guiLeft + sizeX, guiTop + 35 + 30, 0x50303030) + } + if (currentTextBox == "phrase") { + drawRect(guiLeft, guiTop + 35, guiLeft + sizeX, guiTop + 35 + 30, 0x50828282) + } + + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 90, sizeX, 30)) { + drawRect(guiLeft, guiTop + 90, guiLeft + sizeX, guiTop + 90 + 30, 0x50303030) + } + if (currentTextBox == "replacement") { + drawRect(guiLeft, guiTop + 90, guiLeft + sizeX, guiTop + 90 + 30, 0x50828282) + } + + GlStateManager.scale(0.75f, 0.75f, 1f) + + GuiRenderUtils.drawTwoLineString("§bThe top line of each section is the preview of the bottom text", + (guiLeft + 10) * inverseScale, (guiTop + 17) * inverseScale) + GuiRenderUtils.drawTwoLineString("§bTo get the minecraft formatting sign use \"&&\"", + (guiLeft + 220) * inverseScale, (guiTop + 17) * inverseScale) + + GuiRenderUtils.drawString(currentPhrase.phrase.convertToFormatted(), (guiLeft + 30) * inverseScale, (guiTop + 40) * inverseScale) + GuiRenderUtils.drawString(currentPhrase.phrase, (guiLeft + 30) * inverseScale, (guiTop + 55) * inverseScale) + + GuiRenderUtils.drawString(currentPhrase.replacement.convertToFormatted(), (guiLeft + 30) * inverseScale, (guiTop + 95) * inverseScale) + GuiRenderUtils.drawString(currentPhrase.replacement, (guiLeft + 30) * inverseScale, (guiTop + 110) * inverseScale) + + GlStateManager.scale(inverseScale, inverseScale, 1f) + } + } + + if (changedIndex != -1) { + if (changedAction == "up") { + if (changedIndex > 0) { + val temp = modifiedWords[changedIndex] + modifiedWords[changedIndex] = modifiedWords[changedIndex - 1] + modifiedWords[changedIndex - 1] = temp + } + } + else if (changedAction == "down") { + if (changedIndex < modifiedWords.size - 1) { + val temp = modifiedWords[changedIndex] + modifiedWords[changedIndex] = modifiedWords[changedIndex + 1] + modifiedWords[changedIndex + 1] = temp + } + } + + changedIndex = -1 + changedAction = "" + saveChanges() + } + + GlStateManager.popMatrix() + } + + override fun handleMouseInput() { + super.handleMouseInput() + + if (Mouse.getEventButtonState()) { + mouseClickEvent() + } + if (!Mouse.getEventButtonState()) { + if (Mouse.getEventDWheel() != 0) { + lastMouseScroll = Mouse.getEventDWheel() + noMouseScrollFrames = 0 + } + } + } + + @Throws(IOException::class) + fun mouseClickEvent() { + if (!currentlyEditing) { + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop, sizeX, sizeY - 25)) { + lastClickedWidth = mouseX + lastClickedHeight = mouseY + } + } + val x = guiLeft + 180 + var y = guiTop + 140 + if (currentlyEditing) { + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) { + SoundUtils.playClickSound() + currentlyEditing = false + modifiedWords.removeAt(currentIndex) + currentIndex = -1 + saveChanges() + currentTextBox = "" + } + if (currentIndex < modifiedWords.size && currentIndex != -1) { + y = guiTop + 20 + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) { + SoundUtils.playClickSound() + modifiedWords[currentIndex].enabled = !modifiedWords[currentIndex].enabled + saveChanges() + } else if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 35, sizeX, 30)) { + SoundUtils.playClickSound() + currentTextBox = "phrase" + currentText = modifiedWords[currentIndex].phrase + } else if (GuiRenderUtils.isPointInRect(mouseX, mouseY, guiLeft, guiTop + 90, sizeX, 30)) { + SoundUtils.playClickSound() + currentTextBox = "replacement" + currentText = modifiedWords[currentIndex].replacement + } else { + if (currentTextBox != "") { + SoundUtils.playClickSound() + currentTextBox = "" + } + } + } + } + y = guiTop + 170 + if (GuiRenderUtils.isPointInRect(mouseX, mouseY, x - 30, y - 10, 60, 20)) { + SoundUtils.playClickSound() + if (currentlyEditing) { + currentIndex = -1 + currentTextBox = "" + } else { + modifiedWords.add(VisualWord("", "", true)) + currentTextBox = "phrase" + currentIndex = modifiedWords.size - 1 + saveChanges() + } + currentlyEditing = !currentlyEditing + } + } + + @Throws(IOException::class) + override fun keyTyped(typedChar: Char, keyCode: Int) { + super.keyTyped(typedChar, keyCode) + if (!currentlyEditing) return + if (currentTextBox == "") return + if (currentIndex >= modifiedWords.size || currentIndex == -1) return + + if (keyCode == Keyboard.KEY_ESCAPE) { + saveTextChanges() + currentTextBox = "" + return + } + + if (keyCode == Keyboard.KEY_BACK) { + if (currentText.isNotEmpty()) { + currentText = if (KeyboardManager.isControlKeyDown()) { + "" + } else if (KeyboardManager.isShiftKeyDown()) { + val lastSpaceIndex = currentText.lastIndexOf(' ') + if (lastSpaceIndex >= 0) { + currentText.substring(0, lastSpaceIndex) + } else { + "" + } + } else { + currentText.substring(0, currentText.length - 1) + } + saveTextChanges() + } + + return + } + + if (currentText.length < maxTextLength && !Character.isISOControl(typedChar)) { + currentText += typedChar + saveTextChanges() + return + } + + if (KeyboardManager.isPastingKeysDown()) { + SkyHanniMod.coroutineScope.launch { + val clipboard = OSUtils.readFromClipboard() ?: "" + for (char in clipboard) { + if (currentText.length < maxTextLength && !Character.isISOControl(char)) { + currentText += char + } + } + saveTextChanges() + } + } + } + + private fun saveTextChanges() { + if (currentTextBox == "phrase") { + modifiedWords[currentIndex].phrase = currentText + } else if (currentTextBox == "replacement") { + modifiedWords[currentIndex].replacement = currentText + } + saveChanges() + } + + private fun scrollScreen() { + scrollVelocity += lastMouseScroll / 48.0 + scrollVelocity *= 0.95 + pageScroll += scrollVelocity.toInt() + lastMouseScroll / 24 + + noMouseScrollFrames++ + + if (noMouseScrollFrames >= maxNoInputFrames) { + scrollVelocity *= 0.75 + } + + if (pageScroll > 0) { + pageScroll = 0 + } + + pageScroll = MathHelper.clamp_int(pageScroll, -(SkyHanniMod.feature.storage.modifiedWords.size * 30 - 100), 0) + lastMouseScroll = 0 + } + + private fun saveChanges() { + ModifyVisualWords.modifiedWords = modifiedWords + ModifyVisualWords.textCache.invalidateAll() + SkyHanniMod.feature.storage.modifiedWords = modifiedWords + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java index cf357eb74..7b6631ae4 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinFontRenderer.java @@ -1,12 +1,17 @@ package at.hannibal2.skyhanni.mixins.transformers; import at.hannibal2.skyhanni.SkyHanniMod; +import at.hannibal2.skyhanni.features.misc.visualwords.ModifyVisualWords; import at.hannibal2.skyhanni.mixins.hooks.FontRendererHook; import net.minecraft.client.gui.FontRenderer; import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -72,4 +77,14 @@ public abstract class MixinFontRenderer { public void insertEndOfString(String text, boolean shadow, CallbackInfo ci) { FontRendererHook.endChromaRendering(); } + + @ModifyVariable(method = "renderStringAtPos", at = @At("HEAD"), argsOnly = true) + private String renderStringAtPos(String text) { + return ModifyVisualWords.INSTANCE.modifyText(text); + } + + @ModifyVariable(method = "getStringWidth", at = @At("HEAD"), argsOnly = true) + private String getStringWidth(String text) { + return ModifyVisualWords.INSTANCE.modifyText(text); + } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt index e250511a5..1269ec005 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt @@ -1,6 +1,5 @@ package at.hannibal2.skyhanni.utils -import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI import net.minecraft.client.Minecraft import net.minecraft.client.gui.FontRenderer import net.minecraft.client.gui.GuiScreen @@ -13,7 +12,7 @@ import java.text.DecimalFormat import kotlin.math.roundToInt /** - * Taken from NotEnoughUpdates + * Some functions taken from NotEnoughUpdates */ object GuiRenderUtils { @@ -60,7 +59,6 @@ object GuiRenderUtils { Minecraft.getMinecraft().fontRendererObj.drawString(firstString, x, y - 5, 0xffffff, true) Minecraft.getMinecraft().fontRendererObj.drawString(secondString, x, y + 5, 0xffffff, true) - } fun drawStringCentered(str: String?, x: Int, y: Int) { @@ -74,6 +72,10 @@ object GuiRenderUtils { ) } + fun drawStringCentered(str: String?, x: Float, y: Float) { + drawStringCentered(str, x.toInt(), y.toInt()) + } + fun renderItemStack(item: ItemStack, x: Int, y: Int) { val itemRender = Minecraft.getMinecraft().renderItem RenderHelper.enableGUIStandardItemLighting() @@ -179,18 +181,19 @@ object GuiRenderUtils { ) } - fun renderItemAndTip(item: ItemStack?, x: Int, y: Int, mouseX: Int, mouseY: Int, color: Int = 0xFF43464B.toInt()) { + fun renderItemAndTip(list: MutableList<String>, item: ItemStack?, x: Int, y: Int, mouseX: Int, mouseY: Int, color: Int = 0xFF43464B.toInt()) { GuiScreen.drawRect(x, y, x + 16, y + 16, color) if (item != null) { renderItemStack(item, x, y) if (isPointInRect(mouseX, mouseY, x, y, 16, 16)) { val tt: List<String> = item.getTooltip(Minecraft.getMinecraft().thePlayer, false) - FFGuideGUI.tooltipToDisplay.addAll(tt) + list.addAll(tt) } } } fun renderItemAndTip( + list: MutableList<String>, item: ItemStack?, x: Float, y: Float, @@ -198,7 +201,7 @@ object GuiRenderUtils { mouseY: Float, color: Int = 0xFF43464B.toInt() ) { - renderItemAndTip(item, x.toInt(), y.toInt(), mouseX.toInt(), mouseY.toInt(), color) + renderItemAndTip(list, item, x.toInt(), y.toInt(), mouseX.toInt(), mouseY.toInt(), color) } // assuming 70% font size @@ -272,4 +275,14 @@ object GuiRenderUtils { val color = Color(this) return Color(color.red / 5, color.green / 5, color.blue / 5).rgb } + + fun drawScaledRec(left: Int, top: Int, right: Int, bottom: Int, colour: Int, inverseScale: Float) { + GuiScreen.drawRect((left * inverseScale).toInt(), (top * inverseScale).toInt(), + (right * inverseScale).toInt(), (bottom * inverseScale).toInt(), colour) + } + + fun renderItemAndBackground(item: ItemStack, x: Int, y: Int, colour: Int) { + renderItemStack(item, x, y) + GuiScreen.drawRect(x, y, x + 16, y + 16, colour) + } }
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt index e00aadf42..06e7108d9 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -13,6 +13,9 @@ import com.google.gson.JsonObject import net.minecraft.client.Minecraft import net.minecraft.init.Items import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.NBTTagList +import net.minecraft.nbt.NBTTagString import net.minecraftforge.common.util.Constants import java.util.LinkedList import kotlin.time.Duration.Companion.seconds @@ -146,6 +149,49 @@ object ItemUtils { return nbt.getCompoundTag("SkullOwner").getString("Id") } + // Taken from NEU + fun createSkull(displayName: String, uuid: String, value: String): ItemStack { + return createSkull(displayName, uuid, value, null) + } + + // Taken from NEU + fun createSkull(displayName: String, uuid: String, value: String, lore: Array<String>?): ItemStack { + val render = ItemStack(Items.skull, 1, 3) + val tag = NBTTagCompound() + val skullOwner = NBTTagCompound() + val properties = NBTTagCompound() + val textures = NBTTagList() + val textures0 = NBTTagCompound() + + skullOwner.setString("Id", uuid) + skullOwner.setString("Name", uuid) + textures0.setString("Value", value) + + textures.appendTag(textures0) + + addNameAndLore(tag, displayName, lore) + + properties.setTag("textures", textures) + skullOwner.setTag("Properties", properties) + tag.setTag("SkullOwner", skullOwner) + render.tagCompound = tag + return render + } + + // Taken from NEU + private fun addNameAndLore(tag: NBTTagCompound, displayName: String, lore: Array<String>?) { + val display = NBTTagCompound() + display.setString("Name", displayName) + if (lore != null) { + val tagLore = NBTTagList() + for (line in lore) { + tagLore.appendTag(NBTTagString(line)) + } + display.setTag("Lore", tagLore) + } + tag.setTag("display", display) + } + fun ItemStack.getItemRarityOrCommon() = getItemRarityOrNull() ?: LorenzRarity.COMMON fun ItemStack.getItemRarityOrNull(logError: Boolean = true): LorenzRarity? { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt index 58659daeb..2e0a57c53 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt @@ -220,4 +220,8 @@ object StringUtils { if (!matcher.matches()) return null return matcher.group("username") } + + fun String.convertToFormatted(): String { + return this.replace("&&", "§") + } }
\ No newline at end of file |