From 4987b64d3f863b96b43bca9fe4c4fa3812a9951c Mon Sep 17 00:00:00 2001 From: Empa <42304516+ItsEmpa@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:40:43 +0200 Subject: [PATCH 01/11] Custom Wardrobe Signed-off-by: Empa <42304516+ItsEmpa@users.noreply.github.com> Signed-off-by: J10a1n15 <45315647+j10a1n15@users.noreply.github.com> Co-authored-by: J10a1n15 <45315647+j10a1n15@users.noreply.github.com> --- .../features/inventory/InventoryConfig.java | 31 +- .../inventory/customwardrobe/ColorConfig.java | 44 ++ .../customwardrobe/CustomWardrobeConfig.java | 54 ++ .../customwardrobe/SpacingConfig.java | 145 +++++ .../storage/ProfileSpecificStorage.java | 16 +- .../inventory/wardrobe/CustomWardrobe.kt | 578 ++++++++++++++++++ .../wardrobe/EstimatedWardrobePrice.kt | 39 ++ .../inventory/wardrobe/WardrobeAPI.kt | 253 ++++++++ .../misc/items/EstimatedWardrobePrice.kt | 74 --- .../skyhanni/mixins/hooks/GuiContainerHook.kt | 5 +- .../gui/AccessorGuiContainer.java | 6 + .../hannibal2/skyhanni/utils/EntityUtils.kt | 24 + .../skyhanni/utils/InventoryUtils.kt | 8 + .../at/hannibal2/skyhanni/utils/ItemUtils.kt | 7 + .../hannibal2/skyhanni/utils/RenderUtils.kt | 17 +- .../skyhanni/utils/renderables/Renderable.kt | 116 +++- .../utils/renderables/RenderableUtils.kt | 9 +- 17 files changed, 1324 insertions(+), 102 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/ColorConfig.java create mode 100644 src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/CustomWardrobeConfig.java create mode 100644 src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/SpacingConfig.java create mode 100644 src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java index 05f70105900c..990e555d2706 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java @@ -3,6 +3,7 @@ import at.hannibal2.skyhanni.config.FeatureToggle; import at.hannibal2.skyhanni.config.HasLegacyId; import at.hannibal2.skyhanni.config.features.inventory.chocolatefactory.ChocolateFactoryConfig; +import at.hannibal2.skyhanni.config.features.inventory.customwardrobe.CustomWardrobeConfig; import at.hannibal2.skyhanni.config.features.inventory.helper.HelperConfig; import at.hannibal2.skyhanni.config.features.itemability.ItemAbilityConfig; import at.hannibal2.skyhanni.config.features.misc.EstimatedItemValueConfig; @@ -49,6 +50,10 @@ public class InventoryConfig { @Category(name = "Item Abilities", desc = "Stuff about item abilities.") public ItemAbilityConfig itemAbilities = new ItemAbilityConfig(); + @Expose + @Category(name = "Custom Wardrobe", desc = "New Wardrobe Look.") + public CustomWardrobeConfig customWardrobe = new CustomWardrobeConfig(); + @Expose @Category(name = "Chocolate Factory", desc = "Features to help you master the Chocolate Factory idle game.") public ChocolateFactoryConfig chocolateFactory = new ChocolateFactoryConfig(); @@ -93,23 +98,19 @@ public class InventoryConfig { @Accordion public GetFromSackConfig gfs = new GetFromSackConfig(); + @Expose @ConfigOption(name = "Pocket Sack-In-A-Sack", desc = "") @Accordion - @Expose public PocketSackInASackConfig pocketSackInASack = new PocketSackInASackConfig(); @Expose - @ConfigOption( - name = "Item Number", - desc = "Showing the item number as a stack size for these items." - ) + @ConfigOption(name = "Item Number", desc = "Showing the item number as a stack size for these items.") @ConfigEditorDraggableList public List itemNumberAsStackSize = new ArrayList<>(Arrays.asList( NEW_YEAR_CAKE, RANCHERS_BOOTS_SPEED, LARVA_HOOK, - VACUUM_GARDEN - )); + VACUUM_GARDEN)); public enum ItemNumberEntry implements HasLegacyId { MASTER_STAR_TIER("§bMaster Star Tier", 0), @@ -168,11 +169,8 @@ public String toString() { public boolean vacuumBagCap = true; @Expose - @ConfigOption( - name = "Quick Craft Confirmation", - desc = "Require Ctrl+Click to craft items that aren't often quick crafted " + - "(e.g. armor, weapons, accessories). Sack items can be crafted normally." - ) + @ConfigOption(name = "Quick Craft Confirmation", desc = "Require Ctrl+Click to craft items that aren't often quick crafted " + + "(e.g. armor, weapons, accessories). Sack items can be crafted normally.") @ConfigEditorBoolean @FeatureToggle public boolean quickCraftingConfirmation = false; @@ -190,23 +188,20 @@ public String toString() { public boolean anvilCombineHelper = false; @Expose - @ConfigOption(name = "Item Stars", - desc = "Show a compact star count in the item name for all items.") + @ConfigOption(name = "Item Stars", desc = "Show a compact star count in the item name for all items.") @ConfigEditorBoolean @FeatureToggle public boolean itemStars = false; @Expose - @ConfigOption(name = "Missing Tasks", - desc = "Highlight missing tasks in the SkyBlock Level Guide inventory.") + @ConfigOption(name = "Missing Tasks", desc = "Highlight missing tasks in the SkyBlock Level Guide inventory.") // TODO move( , "inventory.highlightMissingSkyBlockLevelGuide", "inventory.skyblockGuideConfig.highlightMissingSkyBlockLevelGuide") @ConfigEditorBoolean @FeatureToggle public boolean highlightMissingSkyBlockLevelGuide = true; @Expose - @ConfigOption(name = "Power Stone Guide", - desc = "Highlight missing power stones, show their total bazaar price, and allows to open the bazaar when clicking on the items in the Power Stone Guide.") + @ConfigOption(name = "Power Stone Guide", desc = "Highlight missing power stones, show their total bazaar price, and allows to open the bazaar when clicking on the items in the Power Stone Guide.") // TODO move( , "inventory.powerStoneGuide", "inventory.skyblockGuideConfig.powerStoneGuide") @ConfigEditorBoolean @FeatureToggle diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/ColorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/ColorConfig.java new file mode 100644 index 000000000000..20f9282542b3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/ColorConfig.java @@ -0,0 +1,44 @@ +package at.hannibal2.skyhanni.config.features.inventory.customwardrobe; + +import com.google.gson.annotations.Expose; +import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorColour; +import io.github.notenoughupdates.moulconfig.annotations.ConfigOption; + +public class ColorConfig { + + @Expose + @ConfigOption(name = "Background", desc = "Color of the GUI background.") + @ConfigEditorColour + public String backgroundColor = "0:127:0:0:0"; + + @Expose + @ConfigOption(name = "Equipped", desc = "Color of the currently equipped wardrobe slot.") + @ConfigEditorColour + public String equippedColor = "0:127:85:255:85"; + + @Expose + @ConfigOption(name = "Favorite", desc = "Color of the wardrobe slots that have been added as favorites.") + @ConfigEditorColour + public String favoriteColor = "0:127:255:85:85"; + + @Expose + @ConfigOption(name = "Same Page", desc = "Color of wardrobe slots in the same page.") + @ConfigEditorColour + public String samePageColor = "0:127:94:108:255"; + + @Expose + @ConfigOption(name = "Other Page", desc = "Color of wardrobe slots in another page.") + @ConfigEditorColour + public String otherPageColor = "0:127:0:0:0"; + + @Expose + @ConfigOption(name = "Top Outline", desc = "Color of the top of the outline when hovered.") + @ConfigEditorColour + public String topBorderColor = "0:255:255:200:0"; + + @Expose + @ConfigOption(name = "Bottom Outline", desc = "Color of the bottom of the outline when hovered.") + @ConfigEditorColour + public String bottomBorderColor = "0:255:255:0:0"; + +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/CustomWardrobeConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/CustomWardrobeConfig.java new file mode 100644 index 000000000000..a4ea69badb20 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/CustomWardrobeConfig.java @@ -0,0 +1,54 @@ +package at.hannibal2.skyhanni.config.features.inventory.customwardrobe; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import com.google.gson.annotations.Expose; +import io.github.notenoughupdates.moulconfig.annotations.Accordion; +import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean; +import io.github.notenoughupdates.moulconfig.annotations.ConfigOption; + +public class CustomWardrobeConfig { + + @Expose + @ConfigOption(name = "Enable", desc = "Enables the Custom Wardrobe GUI.") + @ConfigEditorBoolean + @FeatureToggle + public boolean enabled = true; + + @Expose + @ConfigOption(name = "Follow mouse", desc = "Players follow the movement of the mouse.") + @ConfigEditorBoolean + public boolean eyesFollowMouse = true; + + @Expose + @ConfigOption(name = "Hide Empty Slots", desc = "Hides wardrobe slots with no armor.") + @ConfigEditorBoolean + public boolean hideEmptySlots = false; + + @Expose + @ConfigOption(name = "Hide Locked Slots", desc = "Hides locked wardrobe slots.") + @ConfigEditorBoolean + public boolean hideLockedSlots = false; + + @Expose + public boolean onlyFavorites = false; + + @Expose + @ConfigOption(name = "Estimated Value", desc = "Show a §2$ §7sign you can hover to see the wardrobe slot value.") + @ConfigEditorBoolean + public boolean estimatedValue = true; + + @Expose + @ConfigOption(name = "Loading text", desc = "Shows a \"§cLoading...\" §7text when the wardrobe page hasn't fully loaded in yet.") + @ConfigEditorBoolean + public boolean loadingText = true; + + @Expose + @ConfigOption(name = "Colors", desc = "Change the color settings.") + @Accordion + public ColorConfig color = new ColorConfig(); + + @Expose + @ConfigOption(name = "Spacing", desc = "") + @Accordion + public SpacingConfig spacing = new SpacingConfig(); +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/SpacingConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/SpacingConfig.java new file mode 100644 index 000000000000..363a9a6a70bf --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/customwardrobe/SpacingConfig.java @@ -0,0 +1,145 @@ +package at.hannibal2.skyhanni.config.features.inventory.customwardrobe; + +import com.google.gson.annotations.Expose; +import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorSlider; +import io.github.notenoughupdates.moulconfig.annotations.ConfigOption; +import io.github.notenoughupdates.moulconfig.observer.Property; + +public class SpacingConfig { + + @Expose + @ConfigOption(name = "Global Scale", desc = "Controls the scale of the entirety of the wardrobe.") + @ConfigEditorSlider( + minValue = 30, + maxValue = 200, + minStep = 1 + ) + public Property globalScale = Property.of(100); + + @Expose + @ConfigOption(name = "Outline Thickness", desc = "How thick the outline of the hovered slot is.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 15, + minStep = 1 + ) + public Property outlineThickness = Property.of(5); + + @Expose + @ConfigOption(name = "Outline Blur", desc = "Amount of blur of the outline.") + @ConfigEditorSlider( + minValue = 0f, + maxValue = 1f, + minStep = 0.1f + ) + public Property outlineBlur = Property.of(0.5f); + + @Expose + @ConfigOption(name = "Slot Width", desc = "Width of the wardrobe slots.") + @ConfigEditorSlider( + minValue = 30, + maxValue = 100, + minStep = 1 + ) + public Property slotWidth = Property.of(75); + + @Expose + @ConfigOption(name = "Slot Height", desc = "Height of the wardrobe slots.") + @ConfigEditorSlider( + minValue = 60, + maxValue = 200, + minStep = 1 + ) + public Property slotHeight = Property.of(140); + + @Expose + @ConfigOption(name = "Player Scale", desc = "Scale of the players.") + @ConfigEditorSlider( + minValue = 0, + maxValue = 100, + minStep = 1 + ) + public Property playerScale = Property.of(75); + + @Expose + @ConfigOption(name = "Slots per Row", desc = "Max amount of wardrobe slots per row.") + @ConfigEditorSlider( + minValue = 5, + maxValue = 18, + minStep = 1 + ) + public Property maxPlayersPerRow = Property.of(9); + + @Expose + @ConfigOption(name = "Slots Horizontal Spacing", desc = "How much space horizontally between wardrobe slots.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public Property horizontalSpacing = Property.of(3); + + @Expose + @ConfigOption(name = "Slots Vertical Spacing", desc = "How much space vertically between wardrobe slots.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public Property verticalSpacing = Property.of(3); + + @Expose + @ConfigOption(name = "Slots & Buttons Spacing", desc = "How much vertical space there is between wardrobe slots and the buttons.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 40, + minStep = 1 + ) + public Property buttonSlotsVerticalSpacing = Property.of(10); + + @Expose + @ConfigOption(name = "Button Horizontal Spacing", desc = "How much space horizontally between buttons.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 40, + minStep = 1 + ) + public Property buttonHorizontalSpacing = Property.of(10); + + @Expose + @ConfigOption(name = "Button Vertical Spacing", desc = "How much space vertically between buttons.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 40, + minStep = 1 + ) + public Property buttonVerticalSpacing = Property.of(10); + + @Expose + @ConfigOption(name = "Button Width", desc = "Width of the buttons.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 60, + minStep = 1 + ) + public Property buttonWidth = Property.of(50); + + @Expose + @ConfigOption(name = "Button Height", desc = "Height of the buttons.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 60, + minStep = 1 + ) + public Property buttonHeight = Property.of(20); + + @Expose + @ConfigOption(name = "Background Padding", desc = "Space between the edges of the background and the slots.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public Property backgroundPadding = Property.of(10); + +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java index bc25da446e3e..0fce526a5e47 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java @@ -28,6 +28,7 @@ import at.hannibal2.skyhanni.features.garden.pests.PestProfitTracker; import at.hannibal2.skyhanni.features.garden.pests.VinylType; import at.hannibal2.skyhanni.features.garden.visitor.VisitorReward; +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI; import at.hannibal2.skyhanni.features.mining.fossilexcavator.ExcavatorProfitTracker; import at.hannibal2.skyhanni.features.mining.powdertracker.PowderTracker; import at.hannibal2.skyhanni.features.misc.trevor.TrevorTracker; @@ -609,13 +610,26 @@ public static class DianaStorage { public DianaProfitTracker.Data dianaProfitTracker = new DianaProfitTracker.Data(); @Expose - // TODO renmae + // TODO rename public MythologicalCreatureTracker.Data mythologicalMobTracker = new MythologicalCreatureTracker.Data(); } @Expose public Map skillData = new HashMap<>(); + @Expose + public WardrobeStorage wardrobe = new WardrobeStorage(); + + public static class WardrobeStorage { + @Expose + public Map wardrobeData = new HashMap<>(); + + @Expose + @Nullable + public Integer currentWardrobeSlot = null; + } + + @Expose public UpgradeReminder.CommunityShopUpgrade communityShopProfileUpgrade = null; } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt new file mode 100644 index 000000000000..03004a7f7e83 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -0,0 +1,578 @@ +package at.hannibal2.skyhanni.features.inventory.wardrobe + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.core.config.Position +import at.hannibal2.skyhanni.events.ConfigLoadEvent +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryUpdatedEvent +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.MAX_PAGES +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.MAX_SLOT_PER_PAGE +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.createWardrobePriceLore +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.currentPage +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.currentWardrobeSlot +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.inCustomWardrobe +import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.inWardrobe +import at.hannibal2.skyhanni.mixins.transformers.gui.AccessorGuiContainer +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.ColorUtils.addAlpha +import at.hannibal2.skyhanni.utils.ColorUtils.darker +import at.hannibal2.skyhanni.utils.ColorUtils.toChromaColor +import at.hannibal2.skyhanni.utils.ColorUtils.toChromaColorInt +import at.hannibal2.skyhanni.utils.ColorUtils.withAlpha +import at.hannibal2.skyhanni.utils.ConditionalUtils +import at.hannibal2.skyhanni.utils.ConditionalUtils.transformIf +import at.hannibal2.skyhanni.utils.ConfigUtils.jumpToEditor +import at.hannibal2.skyhanni.utils.DelayedRun +import at.hannibal2.skyhanni.utils.EntityUtils.getFakePlayer +import at.hannibal2.skyhanni.utils.InventoryUtils.clickSlot +import at.hannibal2.skyhanni.utils.InventoryUtils.getWindowId +import at.hannibal2.skyhanni.utils.ItemUtils.removeEnchants +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment +import at.hannibal2.skyhanni.utils.RenderUtils.VerticalAlignment +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderable +import at.hannibal2.skyhanni.utils.renderables.Renderable +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiContainer +import net.minecraft.client.renderer.GlStateManager +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.awt.Color +import kotlin.math.min +import kotlin.time.Duration.Companion.milliseconds + +@SkyHanniModule +object CustomWardrobe { + + private val config get() = SkyHanniMod.feature.inventory.customWardrobe + + private var displayRenderable: Renderable? = null + private var inventoryButton: Renderable? = null + private var editMode = false + private var waitingForInventoryUpdate = false + + private var activeScale: Int = 100 + private var currentMaxSize: Pair? = null + private var lastScreenSize: Pair? = null + private var guiName = "Custom Wardrobe" + + @SubscribeEvent + fun onGuiRender(event: GuiContainerEvent.BeforeDraw) { + if (!isEnabled() || editMode) return + val gui = event.gui + val renderable = displayRenderable ?: run { + update() + displayRenderable ?: return + } + + val screenSize = gui.width to gui.height + + if (screenSize != lastScreenSize) { + lastScreenSize = screenSize + val didUpdate = updateScreenSize(screenSize) + if (didUpdate) return + } + + val (width, height) = renderable.width to renderable.height + val pos = Position((gui.width - width) / 2, (gui.height - height) / 2) + if (waitingForInventoryUpdate && config.loadingText) { + val loadingRenderable = Renderable.string( + "§cLoading...", + scale = activeScale / 100.0 + ) + val loadingPos = + Position(pos.rawX + (width - loadingRenderable.width) / 2, pos.rawY - loadingRenderable.height) + loadingPos.renderRenderable(loadingRenderable, posLabel = guiName, addToGuiManager = false) + } + + GlStateManager.translate(0f, 0f, 100f) + pos.renderRenderable(renderable, posLabel = guiName, addToGuiManager = false) + GlStateManager.translate(0f, 0f, -100f) + event.cancel() + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) { + if (!isEnabled()) return + if (!editMode) return + val gui = Minecraft.getMinecraft().currentScreen as? GuiContainer ?: return + val renderable = inventoryButton ?: addReEnableButton().also { inventoryButton = it } + val accessorGui = gui as AccessorGuiContainer + val posX = accessorGui.guiLeft + (1.05 * accessorGui.width).toInt() + val posY = accessorGui.guiTop + (accessorGui.height - renderable.height) / 2 + Position(posX, posY).renderRenderable(renderable, posLabel = guiName, addToGuiManager = false) + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + waitingForInventoryUpdate = false + DelayedRun.runDelayed(500.milliseconds) { + if (!inWardrobe()) { + reset() + } + } + } + + @SubscribeEvent + fun onConfigUpdate(event: ConfigLoadEvent) { + with(config.spacing) { + ConditionalUtils.onToggle( + globalScale, outlineThickness, outlineBlur, + slotWidth, slotHeight, playerScale, + maxPlayersPerRow, horizontalSpacing, verticalSpacing, + buttonSlotsVerticalSpacing, buttonHorizontalSpacing, buttonVerticalSpacing, + buttonWidth, buttonHeight, backgroundPadding, + ) { + currentMaxSize = null + lastScreenSize = null + } + } + } + + @SubscribeEvent + fun onInventoryUpdate(event: InventoryUpdatedEvent) { + if (!isEnabled() || editMode) return + update() + } + + private fun update() { + displayRenderable = createRenderables() + } + + private fun updateScreenSize(gui: Pair): Boolean { + val renderable = currentMaxSize ?: run { + activeScale = config.spacing.globalScale.get() + update() + return true + } + val previousActiveScale = activeScale + val unscaledRenderableWidth = 100 * (renderable.first / activeScale.toDouble()) + val unscaledRenderableHeight = 100 * (renderable.second / activeScale.toDouble()) + val autoScaleWidth = 100 * ((gui.first * 0.9) / unscaledRenderableWidth) + val autoScaleHeight = 10_000 * ((gui.second * 0.9) / unscaledRenderableHeight) + val maxScale = min(autoScaleWidth, autoScaleHeight).toInt() + + activeScale = config.spacing.globalScale.get().coerceAtMost(maxScale) + return if (activeScale != previousActiveScale) { + update() + true + } else false + } + + private fun createRenderables(): Renderable { + var list = WardrobeAPI.wardrobeSlots + var wardrobeWarning: String? = null + + if (list.isEmpty()) wardrobeWarning = "§cYour wardrobe is empty :(" + + if (config.hideLockedSlots) { + list = list.filter { !it.locked } + if (list.isEmpty()) wardrobeWarning = "§cAll your slots are locked? Somehow" + } + + if (config.hideEmptySlots) { + list = list.filter { !it.isEmpty() } + if (list.isEmpty()) wardrobeWarning = "§cAll slots are empty :(" + } + if (config.onlyFavorites) { + list = list.filter { it.favorite || it.isCurrentSlot() } + if (list.isEmpty()) wardrobeWarning = "§cDidn't set any favorites" + } + + val maxPlayersPerRow = config.spacing.maxPlayersPerRow.get() + val maxPlayersRows = ((MAX_SLOT_PER_PAGE * MAX_PAGES - 1) / maxPlayersPerRow) + 1 + val containerWidth = (config.spacing.slotWidth.get() * (activeScale / 100.0)).toInt() + val containerHeight = (config.spacing.slotHeight.get() * (activeScale / 100.0)).toInt() + val playerWidth = (containerWidth * (config.spacing.playerScale.get() / 100.0)) + val horizontalSpacing = (config.spacing.horizontalSpacing.get() * (activeScale / 100.0)).toInt() + val verticalSpacing = (config.spacing.verticalSpacing.get() * (activeScale / 100.0)).toInt() + val backgroundPadding = (config.spacing.backgroundPadding.get() * (activeScale / 100.0)).toInt() + val buttonVerticalSpacing = (config.spacing.buttonVerticalSpacing.get() * (activeScale / 100.0)).toInt() + + var maxRenderableWidth = maxPlayersPerRow * containerWidth + (maxPlayersPerRow - 1) * horizontalSpacing + var maxRenderableHeight = maxPlayersRows * containerHeight + (maxPlayersRows - 1) * verticalSpacing + + val button = addButtons() + + if (button.width > maxRenderableWidth) maxRenderableWidth = button.width + maxRenderableHeight += button.height + buttonVerticalSpacing + + maxRenderableWidth += 2 * backgroundPadding + maxRenderableHeight += 2 * backgroundPadding + currentMaxSize = maxRenderableWidth to maxRenderableHeight + + wardrobeWarning?.let { text -> + val warningRenderable = Renderable.string( + text, + 3.0 * (activeScale / 100.0), + horizontalAlign = HorizontalAlignment.CENTER + ) + val withButtons = Renderable.verticalContainer( + listOf(warningRenderable, button), + buttonVerticalSpacing, + horizontalAlign = HorizontalAlignment.CENTER + ) + return addGuiBackground(withButtons, backgroundPadding) + } + + val chunkedList = list.chunked(maxPlayersPerRow) + + val rowsRenderables = chunkedList.map { row -> + val slotsRenderables = row.map { slot -> + var scale = playerWidth + val armorTooltipRenderable = { + val loreList = mutableListOf() + val height = containerHeight - 3 + + // This is needed to keep the background size the same as the player renderable size + val hoverableSizes = MutableList(4) { height / 4 }.apply { + for (k in 0 until height % 4) this[k]++ + } + + for (armorIndex in 0 until 4) { + val stack = slot.armor[armorIndex]?.copy() + if (stack == null) { + loreList.add(Renderable.placeholder(containerWidth, hoverableSizes[armorIndex])) + } else { + loreList.add( + Renderable.hoverable( + Renderable.hoverTips( + Renderable.placeholder(containerWidth, hoverableSizes[armorIndex]), + stack.getTooltip(Minecraft.getMinecraft().thePlayer, false) + ), + Renderable.placeholder(containerWidth, hoverableSizes[armorIndex]), + bypassChecks = true + ) + ) + } + } + Renderable.verticalContainer(loreList, spacing = 1) + } + + val playerBackground = createHoverableRenderable( + armorTooltipRenderable.invoke(), + topLayerRenderable = addSlotHoverableButtons(slot), + hoveredColor = slot.getSlotColor(), + borderOutlineThickness = config.spacing.outlineThickness.get(), + borderOutlineBlur = config.spacing.outlineBlur.get(), + onClick = { slot.clickSlot() } + ) + + val fakePlayer = getFakePlayer() + + fakePlayer.inventory.armorInventory = + slot.armor.map { it?.copy()?.removeEnchants() }.reversed().toTypedArray() + + val playerColor = if (!slot.isInCurrentPage()) { + scale *= 0.9 + Color.GRAY.withAlpha(100) + } else null + + val playerRenderable = Renderable.fakePlayer( + fakePlayer, + followMouse = config.eyesFollowMouse, + width = containerWidth, + height = containerHeight, + entityScale = scale.toInt(), + padding = 0, + color = playerColor, + ) + + Renderable.doubleLayered(playerBackground, playerRenderable, false) + } + Renderable.horizontalContainer(slotsRenderables, horizontalSpacing) + } + + val allSlotsRenderable = Renderable.verticalContainer( + rowsRenderables, + verticalSpacing, + horizontalAlign = HorizontalAlignment.CENTER + ) + + val withButtons = Renderable.verticalContainer( + listOf(allSlotsRenderable, button), + buttonVerticalSpacing, + horizontalAlign = HorizontalAlignment.CENTER + ) + + return addGuiBackground(withButtons, backgroundPadding) + } + + private fun addGuiBackground(renderable: Renderable, borderPadding: Int) = + Renderable.drawInsideRoundedRect( + Renderable.doubleLayered( + renderable, + Renderable.clickable( + Renderable.string( + "§7SkyHanni", + horizontalAlign = HorizontalAlignment.RIGHT, + verticalAlign = VerticalAlignment.BOTTOM, + scale = 1.0 * (activeScale / 100.0) + ).let { Renderable.hoverable(hovered = Renderable.underlined(it), unhovered = it) }, + onClick = { + config::enabled.jumpToEditor() + reset() + currentPage = null + } + ), + blockBottomHover = false + ), + config.color.backgroundColor.toChromaColor(), + padding = borderPadding + ) + + private fun reset() { + inCustomWardrobe = false + editMode = false + displayRenderable = null + inventoryButton = null + } + + private fun addButtons(): Renderable { + val (horizontalSpacing, verticalSpacing) = with(config.spacing) { + buttonHorizontalSpacing.get() * (activeScale / 100.0) to buttonVerticalSpacing.get() * (activeScale / 100.0) + } + + val backButton = createLabeledButton( + "§aBack", + onClick = { + clickSlot(48, getWindowId() ?: -1) + reset() + currentPage = null + } + ) + val exitButton = createLabeledButton( + "§cClose", + onClick = { + clickSlot(49, getWindowId() ?: -1) + reset() + currentPage = null + } + ) + + val greenColor = Color(85, 255, 85, 200) + val redColor = Color(255, 85, 85, 200) + + val onlyFavoriteButton = createLabeledButton( + "§eFavorite", + hoveredColor = if (config.onlyFavorites) greenColor else redColor, + onClick = { + config.onlyFavorites = !config.onlyFavorites + update() + } + ) + + val editButton = createLabeledButton( + "§bEdit", + onClick = { + DelayedRun.runNextTick { + reset() + editMode = true + } + } + ) + + val row = Renderable.horizontalContainer( + listOf(backButton, exitButton, onlyFavoriteButton), + horizontalSpacing.toInt(), + horizontalAlign = HorizontalAlignment.CENTER, + ) + + val total = Renderable.verticalContainer( + listOf(row, editButton), + verticalSpacing.toInt(), + horizontalAlign = HorizontalAlignment.CENTER, + verticalAlign = VerticalAlignment.CENTER + ) + + return total + } + + private fun addReEnableButton(): Renderable { + val color = Color(116, 150, 255, 200) + return createLabeledButton( + "§bEdit", + hoveredColor = color, + unhoveredColor = color.darker(0.8), + onClick = { + inCustomWardrobe = false + editMode = false + update() + } + ) + } + + private fun addSlotHoverableButtons(wardrobeSlot: WardrobeAPI.WardrobeSlot): Renderable { + val list = mutableListOf() + val textScale = 1.5 * (activeScale / 100.0) + list.add( + Renderable.clickable( + Renderable.hoverable( + Renderable.string( + (if (wardrobeSlot.favorite) "§c" else "§7") + "❤", + scale = textScale, + horizontalAlign = HorizontalAlignment.CENTER, + verticalAlign = VerticalAlignment.CENTER + ), + Renderable.string( + (if (wardrobeSlot.favorite) "§4" else "§8") + "❤", + scale = textScale, + horizontalAlign = HorizontalAlignment.CENTER, + verticalAlign = VerticalAlignment.CENTER + ) + ), + onClick = { + wardrobeSlot.favorite = !wardrobeSlot.favorite + update() + } + ) + ) + + if (config.estimatedValue && !wardrobeSlot.isEmpty()) { + val lore = createWardrobePriceLore(wardrobeSlot) + list.add( + Renderable.hoverTips( + Renderable.string( + "§2$", + scale = textScale, + horizontalAlign = HorizontalAlignment.CENTER, + verticalAlign = VerticalAlignment.CENTER + ), lore + ) + ) + } + + return Renderable.verticalContainer(list, 1, HorizontalAlignment.RIGHT) + } + + private fun createLabeledButton( + text: String, + hoveredColor: Color = Color(130, 130, 130, 200), + unhoveredColor: Color = hoveredColor.darker(0.57), + onClick: () -> Unit + ): Renderable { + val buttonWidth = (config.spacing.buttonWidth.get() * (activeScale / 100.0)).toInt() + val buttonHeight = (config.spacing.buttonHeight.get() * (activeScale / 100.0)).toInt() + val textScale = (activeScale / 100.0) + + val renderable = Renderable.hoverable( + Renderable.drawInsideRoundedRectWithOutline( + Renderable.doubleLayered( + Renderable.clickable( + Renderable.placeholder(buttonWidth, buttonHeight), + onClick + ), + Renderable.string( + text, + horizontalAlign = HorizontalAlignment.CENTER, + verticalAlign = VerticalAlignment.CENTER, + scale = textScale + ), + false, + ), + hoveredColor, + padding = 0, + topOutlineColor = config.color.topBorderColor.toChromaColorInt(), + bottomOutlineColor = config.color.bottomBorderColor.toChromaColorInt(), + borderOutlineThickness = 2, + horizontalAlign = HorizontalAlignment.CENTER + ), + Renderable.drawInsideRoundedRect( + Renderable.doubleLayered( + Renderable.placeholder(buttonWidth, buttonHeight), + Renderable.string( + text, + horizontalAlign = HorizontalAlignment.CENTER, + verticalAlign = VerticalAlignment.CENTER, + scale = textScale + ), + ), + unhoveredColor.darker(0.57), + padding = 0, + horizontalAlign = HorizontalAlignment.CENTER + ) + ) + + return renderable + } + + private fun createHoverableRenderable( + hoveredRenderable: Renderable, + unhoveredRenderable: Renderable = Renderable.placeholder(hoveredRenderable.width, hoveredRenderable.height), + topLayerRenderable: Renderable = Renderable.placeholder(0, 0), + padding: Int = 0, + horizontalAlignment: HorizontalAlignment = HorizontalAlignment.CENTER, + verticalAlignment: VerticalAlignment = VerticalAlignment.CENTER, + hoveredColor: Color, + unHoveredColor: Color = hoveredColor, + borderOutlineThickness: Int, + borderOutlineBlur: Float = 0.5f, + onClick: () -> Unit, + onHover: () -> Unit = {}, + ): Renderable = + Renderable.hoverable( + Renderable.drawInsideRoundedRectWithOutline( + Renderable.doubleLayered( + Renderable.clickable( + hoveredRenderable, + onClick + ), topLayerRenderable + ), + hoveredColor, + padding = padding, + topOutlineColor = config.color.topBorderColor.toChromaColorInt(), + bottomOutlineColor = config.color.bottomBorderColor.toChromaColorInt(), + borderOutlineThickness = borderOutlineThickness, + blur = borderOutlineBlur, + horizontalAlign = horizontalAlignment, + verticalAlign = verticalAlignment + ), + Renderable.drawInsideRoundedRect( + unhoveredRenderable, + unHoveredColor, + padding = padding, + horizontalAlign = horizontalAlignment, + verticalAlign = verticalAlignment + ), + onHover = { onHover() } + ) + + private fun WardrobeAPI.WardrobeSlot.clickSlot() { + val previousPageSlot = 45 + val nextPageSlot = 53 + val wardrobePage = currentPage ?: return + val windowId = getWindowId() ?: -1 + if (isInCurrentPage()) { + if (isEmpty() || locked || waitingForInventoryUpdate) return + currentWardrobeSlot = if (isCurrentSlot()) null + else id + clickSlot(inventorySlot, windowId) + } else { + if (page < wardrobePage) { + currentPage = wardrobePage - 1 + waitingForInventoryUpdate = true + clickSlot(previousPageSlot, windowId) + } else if (page > wardrobePage) { + currentPage = wardrobePage + 1 + waitingForInventoryUpdate = true + clickSlot(nextPageSlot, windowId) + } + } + update() + } + + private fun WardrobeAPI.WardrobeSlot.getSlotColor() = + with(config.color) { + when { + isCurrentSlot() -> equippedColor + favorite -> favoriteColor + else -> null + }?.toChromaColor()?.transformIf({ isInCurrentPage() }) { darker() } + ?: (if (!isInCurrentPage()) samePageColor else otherPageColor).toChromaColor() + .transformIf({ locked || isEmpty() }) { darker() }.addAlpha(100) + + } + + fun isEnabled() = LorenzUtils.inSkyBlock && inWardrobe() && config.enabled +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt new file mode 100644 index 000000000000..7c2610c83ce4 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt @@ -0,0 +1,39 @@ +package at.hannibal2.skyhanni.features.inventory.wardrobe + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator +import at.hannibal2.skyhanni.events.LorenzToolTipEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class EstimatedWardrobePrice { + + private val config get() = SkyHanniMod.feature.inventory.estimatedItemValues + + @SubscribeEvent + fun onTooltip(event: LorenzToolTipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.armor) return + if (!WardrobeAPI.inWardrobe()) return + if (WardrobeAPI.inCustomWardrobe) return + + val slot = WardrobeAPI.wardrobeSlots.firstOrNull { + event.slot.slotNumber == it.inventorySlot && it.isInCurrentPage() + } ?: return + + + val lore = WardrobeAPI.createWardrobePriceLore(slot) + if (lore.isEmpty()) return + + val tooltip = event.toolTip + var index = 3 + + tooltip.add(index++, "") + tooltip.addAll(index, lore) + } + + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(3, "misc.estimatedIemValueArmor", "misc.estimatedItemValues.armor") + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt new file mode 100644 index 000000000000..070e343a4ff4 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt @@ -0,0 +1,253 @@ +package at.hannibal2.skyhanni.features.inventory.wardrobe + +import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.events.DebugDataCollectEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryUpdatedEvent +import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValueCalculator +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.DelayedRun +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.NumberUtil.formatInt +import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher +import at.hannibal2.skyhanni.utils.RegexUtils.matches +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import com.google.gson.annotations.Expose +import net.minecraft.init.Blocks +import net.minecraft.init.Items +import net.minecraft.item.EnumDyeColor +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.milliseconds + +@SkyHanniModule +object WardrobeAPI { + + val storage get() = ProfileStorageData.profileSpecific?.wardrobe + + private val repoGroup = RepoPattern.group("inventory.wardrobe") + private val inventoryPattern by repoGroup.pattern( + "inventory.name", + "Wardrobe \\((?\\d+)/\\d+\\)" + ) + + /** + * REGEX-TEST: §7Slot 4: §aEquipped + */ + private val equippedSlotPattern by repoGroup.pattern( + "equippedslot", + "§7Slot \\d+: §aEquipped" + ) + + private const val FIRST_SLOT = 36 + private const val FIRST_HELMET_SLOT = 0 + private const val FIRST_CHESTPLATE_SLOT = 9 + private const val FIRST_LEGGINGS_SLOT = 18 + private const val FIRST_BOOTS_SLOT = 27 + const val MAX_SLOT_PER_PAGE = 9 + const val MAX_PAGES = 2 + + var wardrobeSlots = listOf() + var inCustomWardrobe = false + + class WardrobeSlot( + val id: Int, + val page: Int, + val inventorySlot: Int, + val helmetSlot: Int, + val chestplateSlot: Int, + val leggingsSlot: Int, + val bootsSlot: Int, + ) { + private fun getData() = storage?.wardrobeData?.getOrPut(id) { + WardrobeData( + id, + (1..4).associateWith { null }.toMutableMap(), + locked = true, + favorite = false, + ) + } + + var helmet: ItemStack? + get() = getData()?.armor?.get(1) + set(value) { + getData()?.armor?.set(1, value) + } + + var chestplate: ItemStack? + get() = getData()?.armor?.get(2) + set(value) { + getData()?.armor?.set(2, value) + } + + var leggings: ItemStack? + get() = getData()?.armor?.get(3) + set(value) { + getData()?.armor?.set(3, value) + } + + var boots: ItemStack? + get() = getData()?.armor?.get(4) + set(value) { + getData()?.armor?.set(4, value) + } + + var locked: Boolean + get() = getData()?.locked ?: true + set(value) { + getData()?.locked = value + } + + var favorite: Boolean + get() = getData()?.favorite ?: false + set(value) { + getData()?.favorite = value + } + + val armor get() = (1..4).associateWith { getData()?.armor?.get(it) }.toSortedMap().values.toList() + + fun isEmpty(): Boolean = armor.all { it == null } + + fun isCurrentSlot() = getData()?.id == currentWardrobeSlot + + fun isInCurrentPage() = (currentPage == null && page == 1) || (page == currentPage) + } + + + var currentWardrobeSlot: Int? + get() = storage?.currentWardrobeSlot + set(value) { + storage?.currentWardrobeSlot = value + } + + var currentPage: Int? = null + + init { + val list = mutableListOf() + var id = 0 + + for (page in 1..MAX_PAGES) { + for (slot in 0 until MAX_SLOT_PER_PAGE) { + val inventorySlot = FIRST_SLOT + slot + val helmetSlot = FIRST_HELMET_SLOT + slot + val chestplateSlot = FIRST_CHESTPLATE_SLOT + slot + val leggingsSlot = FIRST_LEGGINGS_SLOT + slot + val bootsSlot = FIRST_BOOTS_SLOT + slot + list.add(WardrobeSlot(++id, page, inventorySlot, helmetSlot, chestplateSlot, leggingsSlot, bootsSlot)) + } + } + wardrobeSlots = list + } + + private fun getWardrobeItem(itemStack: ItemStack?) = + if (itemStack?.item == ItemStack(Blocks.stained_glass_pane).item || itemStack == null) null else itemStack + + private fun getWardrobeSlotFromId(id: Int?) = wardrobeSlots.find { it.id == id } + + fun inWardrobe() = inventoryPattern.matches(InventoryUtils.openInventoryName()) + + fun createWardrobePriceLore(slot: WardrobeSlot) = buildList { + if (slot.isEmpty()) return@buildList + add("§aEstimated Armor Value:") + var totalPrice = 0.0 + slot.armor.forEach { + if (it != null) { + val price = EstimatedItemValueCalculator.getTotalPrice(it) + add(" §7- ${it.name}: §6${NumberUtil.format(price)}") + totalPrice += price + } + } + if (totalPrice != 0.0) add(" §aTotal Value: §6§l${NumberUtil.format(totalPrice)} coins") + } + + @SubscribeEvent + fun onInventoryUpdate(event: InventoryUpdatedEvent) { + if (!LorenzUtils.inSkyBlock) return + + inventoryPattern.matchMatcher(event.inventoryName) { + currentPage = group("currentPage").formatInt() + } ?: return + if (currentPage == null) return + + val itemsList = event.inventoryItems + + val allGrayDye = wardrobeSlots.all { + itemsList[it.inventorySlot]?.itemDamage == EnumDyeColor.GRAY.dyeDamage || !it.isInCurrentPage() + } + + if (allGrayDye) { + val allSlotsEmpty = wardrobeSlots.all { + (getWardrobeItem(itemsList[it.helmetSlot]) == null && getWardrobeItem(itemsList[it.chestplateSlot]) == null && + getWardrobeItem(itemsList[it.leggingsSlot]) == null && getWardrobeItem(itemsList[it.bootsSlot]) == null) || + !it.isInCurrentPage() + } + if (allSlotsEmpty) { + wardrobeSlots.filter { it.isInCurrentPage() }.forEach { + it.helmet = null + it.chestplate = null + it.leggings = null + it.boots = null + } + } else return + } + + var foundCurrentSlot = false + + for (slot in wardrobeSlots.filter { it.isInCurrentPage() }) { + slot.helmet = getWardrobeItem(itemsList[slot.helmetSlot]) + slot.chestplate = getWardrobeItem(itemsList[slot.chestplateSlot]) + slot.leggings = getWardrobeItem(itemsList[slot.leggingsSlot]) + slot.boots = getWardrobeItem(itemsList[slot.bootsSlot]) + if (equippedSlotPattern.matches(itemsList[slot.inventorySlot]?.name)) { + currentWardrobeSlot = slot.id + foundCurrentSlot = true + } + slot.locked = (itemsList[slot.inventorySlot] == ItemStack(Items.dye, EnumDyeColor.RED.dyeDamage)) + if (slot.locked) wardrobeSlots.forEach { if (it.id > slot.id) it.locked = true } + } + if (!foundCurrentSlot && getWardrobeSlotFromId(currentWardrobeSlot)?.page == currentPage) { + currentWardrobeSlot = null + } + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + DelayedRun.runDelayed(500.milliseconds) { + if (!inWardrobe()) currentPage = null + } + } + + @SubscribeEvent + fun onDebugCollect(event: DebugDataCollectEvent) { + event.title("Wardrobe") + event.addIrrelevant { + wardrobeSlots.forEach { slot -> + val slotInfo = buildString { + append("Slot ${slot.id}") + if (slot.favorite) append(" - Favorite: true") + } + if (slot.locked) { + add("$slotInfo is locked") + } else if (slot.isEmpty()) { + add("$slotInfo is empty") + } else { + add(slotInfo) + slot.helmet?.let { add(" Helmet: ${it.name}") } + slot.chestplate?.let { add(" Chestplate: ${it.name}") } + slot.leggings?.let { add(" Leggings: ${it.name}") } + slot.boots?.let { add(" Boots: ${it.name}") } + } + } + } + } + + class WardrobeData( + @Expose val id: Int, + @Expose var armor: MutableMap, + @Expose var locked: Boolean, + @Expose var favorite: Boolean, + ) +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt deleted file mode 100644 index 5e536ad015fe..000000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt +++ /dev/null @@ -1,74 +0,0 @@ -package at.hannibal2.skyhanni.features.misc.items - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator -import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent -import at.hannibal2.skyhanni.events.LorenzToolTipEvent -import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule -import at.hannibal2.skyhanni.utils.InventoryUtils -import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull -import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.NumberUtil -import net.minecraft.item.ItemStack -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -@SkyHanniModule -object EstimatedWardrobePrice { - - private val config get() = SkyHanniMod.feature.inventory.estimatedItemValues - var data = mutableMapOf>() - - @SubscribeEvent - fun onTooltip(event: LorenzToolTipEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!config.armor) return - if (!InventoryUtils.openInventoryName().contains("Wardrobe")) return - - val slot = event.slot.slotNumber - val id = slot % 9 - // Only showing in the armor select line - if (slot - id != 36) return - val items = data[id] ?: return - - var index = 3 - val toolTip = event.toolTip - if (toolTip.size < 4) return - toolTip.add(index++, "") - toolTip.add(index++, "§aEstimated Armor Value:") - - var totalPrice = 0.0 - for (item in items) { - - val price = EstimatedItemValueCalculator.getTotalPrice(item) - totalPrice += price - - toolTip.add(index++, " §7- ${item.name}: §6${NumberUtil.format(price)}") - } - toolTip.add(index, " §aTotal Value: §6§l${NumberUtil.format(totalPrice)} coins") - } - - @SubscribeEvent - fun onInventoryOpen(event: InventoryFullyOpenedEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!config.armor) return - if (!event.inventoryName.startsWith("Wardrobe")) return - - val map = mutableMapOf>() - - for ((slot, item) in event.inventoryItems) { - item.getInternalNameOrNull() ?: continue - val price = EstimatedItemValueCalculator.getTotalPrice(item) - if (price == 0.0) continue - val id = slot % 9 - val list = map.getOrPut(id) { mutableListOf() } - list.add(item) - } - data = map - } - - @SubscribeEvent - fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { - event.move(3, "misc.estimatedIemValueArmor", "misc.estimatedItemValues.armor") - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt index 2572b969f2fd..041457d25735 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt @@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.GuiContainerEvent.CloseWindowEvent import at.hannibal2.skyhanni.events.GuiContainerEvent.SlotClickEvent import at.hannibal2.skyhanni.test.SkyHanniDebugsAndTests +import at.hannibal2.skyhanni.utils.DelayedRun import io.github.moulberry.notenoughupdates.NEUApi import net.minecraft.client.gui.inventory.GuiContainer import net.minecraft.inventory.Slot @@ -40,7 +41,9 @@ class GuiContainerHook(guiAny: Any) { GuiData.preDrawEventCancelled = true ci.cancel() } else { - GuiData.preDrawEventCancelled = false + DelayedRun.runNextTick { + GuiData.preDrawEventCancelled = false + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/AccessorGuiContainer.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/AccessorGuiContainer.java index 5d9d6146dfd3..8a4485694af4 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/AccessorGuiContainer.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/AccessorGuiContainer.java @@ -20,4 +20,10 @@ public interface AccessorGuiContainer { @Invoker("drawGuiContainerBackgroundLayer") void invokeDrawGuiContainerBackgroundLayer_skyhanni(float f, int i, int mouseY); + + @Accessor("xSize") + int getWidth(); + + @Accessor("ySize") + int getHeight(); } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt index 00eb2e04642b..430310709c42 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt @@ -14,13 +14,16 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor import net.minecraft.block.state.IBlockState import net.minecraft.client.Minecraft import net.minecraft.client.entity.EntityOtherPlayerMP +import net.minecraft.client.resources.DefaultPlayerSkin import net.minecraft.entity.Entity import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.item.EntityArmorStand import net.minecraft.entity.monster.EntityEnderman import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.EnumPlayerModelParts import net.minecraft.item.ItemStack import net.minecraft.potion.Potion +import net.minecraft.scoreboard.ScorePlayerTeam import net.minecraft.util.AxisAlignedBB import net.minecraftforge.client.event.RenderLivingEvent import net.minecraftforge.fml.common.eventhandler.Event @@ -190,6 +193,27 @@ object EntityUtils { fun EntityLivingBase.isRunicAndCorrupt() = baseMaxHealth == health.toInt().derpy() * 3 * 4 fun Entity.cleanName() = this.name.removeColor() + + /** + * @return a fake player with the same skin as the real player + */ + fun getFakePlayer(): EntityOtherPlayerMP { + val mc = Minecraft.getMinecraft() + return object : EntityOtherPlayerMP( + mc.theWorld, + mc.thePlayer.gameProfile + ) { + override fun getLocationSkin() = + mc.thePlayer.locationSkin ?: DefaultPlayerSkin.getDefaultSkin(mc.thePlayer.uniqueID) + + override fun getTeam() = object : ScorePlayerTeam(null, null) { + override fun getNameTagVisibility() = EnumVisible.NEVER + } + + override fun isWearing(part: EnumPlayerModelParts?) = + mc.thePlayer.isWearing(part) && part != EnumPlayerModelParts.CAPE + } + } } private fun Event.cancel() { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt index e3f06b83b241..a0e8cd5d54f0 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt @@ -36,6 +36,8 @@ object InventoryUtils { fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim() + fun getWindowId() = (Minecraft.getMinecraft().currentScreen as? GuiChest)?.inventorySlots?.windowId + fun getItemsInOwnInventory() = getItemsInOwnInventoryWithNull()?.filterNotNull() ?: emptyList() @@ -112,4 +114,10 @@ object InventoryUtils { } fun NEUInternalName.getAmountInInventory(): Int = countItemsInLowerInventory { it.getInternalNameOrNull() == this } + + fun clickSlot(slot: Int, windowId: Int) { + if (windowId == -1) return + val mc = Minecraft.getMinecraft() + mc.playerController.windowClick(windowId, slot, 0, 0, mc.thePlayer) + } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt index d093dcfaf1ab..6af19e382e11 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -123,6 +123,13 @@ object ItemUtils { // Checks for hypixel enchantments in the attributes fun ItemStack.hasEnchantments() = getEnchantments()?.isNotEmpty() ?: false + fun ItemStack.removeEnchants(): ItemStack = apply { + val tag = tagCompound ?: NBTTagCompound() + tag.removeTag("ench") + tag.removeTag("StoredEnchantments") + tagCompound = tag + } + fun ItemStack.getSkullTexture(): String? { if (item != Items.skull) return null if (tagCompound == null) return null diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 40e8ddab95db..1506882cd40d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -559,6 +559,7 @@ object RenderUtils { renderables: List, extraSpace: Int = 0, posLabel: String, + addToGuiManager: Boolean = true, ) { if (renderables.isEmpty()) return var longestY = 0 @@ -575,7 +576,21 @@ object RenderUtils { GlStateManager.popMatrix() } - GuiEditManager.add(this, posLabel, longestX, longestY) + if (addToGuiManager) GuiEditManager.add(this, posLabel, longestX, longestY) + } + + fun Position.renderRenderable( + renderable: Renderable, + posLabel: String, + addToGuiManager: Boolean = true, + ) { + GlStateManager.pushMatrix() + val (x, y) = transform() + Renderable.withMousePosition(x, y) { + renderable.render(0, 0) + } + GlStateManager.popMatrix() + if (addToGuiManager) GuiEditManager.add(this, posLabel, renderable.width, 0) } /** diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt index 0d830e5c1788..cf6a3f181e70 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt @@ -8,8 +8,10 @@ import at.hannibal2.skyhanni.data.ToolTipData import at.hannibal2.skyhanni.features.chroma.ChromaShaderManager import at.hannibal2.skyhanni.features.chroma.ChromaType import at.hannibal2.skyhanni.features.misc.DarkenShader +import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper import at.hannibal2.skyhanni.utils.CollectionUtils.contains import at.hannibal2.skyhanni.utils.ColorUtils +import at.hannibal2.skyhanni.utils.ColorUtils.addAlpha import at.hannibal2.skyhanni.utils.ColorUtils.darker import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyClicked import at.hannibal2.skyhanni.utils.LorenzColor @@ -31,7 +33,9 @@ import net.minecraft.client.Minecraft import net.minecraft.client.gui.Gui import net.minecraft.client.gui.GuiIngameMenu import net.minecraft.client.gui.inventory.GuiEditSign +import net.minecraft.client.gui.inventory.GuiInventory.drawEntityOnScreen import net.minecraft.client.renderer.GlStateManager +import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation import java.awt.Color @@ -292,10 +296,10 @@ interface Renderable { bypassChecks: Boolean = false, condition: () -> Boolean = { true }, highlightsOnHoverSlots: List = emptyList(), + onHover: () -> Unit = {}, ) = object : Renderable { - override val width: Int - get() = max(hovered.width, unhovered.width) - override val height = 10 + override val width = max(hovered.width, unhovered.width) + override val height = max(hovered.height, unhovered.height) override val horizontalAlign get() = if (isHovered) hovered.horizontalAlign else unhovered.horizontalAlign override val verticalAlign get() = if (isHovered) hovered.verticalAlign else unhovered.verticalAlign @@ -304,6 +308,7 @@ interface Renderable { override fun render(posX: Int, posY: Int) { val pair = Pair(posX, posY) isHovered = if (isHovered(posX, posY) && condition() && shouldAllowLink(true, bypassChecks)) { + onHover() hovered.render(posX, posY) HighlightOnHoverSlot.currentSlots[pair] = highlightsOnHoverSlots true @@ -315,6 +320,29 @@ interface Renderable { } } + /** Bottom Layer must be bigger then the top layer */ + fun doubleLayered( + bottomLayer: Renderable, + topLayer: Renderable, + blockBottomHover: Boolean = true, + ) = object : Renderable { + override val width = bottomLayer.width + override val height = bottomLayer.height + override val horizontalAlign = bottomLayer.horizontalAlign + override val verticalAlign = bottomLayer.verticalAlign + + override fun render(posX: Int, posY: Int) { + val (x, y) = topLayer.renderXYAligned(posX, posY, width, height) + val (posX, posY) = if (topLayer.isHovered(posX + x, posY + y) && blockBottomHover) { + bottomLayer.width + 1 to bottomLayer.height + 1 + } else { + posX to posY + } + bottomLayer.render(posX, posY) + } + + } + fun itemStackWithTip( item: ItemStack, scale: Double = NEUItems.itemFontSize, @@ -562,7 +590,7 @@ interface Renderable { } // TODO use this to render current boosted crop in next jacob contest crops - fun Renderable.renderBounds(color: Color = LorenzColor.GREEN.toColor()) = object : Renderable { + fun Renderable.renderBounds(color: Color = LorenzColor.GREEN.toColor().addAlpha(100)) = object : Renderable { override val width = this@renderBounds.width override val height = this@renderBounds.height override val horizontalAlign = this@renderBounds.horizontalAlign @@ -846,5 +874,85 @@ interface Renderable { GlStateManager.translate(-padding.toFloat(), -padding.toFloat(), 0f) } } + + fun drawInsideRoundedRectWithOutline( + input: Renderable, + color: Color, + padding: Int = 2, + radius: Int = 10, + smoothness: Int = 2, + topOutlineColor: Int, + bottomOutlineColor: Int, + borderOutlineThickness: Int, + blur: Float = 0.7f, + horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT, + verticalAlign: VerticalAlignment = VerticalAlignment.TOP, + ) = object : Renderable { + override val width = input.width + padding * 2 + override val height = input.height + padding * 2 + override val horizontalAlign = horizontalAlign + override val verticalAlign = verticalAlign + + override fun render(posX: Int, posY: Int) { + RenderUtils.drawRoundRect(0, 0, width, height, color.rgb, radius, smoothness) + RenderUtils.drawRoundRectOutline( + 0, + 0, + width, + height, + topOutlineColor, + bottomOutlineColor, + borderOutlineThickness, + radius, + blur + ) + + GlStateManager.translate(padding.toFloat(), padding.toFloat(), 0f) + input.render(posX + padding, posY + padding) + GlStateManager.translate(-padding.toFloat(), -padding.toFloat(), 0f) + } + } + + fun fakePlayer( + player: EntityPlayer, + followMouse: Boolean = false, + eyesX: Float = 0f, + eyesY: Float = 0f, + width: Int = 50, + height: Int = 100, + entityScale: Int = 30, + padding: Int = 5, + color: Int? = null, + colorCondition: () -> Boolean = { true }, + ) = object : Renderable { + override val width = width + 2 * padding + override val height = height + 2 * padding + override val horizontalAlign = HorizontalAlignment.LEFT + override val verticalAlign = VerticalAlignment.TOP + val playerWidth = entityScale + val playerHeight = entityScale * 2 + val playerX = width / 2 + padding + val playerY = height / 2 + playerHeight / 2 + padding + + override fun render(posX: Int, posY: Int) { + GlStateManager.color(1f, 1f, 1f, 1f) + if (color != null) RenderLivingEntityHelper.setEntityColor(player, color, colorCondition) + val mouse = currentRenderPassMousePosition ?: return + val mouseXRelativeToPlayer = + if (followMouse) (posX + playerX - mouse.first).toFloat() else eyesX + val mouseYRelativeToPlayer = + if (followMouse) (posY + playerY - mouse.second - 1.62 * entityScale).toFloat() else eyesY + GlStateManager.translate(0f, 0f, 100f) + drawEntityOnScreen( + playerX, + playerY, + entityScale, + mouseXRelativeToPlayer, + mouseYRelativeToPlayer, + player + ) + GlStateManager.translate(0f, 0f, -100f) + } + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt index cf81fc9ff8bd..d1a8aae02b1d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt @@ -48,25 +48,28 @@ internal object RenderableUtils { else -> 0 } - fun Renderable.renderXYAligned(posX: Int, posY: Int, xSpace: Int, ySpace: Int) { + fun Renderable.renderXYAligned(posX: Int, posY: Int, xSpace: Int, ySpace: Int): Pair { val xOffset = calculateAlignmentXOffset(this, xSpace) val yOffset = calculateAlignmentYOffset(this, ySpace) GlStateManager.translate(xOffset.toFloat(), yOffset.toFloat(), 0f) this.render(posX + xOffset, posY + yOffset) GlStateManager.translate(-xOffset.toFloat(), -yOffset.toFloat(), 0f) + return xOffset to yOffset } - fun Renderable.renderXAligned(posX: Int, posY: Int, xSpace: Int) { + fun Renderable.renderXAligned(posX: Int, posY: Int, xSpace: Int): Int { val xOffset = calculateAlignmentXOffset(this, xSpace) GlStateManager.translate(xOffset.toFloat(), 0f, 0f) this.render(posX + xOffset, posY) GlStateManager.translate(-xOffset.toFloat(), 0f, 0f) + return xOffset } - fun Renderable.renderYAligned(posX: Int, posY: Int, ySpace: Int) { + fun Renderable.renderYAligned(posX: Int, posY: Int, ySpace: Int): Int { val yOffset = calculateAlignmentYOffset(this, ySpace) GlStateManager.translate(0f, yOffset.toFloat(), 0f) this.render(posX, posY + yOffset) GlStateManager.translate(0f, -yOffset.toFloat(), 0f) + return yOffset } } From 4268fcf7bcb5e23ef85198bf46dbf4c713526567 Mon Sep 17 00:00:00 2001 From: Cal Date: Sun, 9 Jun 2024 09:59:42 +1000 Subject: [PATCH 02/11] a few small things --- .../skyhanni/config/features/inventory/InventoryConfig.java | 3 ++- .../skyhanni/config/storage/ProfileSpecificStorage.java | 1 - .../skyhanni/features/inventory/wardrobe/CustomWardrobe.kt | 1 - .../java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java index 990e555d2706..680b75fc187c 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java @@ -110,7 +110,8 @@ public class InventoryConfig { NEW_YEAR_CAKE, RANCHERS_BOOTS_SPEED, LARVA_HOOK, - VACUUM_GARDEN)); + VACUUM_GARDEN + )); public enum ItemNumberEntry implements HasLegacyId { MASTER_STAR_TIER("§bMaster Star Tier", 0), diff --git a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java index 0fce526a5e47..8848a5da2299 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java @@ -629,7 +629,6 @@ public static class WardrobeStorage { public Integer currentWardrobeSlot = null; } - @Expose public UpgradeReminder.CommunityShopUpgrade communityShopProfileUpgrade = null; } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index 03004a7f7e83..268ae93de571 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -571,7 +571,6 @@ object CustomWardrobe { }?.toChromaColor()?.transformIf({ isInCurrentPage() }) { darker() } ?: (if (!isInCurrentPage()) samePageColor else otherPageColor).toChromaColor() .transformIf({ locked || isEmpty() }) { darker() }.addAlpha(100) - } fun isEnabled() = LorenzUtils.inSkyBlock && inWardrobe() && config.enabled diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt index cf6a3f181e70..870a3a2f297e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt @@ -340,7 +340,6 @@ interface Renderable { } bottomLayer.render(posX, posY) } - } fun itemStackWithTip( From 80bb79903ba4c4b55c462868fc1bbbb774cadcc3 Mon Sep 17 00:00:00 2001 From: Empa <42304516+itsempa@users.noreply.github.com> Date: Sun, 9 Jun 2024 08:55:31 +0200 Subject: [PATCH 03/11] fix some things Signed-off-by: Empa <42304516+ItsEmpa@users.noreply.github.com> --- .../features/inventory/wardrobe/CustomWardrobe.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index 03004a7f7e83..a6cc2745aaf1 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -92,6 +92,7 @@ object CustomWardrobe { event.cancel() } + // Edit button in normal wardrobe while in edit mode @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) { if (!isEnabled()) return @@ -147,10 +148,10 @@ object CustomWardrobe { return true } val previousActiveScale = activeScale - val unscaledRenderableWidth = 100 * (renderable.first / activeScale.toDouble()) - val unscaledRenderableHeight = 100 * (renderable.second / activeScale.toDouble()) - val autoScaleWidth = 100 * ((gui.first * 0.9) / unscaledRenderableWidth) - val autoScaleHeight = 10_000 * ((gui.second * 0.9) / unscaledRenderableHeight) + val unscaledRenderableWidth = renderable.first / activeScale + val unscaledRenderableHeight = renderable.second / activeScale + val autoScaleWidth = 0.95 * gui.first / unscaledRenderableWidth + val autoScaleHeight = 0.95 * gui.second / unscaledRenderableHeight val maxScale = min(autoScaleWidth, autoScaleHeight).toInt() activeScale = config.spacing.globalScale.get().coerceAtMost(maxScale) @@ -180,7 +181,7 @@ object CustomWardrobe { if (list.isEmpty()) wardrobeWarning = "§cDidn't set any favorites" } - val maxPlayersPerRow = config.spacing.maxPlayersPerRow.get() + val maxPlayersPerRow = config.spacing.maxPlayersPerRow.get().coerceAtLeast(1) val maxPlayersRows = ((MAX_SLOT_PER_PAGE * MAX_PAGES - 1) / maxPlayersPerRow) + 1 val containerWidth = (config.spacing.slotWidth.get() * (activeScale / 100.0)).toInt() val containerHeight = (config.spacing.slotHeight.get() * (activeScale / 100.0)).toInt() @@ -203,8 +204,9 @@ object CustomWardrobe { currentMaxSize = maxRenderableWidth to maxRenderableHeight wardrobeWarning?.let { text -> - val warningRenderable = Renderable.string( + val warningRenderable = Renderable.wrappedString( text, + maxRenderableWidth, 3.0 * (activeScale / 100.0), horizontalAlign = HorizontalAlignment.CENTER ) From d7129c2104a07b6aaf84419cf612ca3853928a08 Mon Sep 17 00:00:00 2001 From: Empa <42304516+ItsEmpa@users.noreply.github.com> Date: Sun, 9 Jun 2024 09:32:32 +0200 Subject: [PATCH 04/11] fix color Signed-off-by: Empa <42304516+ItsEmpa@users.noreply.github.com> --- .../inventory/wardrobe/CustomWardrobe.kt | 19 +++++++++---------- .../at/hannibal2/skyhanni/utils/ColorUtils.kt | 18 ++++++++---------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index 8c0dcba15ac0..0932892868e7 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -564,16 +564,15 @@ object CustomWardrobe { update() } - private fun WardrobeAPI.WardrobeSlot.getSlotColor() = - with(config.color) { - when { - isCurrentSlot() -> equippedColor - favorite -> favoriteColor - else -> null - }?.toChromaColor()?.transformIf({ isInCurrentPage() }) { darker() } - ?: (if (!isInCurrentPage()) samePageColor else otherPageColor).toChromaColor() - .transformIf({ locked || isEmpty() }) { darker() }.addAlpha(100) - } + private fun WardrobeAPI.WardrobeSlot.getSlotColor() = with(config.color) { + when { + isCurrentSlot() -> equippedColor + favorite -> favoriteColor + else -> null + }?.toChromaColor()?.transformIf({ isInCurrentPage() }) { darker() } + ?: (if (isInCurrentPage()) samePageColor else otherPageColor).toChromaColor() + .transformIf({ locked || isEmpty() }) { darker(0.2) }.addAlpha(100) + } fun isEnabled() = LorenzUtils.inSkyBlock && inWardrobe() && config.enabled } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt index 52656f6ad44c..ed0a9740eade 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ColorUtils.kt @@ -1,11 +1,10 @@ package at.hannibal2.skyhanni.utils import java.awt.Color -import kotlin.math.max object ColorUtils { - /** Transfer string colors from the config to java.awt.Color */ + /** Transfer string colors from the config to [Color] */ fun String.toChromaColor() = Color(toChromaColorInt(), true) fun String.toChromaColorInt() = SpecialColour.specialToChromaRGB(this) @@ -25,14 +24,13 @@ object ColorUtils { (start.blue * (1 - percent) + end.blue * percent).toInt() ) - fun Color.darker(factor: Double): Color { - return Color( - max((red * factor).toInt(), 0), - max((green * factor).toInt(), 0), - max((blue * factor).toInt(), 0), - alpha - ) - } + /** Darkens a color by a [factor]. The lower the [factor], the darker the color. */ + fun Color.darker(factor: Double = 0.7) = Color( + (red * factor).toInt().coerceIn(0, 255), + (green * factor).toInt().coerceIn(0, 255), + (blue * factor).toInt().coerceIn(0, 255), + alpha + ) fun Color.withAlpha(alpha: Int): Int = (alpha.coerceIn(0, 255) shl 24) or (this.rgb and 0x00ffffff) From b1d8ff8252a765547e743163178a0d26282ef8d3 Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Date: Sun, 9 Jun 2024 10:53:42 +0200 Subject: [PATCH 05/11] code cleanup, rename variables, removed function imports. All in the name of readability --- .../features/inventory/InventoryConfig.java | 7 ++- .../storage/ProfileSpecificStorage.java | 4 +- .../inventory/wardrobe/CustomWardrobe.kt | 52 ++++++++----------- .../wardrobe/EstimatedWardrobePrice.kt | 4 +- .../inventory/wardrobe/WardrobeAPI.kt | 47 ++++++++--------- .../skyhanni/utils/InventoryUtils.kt | 10 ++-- 6 files changed, 58 insertions(+), 66 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java index 680b75fc187c..f20643cc323b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java @@ -170,8 +170,11 @@ public String toString() { public boolean vacuumBagCap = true; @Expose - @ConfigOption(name = "Quick Craft Confirmation", desc = "Require Ctrl+Click to craft items that aren't often quick crafted " + - "(e.g. armor, weapons, accessories). Sack items can be crafted normally.") + @ConfigOption(name = "Quick Craft Confirmation", + desc = "Require Ctrl+Click to craft items that aren't often quick crafted " + + "(e.g. armor, weapons, accessories). " + + "Sack items can be crafted normally." + ) @ConfigEditorBoolean @FeatureToggle public boolean quickCraftingConfirmation = false; diff --git a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java index 8848a5da2299..10fe3a6e6956 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java @@ -622,11 +622,11 @@ public static class DianaStorage { public static class WardrobeStorage { @Expose - public Map wardrobeData = new HashMap<>(); + public Map data = new HashMap<>(); @Expose @Nullable - public Integer currentWardrobeSlot = null; + public Integer currentSlot = null; } @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index 0932892868e7..d4ab3e0f8700 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -9,11 +9,6 @@ import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryUpdatedEvent import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.MAX_PAGES import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.MAX_SLOT_PER_PAGE -import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.createWardrobePriceLore -import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.currentPage -import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.currentWardrobeSlot -import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.inCustomWardrobe -import at.hannibal2.skyhanni.features.inventory.wardrobe.WardrobeAPI.inWardrobe import at.hannibal2.skyhanni.mixins.transformers.gui.AccessorGuiContainer import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.utils.ColorUtils.addAlpha @@ -26,8 +21,7 @@ import at.hannibal2.skyhanni.utils.ConditionalUtils.transformIf import at.hannibal2.skyhanni.utils.ConfigUtils.jumpToEditor import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.EntityUtils.getFakePlayer -import at.hannibal2.skyhanni.utils.InventoryUtils.clickSlot -import at.hannibal2.skyhanni.utils.InventoryUtils.getWindowId +import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.removeEnchants import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment @@ -60,12 +54,12 @@ object CustomWardrobe { @SubscribeEvent fun onGuiRender(event: GuiContainerEvent.BeforeDraw) { if (!isEnabled() || editMode) return - val gui = event.gui val renderable = displayRenderable ?: run { update() displayRenderable ?: return } + val gui = event.gui val screenSize = gui.width to gui.height if (screenSize != lastScreenSize) { @@ -109,7 +103,7 @@ object CustomWardrobe { fun onInventoryClose(event: InventoryCloseEvent) { waitingForInventoryUpdate = false DelayedRun.runDelayed(500.milliseconds) { - if (!inWardrobe()) { + if (!WardrobeAPI.inWardrobe()) { reset() } } @@ -162,7 +156,7 @@ object CustomWardrobe { } private fun createRenderables(): Renderable { - var list = WardrobeAPI.wardrobeSlots + var list = WardrobeAPI.slots var wardrobeWarning: String? = null if (list.isEmpty()) wardrobeWarning = "§cYour wardrobe is empty :(" @@ -315,7 +309,7 @@ object CustomWardrobe { onClick = { config::enabled.jumpToEditor() reset() - currentPage = null + WardrobeAPI.currentPage = null } ), blockBottomHover = false @@ -325,7 +319,7 @@ object CustomWardrobe { ) private fun reset() { - inCustomWardrobe = false + WardrobeAPI.inCustomWardrobe = false editMode = false displayRenderable = null inventoryButton = null @@ -339,17 +333,17 @@ object CustomWardrobe { val backButton = createLabeledButton( "§aBack", onClick = { - clickSlot(48, getWindowId() ?: -1) + InventoryUtils.clickSlot(48) reset() - currentPage = null + WardrobeAPI.currentPage = null } ) val exitButton = createLabeledButton( "§cClose", onClick = { - clickSlot(49, getWindowId() ?: -1) + InventoryUtils.clickSlot(49) reset() - currentPage = null + WardrobeAPI.currentPage = null } ) @@ -398,7 +392,7 @@ object CustomWardrobe { hoveredColor = color, unhoveredColor = color.darker(0.8), onClick = { - inCustomWardrobe = false + WardrobeAPI.inCustomWardrobe = false editMode = false update() } @@ -432,7 +426,7 @@ object CustomWardrobe { ) if (config.estimatedValue && !wardrobeSlot.isEmpty()) { - val lore = createWardrobePriceLore(wardrobeSlot) + val lore = WardrobeAPI.createPriceLore(wardrobeSlot) list.add( Renderable.hoverTips( Renderable.string( @@ -452,7 +446,7 @@ object CustomWardrobe { text: String, hoveredColor: Color = Color(130, 130, 130, 200), unhoveredColor: Color = hoveredColor.darker(0.57), - onClick: () -> Unit + onClick: () -> Unit, ): Renderable { val buttonWidth = (config.spacing.buttonWidth.get() * (activeScale / 100.0)).toInt() val buttonHeight = (config.spacing.buttonHeight.get() * (activeScale / 100.0)).toInt() @@ -543,28 +537,26 @@ object CustomWardrobe { private fun WardrobeAPI.WardrobeSlot.clickSlot() { val previousPageSlot = 45 val nextPageSlot = 53 - val wardrobePage = currentPage ?: return - val windowId = getWindowId() ?: -1 + val wardrobePage = WardrobeAPI.currentPage ?: return if (isInCurrentPage()) { if (isEmpty() || locked || waitingForInventoryUpdate) return - currentWardrobeSlot = if (isCurrentSlot()) null - else id - clickSlot(inventorySlot, windowId) + WardrobeAPI.currentSlot = if (isCurrentSlot()) null else id + InventoryUtils.clickSlot(inventorySlot) } else { if (page < wardrobePage) { - currentPage = wardrobePage - 1 + WardrobeAPI.currentPage = wardrobePage - 1 waitingForInventoryUpdate = true - clickSlot(previousPageSlot, windowId) + InventoryUtils.clickSlot(previousPageSlot) } else if (page > wardrobePage) { - currentPage = wardrobePage + 1 + WardrobeAPI.currentPage = wardrobePage + 1 waitingForInventoryUpdate = true - clickSlot(nextPageSlot, windowId) + InventoryUtils.clickSlot(nextPageSlot) } } update() } - private fun WardrobeAPI.WardrobeSlot.getSlotColor() = with(config.color) { + private fun WardrobeAPI.WardrobeSlot.getSlotColor(): Color = with(config.color) { when { isCurrentSlot() -> equippedColor favorite -> favoriteColor @@ -574,5 +566,5 @@ object CustomWardrobe { .transformIf({ locked || isEmpty() }) { darker(0.2) }.addAlpha(100) } - fun isEnabled() = LorenzUtils.inSkyBlock && inWardrobe() && config.enabled + fun isEnabled() = LorenzUtils.inSkyBlock && WardrobeAPI.inWardrobe() && config.enabled } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt index 7c2610c83ce4..38ef9f8161c6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt @@ -17,12 +17,12 @@ class EstimatedWardrobePrice { if (!WardrobeAPI.inWardrobe()) return if (WardrobeAPI.inCustomWardrobe) return - val slot = WardrobeAPI.wardrobeSlots.firstOrNull { + val slot = WardrobeAPI.slots.firstOrNull { event.slot.slotNumber == it.inventorySlot && it.isInCurrentPage() } ?: return - val lore = WardrobeAPI.createWardrobePriceLore(slot) + val lore = WardrobeAPI.createPriceLore(slot) if (lore.isEmpty()) return val tooltip = event.toolTip diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt index 070e343a4ff4..1ba6d9ea5363 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt @@ -50,7 +50,7 @@ object WardrobeAPI { const val MAX_SLOT_PER_PAGE = 9 const val MAX_PAGES = 2 - var wardrobeSlots = listOf() + var slots = listOf() var inCustomWardrobe = false class WardrobeSlot( @@ -62,7 +62,7 @@ object WardrobeAPI { val leggingsSlot: Int, val bootsSlot: Int, ) { - private fun getData() = storage?.wardrobeData?.getOrPut(id) { + private fun getData() = storage?.data?.getOrPut(id) { WardrobeData( id, (1..4).associateWith { null }.toMutableMap(), @@ -111,16 +111,15 @@ object WardrobeAPI { fun isEmpty(): Boolean = armor.all { it == null } - fun isCurrentSlot() = getData()?.id == currentWardrobeSlot + fun isCurrentSlot() = getData()?.id == currentSlot fun isInCurrentPage() = (currentPage == null && page == 1) || (page == currentPage) } - - var currentWardrobeSlot: Int? - get() = storage?.currentWardrobeSlot + var currentSlot: Int? + get() = storage?.currentSlot set(value) { - storage?.currentWardrobeSlot = value + storage?.currentSlot = value } var currentPage: Int? = null @@ -139,26 +138,24 @@ object WardrobeAPI { list.add(WardrobeSlot(++id, page, inventorySlot, helmetSlot, chestplateSlot, leggingsSlot, bootsSlot)) } } - wardrobeSlots = list + slots = list } private fun getWardrobeItem(itemStack: ItemStack?) = if (itemStack?.item == ItemStack(Blocks.stained_glass_pane).item || itemStack == null) null else itemStack - private fun getWardrobeSlotFromId(id: Int?) = wardrobeSlots.find { it.id == id } + private fun getWardrobeSlotFromId(id: Int?) = slots.find { it.id == id } fun inWardrobe() = inventoryPattern.matches(InventoryUtils.openInventoryName()) - fun createWardrobePriceLore(slot: WardrobeSlot) = buildList { + fun createPriceLore(slot: WardrobeSlot) = buildList { if (slot.isEmpty()) return@buildList add("§aEstimated Armor Value:") var totalPrice = 0.0 - slot.armor.forEach { - if (it != null) { - val price = EstimatedItemValueCalculator.getTotalPrice(it) - add(" §7- ${it.name}: §6${NumberUtil.format(price)}") - totalPrice += price - } + for (stack in slot.armor.filterNotNull()) { + val price = EstimatedItemValueCalculator.getTotalPrice(stack) + add(" §7- ${stack.name}: §6${NumberUtil.format(price)}") + totalPrice += price } if (totalPrice != 0.0) add(" §aTotal Value: §6§l${NumberUtil.format(totalPrice)} coins") } @@ -174,18 +171,18 @@ object WardrobeAPI { val itemsList = event.inventoryItems - val allGrayDye = wardrobeSlots.all { + val allGrayDye = slots.all { itemsList[it.inventorySlot]?.itemDamage == EnumDyeColor.GRAY.dyeDamage || !it.isInCurrentPage() } if (allGrayDye) { - val allSlotsEmpty = wardrobeSlots.all { + val allSlotsEmpty = slots.all { (getWardrobeItem(itemsList[it.helmetSlot]) == null && getWardrobeItem(itemsList[it.chestplateSlot]) == null && getWardrobeItem(itemsList[it.leggingsSlot]) == null && getWardrobeItem(itemsList[it.bootsSlot]) == null) || !it.isInCurrentPage() } if (allSlotsEmpty) { - wardrobeSlots.filter { it.isInCurrentPage() }.forEach { + slots.filter { it.isInCurrentPage() }.forEach { it.helmet = null it.chestplate = null it.leggings = null @@ -196,20 +193,20 @@ object WardrobeAPI { var foundCurrentSlot = false - for (slot in wardrobeSlots.filter { it.isInCurrentPage() }) { + for (slot in slots.filter { it.isInCurrentPage() }) { slot.helmet = getWardrobeItem(itemsList[slot.helmetSlot]) slot.chestplate = getWardrobeItem(itemsList[slot.chestplateSlot]) slot.leggings = getWardrobeItem(itemsList[slot.leggingsSlot]) slot.boots = getWardrobeItem(itemsList[slot.bootsSlot]) if (equippedSlotPattern.matches(itemsList[slot.inventorySlot]?.name)) { - currentWardrobeSlot = slot.id + currentSlot = slot.id foundCurrentSlot = true } slot.locked = (itemsList[slot.inventorySlot] == ItemStack(Items.dye, EnumDyeColor.RED.dyeDamage)) - if (slot.locked) wardrobeSlots.forEach { if (it.id > slot.id) it.locked = true } + if (slot.locked) slots.forEach { if (it.id > slot.id) it.locked = true } } - if (!foundCurrentSlot && getWardrobeSlotFromId(currentWardrobeSlot)?.page == currentPage) { - currentWardrobeSlot = null + if (!foundCurrentSlot && getWardrobeSlotFromId(currentSlot)?.page == currentPage) { + currentSlot = null } } @@ -224,7 +221,7 @@ object WardrobeAPI { fun onDebugCollect(event: DebugDataCollectEvent) { event.title("Wardrobe") event.addIrrelevant { - wardrobeSlots.forEach { slot -> + for (slot in slots) { val slotInfo = buildString { append("Slot ${slot.id}") if (slot.favorite) append(" - Favorite: true") diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt index a0e8cd5d54f0..8e1fff3efd4c 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt @@ -36,7 +36,7 @@ object InventoryUtils { fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim() - fun getWindowId() = (Minecraft.getMinecraft().currentScreen as? GuiChest)?.inventorySlots?.windowId + fun getWindowId(): Int? = (Minecraft.getMinecraft().currentScreen as? GuiChest)?.inventorySlots?.windowId fun getItemsInOwnInventory() = getItemsInOwnInventoryWithNull()?.filterNotNull() ?: emptyList() @@ -115,9 +115,9 @@ object InventoryUtils { fun NEUInternalName.getAmountInInventory(): Int = countItemsInLowerInventory { it.getInternalNameOrNull() == this } - fun clickSlot(slot: Int, windowId: Int) { - if (windowId == -1) return - val mc = Minecraft.getMinecraft() - mc.playerController.windowClick(windowId, slot, 0, 0, mc.thePlayer) + fun clickSlot(slot: Int) { + val windowId = getWindowId() ?: return + val controller = Minecraft.getMinecraft().playerController + controller.windowClick(windowId, slot, 0, 0, Minecraft.getMinecraft().thePlayer) } } From f6706b038c738a17d2af72f9a3c97a6b82e65d67 Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Date: Sun, 9 Jun 2024 11:18:56 +0200 Subject: [PATCH 06/11] using list instead of map, removing unnecessary armor piece parameters --- .../inventory/wardrobe/WardrobeAPI.kt | 61 ++++++------------- 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt index 1ba6d9ea5363..a4e9228da80f 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt @@ -62,39 +62,15 @@ object WardrobeAPI { val leggingsSlot: Int, val bootsSlot: Int, ) { - private fun getData() = storage?.data?.getOrPut(id) { + fun getData() = storage?.data?.getOrPut(id) { WardrobeData( id, - (1..4).associateWith { null }.toMutableMap(), + armor = emptyArmor(), locked = true, favorite = false, ) } - var helmet: ItemStack? - get() = getData()?.armor?.get(1) - set(value) { - getData()?.armor?.set(1, value) - } - - var chestplate: ItemStack? - get() = getData()?.armor?.get(2) - set(value) { - getData()?.armor?.set(2, value) - } - - var leggings: ItemStack? - get() = getData()?.armor?.get(3) - set(value) { - getData()?.armor?.set(3, value) - } - - var boots: ItemStack? - get() = getData()?.armor?.get(4) - set(value) { - getData()?.armor?.set(4, value) - } - var locked: Boolean get() = getData()?.locked ?: true set(value) { @@ -107,7 +83,8 @@ object WardrobeAPI { getData()?.favorite = value } - val armor get() = (1..4).associateWith { getData()?.armor?.get(it) }.toSortedMap().values.toList() +// val armor get() = (1..4).associateWith { getData()?.armor?.get(it) }.toSortedMap().values.toList() + val armor get() = getData()?.armor ?: emptyArmor() fun isEmpty(): Boolean = armor.all { it == null } @@ -116,6 +93,8 @@ object WardrobeAPI { fun isInCurrentPage() = (currentPage == null && page == 1) || (page == currentPage) } + private fun emptyArmor(): List = listOf(null, null, null, null) + var currentSlot: Int? get() = storage?.currentSlot set(value) { @@ -182,11 +161,8 @@ object WardrobeAPI { !it.isInCurrentPage() } if (allSlotsEmpty) { - slots.filter { it.isInCurrentPage() }.forEach { - it.helmet = null - it.chestplate = null - it.leggings = null - it.boots = null + for (slot in slots.filter { it.isInCurrentPage() }) { + slot.getData()?.armor = emptyArmor() } } else return } @@ -194,10 +170,12 @@ object WardrobeAPI { var foundCurrentSlot = false for (slot in slots.filter { it.isInCurrentPage() }) { - slot.helmet = getWardrobeItem(itemsList[slot.helmetSlot]) - slot.chestplate = getWardrobeItem(itemsList[slot.chestplateSlot]) - slot.leggings = getWardrobeItem(itemsList[slot.leggingsSlot]) - slot.boots = getWardrobeItem(itemsList[slot.bootsSlot]) + slot.getData()?.armor = listOf( + getWardrobeItem(itemsList[slot.helmetSlot]), + getWardrobeItem(itemsList[slot.chestplateSlot]), + getWardrobeItem(itemsList[slot.leggingsSlot]), + getWardrobeItem(itemsList[slot.bootsSlot]), + ) if (equippedSlotPattern.matches(itemsList[slot.inventorySlot]?.name)) { currentSlot = slot.id foundCurrentSlot = true @@ -232,10 +210,11 @@ object WardrobeAPI { add("$slotInfo is empty") } else { add(slotInfo) - slot.helmet?.let { add(" Helmet: ${it.name}") } - slot.chestplate?.let { add(" Chestplate: ${it.name}") } - slot.leggings?.let { add(" Leggings: ${it.name}") } - slot.boots?.let { add(" Boots: ${it.name}") } + setOf("Helmet", "Chestplate", "Leggings", "Boots").forEachIndexed { id, armourName -> + slot.getData()?.armor?.get(id)?.name?.let { name -> + add(" $armourName: $name") + } + } } } } @@ -243,7 +222,7 @@ object WardrobeAPI { class WardrobeData( @Expose val id: Int, - @Expose var armor: MutableMap, + @Expose var armor: List, @Expose var locked: Boolean, @Expose var favorite: Boolean, ) From 770ed78f2e650bb8c99fd76749b69a21a7b806ff Mon Sep 17 00:00:00 2001 From: J10a1n15 <45315647+j10a1n15@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:21:14 +0200 Subject: [PATCH 07/11] resolve Signed-off-by: J10a1n15 <45315647+j10a1n15@users.noreply.github.com> --- .../inventory/wardrobe/CustomWardrobe.kt | 146 ++++++++++-------- .../wardrobe/EstimatedWardrobePrice.kt | 11 +- .../inventory/wardrobe/WardrobeAPI.kt | 66 ++------ .../inventory/wardrobe/WardrobeSlot.kt | 40 +++++ 4 files changed, 147 insertions(+), 116 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index d4ab3e0f8700..78e7fffb64fb 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -102,6 +102,7 @@ object CustomWardrobe { @SubscribeEvent fun onInventoryClose(event: InventoryCloseEvent) { waitingForInventoryUpdate = false + if (!isEnabled()) return DelayedRun.runDelayed(500.milliseconds) { if (!WardrobeAPI.inWardrobe()) { reset() @@ -155,26 +156,93 @@ object CustomWardrobe { } else false } - private fun createRenderables(): Renderable { - var list = WardrobeAPI.slots + private fun createWarning(list: List): Pair> { var wardrobeWarning: String? = null + var wardrobeSlots = list - if (list.isEmpty()) wardrobeWarning = "§cYour wardrobe is empty :(" + if (wardrobeSlots.isEmpty()) wardrobeWarning = "§cYour wardrobe is empty :(" if (config.hideLockedSlots) { - list = list.filter { !it.locked } - if (list.isEmpty()) wardrobeWarning = "§cAll your slots are locked? Somehow" + wardrobeSlots = wardrobeSlots.filter { !it.locked } + if (wardrobeSlots.isEmpty()) wardrobeWarning = "§cAll your slots are locked? Somehow" } if (config.hideEmptySlots) { - list = list.filter { !it.isEmpty() } - if (list.isEmpty()) wardrobeWarning = "§cAll slots are empty :(" + wardrobeSlots = wardrobeSlots.filter { !it.isEmpty() } + if (wardrobeSlots.isEmpty()) wardrobeWarning = "§cAll slots are empty :(" } if (config.onlyFavorites) { - list = list.filter { it.favorite || it.isCurrentSlot() } - if (list.isEmpty()) wardrobeWarning = "§cDidn't set any favorites" + wardrobeSlots = wardrobeSlots.filter { it.favorite || it.isCurrentSlot() } + if (wardrobeSlots.isEmpty()) wardrobeWarning = "§cDidn't set any favorites" + } + + return wardrobeWarning to wardrobeSlots + } + + private fun createArmorTooltipRenderable( + slot: WardrobeSlot, + containerHeight: Int, + containerWidth: Int + ): Renderable { + val loreList = mutableListOf() + val height = containerHeight - 3 + + // This is needed to keep the background size the same as the player renderable size + val hoverableSizes = MutableList(4) { height / 4 }.apply { + for (k in 0 until height % 4) this[k]++ } + for (armorIndex in 0 until 4) { + val stack = slot.armor[armorIndex]?.copy() + if (stack == null) { + loreList.add(Renderable.placeholder(containerWidth, hoverableSizes[armorIndex])) + } else { + loreList.add( + Renderable.hoverable( + Renderable.hoverTips( + Renderable.placeholder(containerWidth, hoverableSizes[armorIndex]), + stack.getTooltip(Minecraft.getMinecraft().thePlayer, false) + ), + Renderable.placeholder(containerWidth, hoverableSizes[armorIndex]), + bypassChecks = true + ) + ) + } + } + return Renderable.verticalContainer(loreList, spacing = 1) + } + + private fun createFakePlayerRenderable( + slot: WardrobeSlot, + playerWidth: Double, + containerHeight: Int, + containerWidth: Int + ): Renderable { + val fakePlayer = getFakePlayer() + var scale = playerWidth + + fakePlayer.inventory.armorInventory = + slot.armor.map { it?.copy()?.removeEnchants() }.reversed().toTypedArray() + + val playerColor = if (!slot.isInCurrentPage()) { + scale *= 0.9 + Color.GRAY.withAlpha(100) + } else null + + return Renderable.fakePlayer( + fakePlayer, + followMouse = config.eyesFollowMouse, + width = containerWidth, + height = containerHeight, + entityScale = scale.toInt(), + padding = 0, + color = playerColor, + ) + } + + private fun createRenderables(): Renderable { + val (wardrobeWarning, list) = createWarning(WardrobeAPI.slots) + val maxPlayersPerRow = config.spacing.maxPlayersPerRow.get().coerceAtLeast(1) val maxPlayersRows = ((MAX_SLOT_PER_PAGE * MAX_PAGES - 1) / maxPlayersPerRow) + 1 val containerWidth = (config.spacing.slotWidth.get() * (activeScale / 100.0)).toInt() @@ -216,38 +284,10 @@ object CustomWardrobe { val rowsRenderables = chunkedList.map { row -> val slotsRenderables = row.map { slot -> - var scale = playerWidth - val armorTooltipRenderable = { - val loreList = mutableListOf() - val height = containerHeight - 3 - - // This is needed to keep the background size the same as the player renderable size - val hoverableSizes = MutableList(4) { height / 4 }.apply { - for (k in 0 until height % 4) this[k]++ - } - - for (armorIndex in 0 until 4) { - val stack = slot.armor[armorIndex]?.copy() - if (stack == null) { - loreList.add(Renderable.placeholder(containerWidth, hoverableSizes[armorIndex])) - } else { - loreList.add( - Renderable.hoverable( - Renderable.hoverTips( - Renderable.placeholder(containerWidth, hoverableSizes[armorIndex]), - stack.getTooltip(Minecraft.getMinecraft().thePlayer, false) - ), - Renderable.placeholder(containerWidth, hoverableSizes[armorIndex]), - bypassChecks = true - ) - ) - } - } - Renderable.verticalContainer(loreList, spacing = 1) - } + val armorTooltipRenderable = createArmorTooltipRenderable(slot, containerHeight, containerWidth) val playerBackground = createHoverableRenderable( - armorTooltipRenderable.invoke(), + armorTooltipRenderable, topLayerRenderable = addSlotHoverableButtons(slot), hoveredColor = slot.getSlotColor(), borderOutlineThickness = config.spacing.outlineThickness.get(), @@ -255,25 +295,7 @@ object CustomWardrobe { onClick = { slot.clickSlot() } ) - val fakePlayer = getFakePlayer() - - fakePlayer.inventory.armorInventory = - slot.armor.map { it?.copy()?.removeEnchants() }.reversed().toTypedArray() - - val playerColor = if (!slot.isInCurrentPage()) { - scale *= 0.9 - Color.GRAY.withAlpha(100) - } else null - - val playerRenderable = Renderable.fakePlayer( - fakePlayer, - followMouse = config.eyesFollowMouse, - width = containerWidth, - height = containerHeight, - entityScale = scale.toInt(), - padding = 0, - color = playerColor, - ) + val playerRenderable = createFakePlayerRenderable(slot, playerWidth, containerHeight, containerWidth) Renderable.doubleLayered(playerBackground, playerRenderable, false) } @@ -399,7 +421,7 @@ object CustomWardrobe { ) } - private fun addSlotHoverableButtons(wardrobeSlot: WardrobeAPI.WardrobeSlot): Renderable { + private fun addSlotHoverableButtons(wardrobeSlot: WardrobeSlot): Renderable { val list = mutableListOf() val textScale = 1.5 * (activeScale / 100.0) list.add( @@ -534,7 +556,7 @@ object CustomWardrobe { onHover = { onHover() } ) - private fun WardrobeAPI.WardrobeSlot.clickSlot() { + private fun WardrobeSlot.clickSlot() { val previousPageSlot = 45 val nextPageSlot = 53 val wardrobePage = WardrobeAPI.currentPage ?: return @@ -556,7 +578,7 @@ object CustomWardrobe { update() } - private fun WardrobeAPI.WardrobeSlot.getSlotColor(): Color = with(config.color) { + private fun WardrobeSlot.getSlotColor(): Color = with(config.color) { when { isCurrentSlot() -> equippedColor favorite -> favoriteColor @@ -566,5 +588,5 @@ object CustomWardrobe { .transformIf({ locked || isEmpty() }) { darker(0.2) }.addAlpha(100) } - fun isEnabled() = LorenzUtils.inSkyBlock && WardrobeAPI.inWardrobe() && config.enabled + fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled && WardrobeAPI.inWardrobe() } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt index 38ef9f8161c6..59660fdc4ade 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt @@ -3,19 +3,18 @@ package at.hannibal2.skyhanni.features.inventory.wardrobe import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.events.LorenzToolTipEvent +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.utils.LorenzUtils import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -class EstimatedWardrobePrice { +@SkyHanniModule +object EstimatedWardrobePrice { private val config get() = SkyHanniMod.feature.inventory.estimatedItemValues @SubscribeEvent fun onTooltip(event: LorenzToolTipEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!config.armor) return - if (!WardrobeAPI.inWardrobe()) return - if (WardrobeAPI.inCustomWardrobe) return + if (!isEnabled()) return val slot = WardrobeAPI.slots.firstOrNull { event.slot.slotNumber == it.inventorySlot && it.isInCurrentPage() @@ -32,6 +31,8 @@ class EstimatedWardrobePrice { tooltip.addAll(index, lore) } + private fun isEnabled() = LorenzUtils.inSkyBlock && config.armor && WardrobeAPI.inWardrobe() + @SubscribeEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { event.move(3, "misc.estimatedIemValueArmor", "misc.estimatedItemValues.armor") diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt index a4e9228da80f..278f32da0e69 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt @@ -53,47 +53,7 @@ object WardrobeAPI { var slots = listOf() var inCustomWardrobe = false - class WardrobeSlot( - val id: Int, - val page: Int, - val inventorySlot: Int, - val helmetSlot: Int, - val chestplateSlot: Int, - val leggingsSlot: Int, - val bootsSlot: Int, - ) { - fun getData() = storage?.data?.getOrPut(id) { - WardrobeData( - id, - armor = emptyArmor(), - locked = true, - favorite = false, - ) - } - - var locked: Boolean - get() = getData()?.locked ?: true - set(value) { - getData()?.locked = value - } - - var favorite: Boolean - get() = getData()?.favorite ?: false - set(value) { - getData()?.favorite = value - } - -// val armor get() = (1..4).associateWith { getData()?.armor?.get(it) }.toSortedMap().values.toList() - val armor get() = getData()?.armor ?: emptyArmor() - - fun isEmpty(): Boolean = armor.all { it == null } - - fun isCurrentSlot() = getData()?.id == currentSlot - - fun isInCurrentPage() = (currentPage == null && page == 1) || (page == currentPage) - } - - private fun emptyArmor(): List = listOf(null, null, null, null) + internal fun emptyArmor(): List = listOf(null, null, null, null) var currentSlot: Int? get() = storage?.currentSlot @@ -131,10 +91,12 @@ object WardrobeAPI { if (slot.isEmpty()) return@buildList add("§aEstimated Armor Value:") var totalPrice = 0.0 - for (stack in slot.armor.filterNotNull()) { - val price = EstimatedItemValueCalculator.getTotalPrice(stack) - add(" §7- ${stack.name}: §6${NumberUtil.format(price)}") - totalPrice += price + slot.armor.forEach { + if (it != null) { + val price = EstimatedItemValueCalculator.getTotalPrice(it) + add(" §7- ${it.name}: §6${NumberUtil.format(price)}") + totalPrice += price + } } if (totalPrice != 0.0) add(" §aTotal Value: §6§l${NumberUtil.format(totalPrice)} coins") } @@ -146,7 +108,6 @@ object WardrobeAPI { inventoryPattern.matchMatcher(event.inventoryName) { currentPage = group("currentPage").formatInt() } ?: return - if (currentPage == null) return val itemsList = event.inventoryItems @@ -167,6 +128,13 @@ object WardrobeAPI { } else return } + val foundCurrentSlot = processSlots(slots, itemsList) + if (!foundCurrentSlot && getWardrobeSlotFromId(currentSlot)?.page == currentPage) { + currentSlot = null + } + } + + private fun processSlots(slots: List, itemsList: Map): Boolean { var foundCurrentSlot = false for (slot in slots.filter { it.isInCurrentPage() }) { @@ -183,13 +151,13 @@ object WardrobeAPI { slot.locked = (itemsList[slot.inventorySlot] == ItemStack(Items.dye, EnumDyeColor.RED.dyeDamage)) if (slot.locked) slots.forEach { if (it.id > slot.id) it.locked = true } } - if (!foundCurrentSlot && getWardrobeSlotFromId(currentSlot)?.page == currentPage) { - currentSlot = null - } + + return foundCurrentSlot } @SubscribeEvent fun onInventoryClose(event: InventoryCloseEvent) { + if (!inCustomWardrobe) return DelayedRun.runDelayed(500.milliseconds) { if (!inWardrobe()) currentPage = null } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt new file mode 100644 index 000000000000..8a8e6ab4085a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt @@ -0,0 +1,40 @@ +package at.hannibal2.skyhanni.features.inventory.wardrobe + +class WardrobeSlot( + val id: Int, + val page: Int, + val inventorySlot: Int, + val helmetSlot: Int, + val chestplateSlot: Int, + val leggingsSlot: Int, + val bootsSlot: Int, +) { + fun getData() = WardrobeAPI.storage?.data?.getOrPut(id) { + WardrobeAPI.WardrobeData( + id, + armor = WardrobeAPI.emptyArmor(), + locked = true, + favorite = false, + ) + } + + var locked: Boolean + get() = getData()?.locked ?: true + set(value) { + getData()?.locked = value + } + + var favorite: Boolean + get() = getData()?.favorite ?: false + set(value) { + getData()?.favorite = value + } + + val armor get() = getData()?.armor ?: WardrobeAPI.emptyArmor() + + fun isEmpty(): Boolean = armor.all { it == null } + + fun isCurrentSlot() = getData()?.id == WardrobeAPI.currentSlot + + fun isInCurrentPage() = (WardrobeAPI.currentPage == null && page == 1) || (page == WardrobeAPI.currentPage) +} From b1ea1863abfccfcbdb2e3a90a3c0ca0c2413d2fd Mon Sep 17 00:00:00 2001 From: Empa <42304516+ItsEmpa@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:55:33 +0200 Subject: [PATCH 08/11] fix second page Signed-off-by: Empa <42304516+ItsEmpa@users.noreply.github.com> --- .../skyhanni/features/inventory/wardrobe/CustomWardrobe.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index 78e7fffb64fb..f4e624cbe8a4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -106,6 +106,7 @@ object CustomWardrobe { DelayedRun.runDelayed(500.milliseconds) { if (!WardrobeAPI.inWardrobe()) { reset() + WardrobeAPI.currentPage = null } } } From 7da600cc01aead4e1f6816fb85b2e517609ab302 Mon Sep 17 00:00:00 2001 From: Empa <42304516+ItsEmpa@users.noreply.github.com> Date: Sun, 9 Jun 2024 13:03:31 +0200 Subject: [PATCH 09/11] fix github action crying? Signed-off-by: Empa <42304516+ItsEmpa@users.noreply.github.com> --- .../inventory/wardrobe/CustomWardrobe.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index f4e624cbe8a4..6cba78853fb2 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -64,8 +64,11 @@ object CustomWardrobe { if (screenSize != lastScreenSize) { lastScreenSize = screenSize - val didUpdate = updateScreenSize(screenSize) - if (didUpdate) return + val shouldUpdate = updateScreenSize(screenSize) + if (shouldUpdate) { + update() + return + } } val (width, height) = renderable.width to renderable.height @@ -151,10 +154,8 @@ object CustomWardrobe { val maxScale = min(autoScaleWidth, autoScaleHeight).toInt() activeScale = config.spacing.globalScale.get().coerceAtMost(maxScale) - return if (activeScale != previousActiveScale) { - update() - true - } else false + + return activeScale != previousActiveScale } private fun createWarning(list: List): Pair> { @@ -183,7 +184,7 @@ object CustomWardrobe { private fun createArmorTooltipRenderable( slot: WardrobeSlot, containerHeight: Int, - containerWidth: Int + containerWidth: Int, ): Renderable { val loreList = mutableListOf() val height = containerHeight - 3 @@ -217,7 +218,7 @@ object CustomWardrobe { slot: WardrobeSlot, playerWidth: Double, containerHeight: Int, - containerWidth: Int + containerWidth: Int, ): Renderable { val fakePlayer = getFakePlayer() var scale = playerWidth From cbabb21964546a5abd7091544f449ab02a9781c1 Mon Sep 17 00:00:00 2001 From: Empa <42304516+ItsEmpa@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:12:40 +0200 Subject: [PATCH 10/11] a bunch of fixes Signed-off-by: Empa <42304516+ItsEmpa@users.noreply.github.com> --- .../inventory/wardrobe/CustomWardrobe.kt | 5 ++- .../wardrobe/EstimatedWardrobePrice.kt | 3 +- .../inventory/wardrobe/WardrobeAPI.kt | 32 +++++++++++++------ .../skyhanni/utils/InventoryUtils.kt | 2 ++ .../utils/renderables/RenderableTooltips.kt | 2 +- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index 6cba78853fb2..a55cc5cd2a6c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -39,7 +39,7 @@ import kotlin.time.Duration.Companion.milliseconds @SkyHanniModule object CustomWardrobe { - private val config get() = SkyHanniMod.feature.inventory.customWardrobe + val config get() = SkyHanniMod.feature.inventory.customWardrobe private var displayRenderable: Renderable? = null private var inventoryButton: Renderable? = null @@ -106,10 +106,9 @@ object CustomWardrobe { fun onInventoryClose(event: InventoryCloseEvent) { waitingForInventoryUpdate = false if (!isEnabled()) return - DelayedRun.runDelayed(500.milliseconds) { + DelayedRun.runDelayed(250.milliseconds) { if (!WardrobeAPI.inWardrobe()) { reset() - WardrobeAPI.currentPage = null } } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt index 59660fdc4ade..d55b30cf1dbf 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/EstimatedWardrobePrice.kt @@ -31,7 +31,8 @@ object EstimatedWardrobePrice { tooltip.addAll(index, lore) } - private fun isEnabled() = LorenzUtils.inSkyBlock && config.armor && WardrobeAPI.inWardrobe() + private fun isEnabled() = + LorenzUtils.inSkyBlock && config.armor && WardrobeAPI.inWardrobe() && !WardrobeAPI.inCustomWardrobe @SubscribeEvent fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt index 278f32da0e69..f10f81764757 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.inventory.wardrobe import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.events.DebugDataCollectEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent import at.hannibal2.skyhanni.events.InventoryUpdatedEvent import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValueCalculator import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule @@ -62,6 +63,7 @@ object WardrobeAPI { } var currentPage: Int? = null + private var inWardrobe = false init { val list = mutableListOf() @@ -85,27 +87,34 @@ object WardrobeAPI { private fun getWardrobeSlotFromId(id: Int?) = slots.find { it.id == id } - fun inWardrobe() = inventoryPattern.matches(InventoryUtils.openInventoryName()) + fun inWardrobe() = InventoryUtils.inInventory() && inWardrobe fun createPriceLore(slot: WardrobeSlot) = buildList { if (slot.isEmpty()) return@buildList add("§aEstimated Armor Value:") var totalPrice = 0.0 - slot.armor.forEach { - if (it != null) { - val price = EstimatedItemValueCalculator.getTotalPrice(it) - add(" §7- ${it.name}: §6${NumberUtil.format(price)}") - totalPrice += price - } + for (stack in slot.armor.filterNotNull()) { + val price = EstimatedItemValueCalculator.getTotalPrice(stack) + add(" §7- ${stack.name}: §6${NumberUtil.format(price)}") + totalPrice += price } if (totalPrice != 0.0) add(" §aTotal Value: §6§l${NumberUtil.format(totalPrice)} coins") } + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + inventoryPattern.matches(event.inventoryName).let { + inWardrobe = it + if (CustomWardrobe.config.enabled) inCustomWardrobe = it + } + } + @SubscribeEvent fun onInventoryUpdate(event: InventoryUpdatedEvent) { if (!LorenzUtils.inSkyBlock) return inventoryPattern.matchMatcher(event.inventoryName) { + inWardrobe = true currentPage = group("currentPage").formatInt() } ?: return @@ -157,9 +166,12 @@ object WardrobeAPI { @SubscribeEvent fun onInventoryClose(event: InventoryCloseEvent) { - if (!inCustomWardrobe) return - DelayedRun.runDelayed(500.milliseconds) { - if (!inWardrobe()) currentPage = null + if (!inWardrobe) return + DelayedRun.runDelayed(250.milliseconds) { + if (!inventoryPattern.matches(InventoryUtils.openInventoryName())) { + inWardrobe = false + currentPage = null + } } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt index 8e1fff3efd4c..53ee6cf7a4ce 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt @@ -34,6 +34,8 @@ object InventoryUtils { } else "" } + fun inInventory() = Minecraft.getMinecraft().currentScreen is GuiChest + fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim() fun getWindowId(): Int? = (Minecraft.getMinecraft().currentScreen as? GuiChest)?.inventorySlots?.windowId diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt index 7fdaba1659f1..0d2c887854ae 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt @@ -75,7 +75,7 @@ object RenderableTooltips { RenderHelper.disableStandardItemLighting() GlStateManager.enableDepth() - val zLevel = 300f + val zLevel = 400f GlStateManager.translate(tooltipX.toFloat(), tooltipY.toFloat(), zLevel) RenderUtils.drawGradientRect( From 7340b1963e3e18b278d67d2f0cc6e333128b0956 Mon Sep 17 00:00:00 2001 From: Empa <42304516+ItsEmpa@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:24:54 +0200 Subject: [PATCH 11/11] surely it will stop crying now Signed-off-by: Empa <42304516+ItsEmpa@users.noreply.github.com> --- .../inventory/wardrobe/CustomWardrobe.kt | 16 +++++++++------- .../features/inventory/wardrobe/WardrobeAPI.kt | 6 ++---- .../features/inventory/wardrobe/WardrobeSlot.kt | 2 ++ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt index a55cc5cd2a6c..243b3132fdad 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/CustomWardrobe.kt @@ -456,9 +456,10 @@ object CustomWardrobe { "§2$", scale = textScale, horizontalAlign = HorizontalAlignment.CENTER, - verticalAlign = VerticalAlignment.CENTER - ), lore - ) + verticalAlign = VerticalAlignment.CENTER, + ), + lore, + ), ) } @@ -535,8 +536,9 @@ object CustomWardrobe { Renderable.doubleLayered( Renderable.clickable( hoveredRenderable, - onClick - ), topLayerRenderable + onClick, + ), + topLayerRenderable, ), hoveredColor, padding = padding, @@ -545,7 +547,7 @@ object CustomWardrobe { borderOutlineThickness = borderOutlineThickness, blur = borderOutlineBlur, horizontalAlign = horizontalAlignment, - verticalAlign = verticalAlignment + verticalAlign = verticalAlignment, ), Renderable.drawInsideRoundedRect( unhoveredRenderable, @@ -554,7 +556,7 @@ object CustomWardrobe { horizontalAlign = horizontalAlignment, verticalAlign = verticalAlignment ), - onHover = { onHover() } + onHover = { onHover() }, ) private fun WardrobeSlot.clickSlot() { diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt index f10f81764757..013aa1866f88 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeAPI.kt @@ -125,10 +125,8 @@ object WardrobeAPI { } if (allGrayDye) { - val allSlotsEmpty = slots.all { - (getWardrobeItem(itemsList[it.helmetSlot]) == null && getWardrobeItem(itemsList[it.chestplateSlot]) == null && - getWardrobeItem(itemsList[it.leggingsSlot]) == null && getWardrobeItem(itemsList[it.bootsSlot]) == null) || - !it.isInCurrentPage() + val allSlotsEmpty = slots.filter { it.isInCurrentPage() }.all { slot -> + (slot.inventorySlots.all { getWardrobeItem(itemsList[it]) == null }) } if (allSlotsEmpty) { for (slot in slots.filter { it.isInCurrentPage() }) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt index 8a8e6ab4085a..e500887f984e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/wardrobe/WardrobeSlot.kt @@ -32,6 +32,8 @@ class WardrobeSlot( val armor get() = getData()?.armor ?: WardrobeAPI.emptyArmor() + val inventorySlots = listOf(helmetSlot, chestplateSlot, leggingsSlot, bootsSlot) + fun isEmpty(): Boolean = armor.all { it == null } fun isCurrentSlot() = getData()?.id == WardrobeAPI.currentSlot