aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorEmpa <42304516+ItsEmpa@users.noreply.github.com>2024-09-07 20:59:56 +0200
committerGitHub <noreply@github.com>2024-09-07 20:59:56 +0200
commitf40863a821218938b8f53f17a4441ad5c973d0e3 (patch)
tree7fad36578e589dafa9cc828c51088fae9cc4834e /src/main
parente3b39759ad89a91dda2ef0549d0a62b58598ec1c (diff)
downloadskyhanni-f40863a821218938b8f53f17a4441ad5c973d0e3.tar.gz
skyhanni-f40863a821218938b8f53f17a4441ad5c973d0e3.tar.bz2
skyhanni-f40863a821218938b8f53f17a4441ad5c973d0e3.zip
Feature: Personal Compactor Overlay (#1869)
Co-authored-by: CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> Co-authored-by: Cal <cwolfson58@gmail.com> Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Co-authored-by: ItsEmpa <itsempa@users.noreply.github.com>
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/inventory/PersonalCompactorConfig.java51
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/PersonalCompactorOverlay.kt134
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt78
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableInventory.kt120
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt56
-rw-r--r--src/main/resources/assets/skyhanni/gui/slot.pngbin0 -> 314 bytes
10 files changed, 444 insertions, 34 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 6c43591a5..dfb8f1f9c 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
@@ -74,6 +74,11 @@ public class InventoryConfig {
public HideNotClickableConfig hideNotClickable = new HideNotClickableConfig();
@Expose
+ @ConfigOption(name = "Personal Compactor Overlay", desc = "Overlay for the Personal Compactor and Deletor.")
+ @Accordion
+ public PersonalCompactorConfig personalCompactor = new PersonalCompactorConfig();
+
+ @Expose
@ConfigOption(name = "RNG Meter", desc = "")
@Accordion
public RngMeterConfig rngMeter = new RngMeterConfig();
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/PersonalCompactorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/PersonalCompactorConfig.java
new file mode 100644
index 000000000..3ded2e812
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/PersonalCompactorConfig.java
@@ -0,0 +1,51 @@
+package at.hannibal2.skyhanni.config.features.inventory;
+
+import at.hannibal2.skyhanni.config.FeatureToggle;
+import com.google.gson.annotations.Expose;
+import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorKeybind;
+import io.github.notenoughupdates.moulconfig.annotations.ConfigOption;
+import org.lwjgl.input.Keyboard;
+
+public class PersonalCompactorConfig {
+
+ @Expose
+ @ConfigOption(name = "Enabled", desc = "Enable showing what items are inside your personal compactor/deletor.")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean enabled = true;
+
+ @Expose
+ @ConfigOption(name = "Visibility Mode", desc = "Choose when to show the overlay.")
+ @ConfigEditorDropdown
+ public VisibilityMode visibilityMode = VisibilityMode.EXCEPT_KEYBIND;
+
+ public enum VisibilityMode {
+ ALWAYS("Always"),
+ KEYBIND("Keybind Held"),
+ EXCEPT_KEYBIND("Except Keybind Held"),
+ ;
+
+ private final String name;
+
+ VisibilityMode(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ @Expose
+ @ConfigOption(name = "Keybind", desc = "The keybind to hold to show the overlay.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_LSHIFT)
+ public int keybind = Keyboard.KEY_LSHIFT;
+
+ @Expose
+ @ConfigOption(name = "Show On/Off", desc = "Show whether the Personal Compactor/Deletor is currently turned on or off.")
+ @ConfigEditorBoolean
+ public boolean showToggle = true;
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
index 43448f8d8..1af2c8c88 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/ItemDisplayOverlayFeatures.kt
@@ -251,7 +251,7 @@ object ItemDisplayOverlayFeatures {
}
}
- if (VACUUM_GARDEN.isSelected() && internalName in PestAPI.vacuumVariants && isOwnVacuum(lore)) {
+ if (VACUUM_GARDEN.isSelected() && internalName in PestAPI.vacuumVariants && isOwnItem(lore)) {
lore.matchFirst(gardenVacuumPatterm) {
val pests = group("amount").formatLong()
return if (config.vacuumBagCap) {
@@ -319,8 +319,13 @@ object ItemDisplayOverlayFeatures {
return null
}
- private fun isOwnVacuum(lore: List<String>) =
- lore.none { it.contains("Click to trade!") || it.contains("Starting bid:") || it.contains("Buy it now:") }
+ fun isOwnItem(lore: List<String>) =
+ lore.none {
+ it.contains("Click to trade!") ||
+ it.contains("Starting bid:") ||
+ it.contains("Buy it now:") ||
+ it.contains("Click to inspect")
+ }
var done = false
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/PersonalCompactorOverlay.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/PersonalCompactorOverlay.kt
new file mode 100644
index 000000000..7c6deb255
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/PersonalCompactorOverlay.kt
@@ -0,0 +1,134 @@
+package at.hannibal2.skyhanni.features.inventory
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.features.inventory.PersonalCompactorConfig
+import at.hannibal2.skyhanni.events.InventoryCloseEvent
+import at.hannibal2.skyhanni.events.InventoryUpdatedEvent
+import at.hannibal2.skyhanni.events.LorenzToolTipEvent
+import at.hannibal2.skyhanni.events.RenderItemTipEvent
+import at.hannibal2.skyhanni.events.RenderObject
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
+import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUItems.getInternalNameFromHypixelId
+import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
+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.SkyBlockItemModifierUtils.getAttributeString
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getItemUuid
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPersonalCompactorActive
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import at.hannibal2.skyhanni.utils.renderables.RenderableInventory
+import at.hannibal2.skyhanni.utils.renderables.RenderableTooltips
+import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
+import net.minecraft.item.ItemStack
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+@SkyHanniModule
+object PersonalCompactorOverlay {
+
+ private val config get() = SkyHanniMod.feature.inventory.personalCompactor
+
+ private val group = RepoPattern.group("inventory.personalcompactor")
+ private val internalNamePattern by group.pattern(
+ "internalname",
+ "PERSONAL_(?<type>[^_]+)_(?<tier>\\d+)",
+ )
+
+ private val slotsMap = mapOf(
+ 7000 to 12,
+ 6000 to 7,
+ 5000 to 3,
+ 4000 to 1
+ )
+
+ private const val MAX_ITEMS_PER_ROW = 7
+
+ private val compactorRenderableMap = mutableMapOf<String, Renderable>()
+ private val compactorEnabledMap = mutableMapOf<String, Boolean>()
+
+ @SubscribeEvent
+ fun onTooltip(event: LorenzToolTipEvent) {
+ if (!isEnabled()) return
+ if (!shouldShow()) return
+
+ val itemStack = event.itemStack
+ val internalName = itemStack.getInternalName()
+ val name = event.toolTip.firstOrNull() ?: return
+ val (type, tier) = internalNamePattern.matchMatcher(internalName.asString()) {
+ group("type") to group("tier").formatInt()
+ } ?: return
+
+ val prefix = when (type) {
+ "COMPACTOR" -> "personal_compact_"
+ "DELETOR" -> "personal_deletor_"
+ else -> return
+ }
+
+ val uuid = itemStack.getItemUuid() ?: return
+ val enabled = getPersonalCompactorEnabled(itemStack) ?: return
+
+ val fakeInventory = compactorRenderableMap.getOrPut(uuid) {
+ val slots = slotsMap[tier] ?: return
+ val itemList = (0 until slots).map { slot ->
+ val skyblockId = itemStack.getAttributeString(prefix + slot)
+ skyblockId?.let { getInternalNameFromHypixelId(it) }?.getItemStack()
+ }
+
+ RenderableInventory.fakeInventory(itemList, MAX_ITEMS_PER_ROW, 1.0)
+ }
+
+ val title = Renderable.string(name)
+ val status = Renderable.string(
+ "§7Status: " + if (enabled) "§aEnabled" else "§cDisabled"
+ )
+
+ RenderableTooltips.setTooltipForRender(listOf(title, status, fakeInventory), spacedTitle = true)
+ event.cancel()
+ }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: InventoryCloseEvent) {
+ compactorRenderableMap.clear()
+ }
+
+ @SubscribeEvent
+ fun onInventoryUpdate(event: InventoryUpdatedEvent) {
+ compactorEnabledMap.clear()
+ }
+
+ @SubscribeEvent
+ fun onRenderItemTip(event: RenderItemTipEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (!config.showToggle) return
+ val itemStack = event.stack
+ val internalName = itemStack.getInternalNameOrNull() ?: return
+ if (!internalNamePattern.matches(internalName.asString())) return
+
+ val enabled = getPersonalCompactorEnabled(itemStack) ?: return
+ val text = if (enabled) "§a✔" else "§c✖"
+ val renderObject = RenderObject(
+ text,
+ -8,
+ -10
+ )
+ event.renderObjects.add(renderObject)
+ }
+
+ private fun shouldShow() = when (config.visibilityMode) {
+ PersonalCompactorConfig.VisibilityMode.ALWAYS -> true
+ PersonalCompactorConfig.VisibilityMode.KEYBIND -> config.keybind.isKeyHeld()
+ PersonalCompactorConfig.VisibilityMode.EXCEPT_KEYBIND -> !config.keybind.isKeyHeld()
+ else -> false
+ }
+
+ private fun getPersonalCompactorEnabled(itemStack: ItemStack): Boolean? {
+ val uuid = itemStack.getItemUuid() ?: return null
+ return compactorEnabledMap.getOrPut(uuid) { itemStack.getPersonalCompactorActive() }
+ }
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
index 82dbb7349..c271ef66c 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -16,6 +16,7 @@ import at.hannibal2.skyhanni.utils.NumberUtil.isInt
import at.hannibal2.skyhanni.utils.PrimitiveItemStack.Companion.makePrimitiveStack
import at.hannibal2.skyhanni.utils.json.BaseGsonBuilder
import at.hannibal2.skyhanni.utils.json.fromJson
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getItemId
import at.hannibal2.skyhanni.utils.system.PlatformUtils
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
@@ -169,6 +170,16 @@ object NEUItems {
fun getInternalNameOrNull(nbt: NBTTagCompound): NEUInternalName? =
ItemResolutionQuery(manager).withItemNBT(nbt).resolveInternalName()?.asInternalName()
+ fun getInternalNameFromHypixelIdOrNull(hypixelId: String): NEUInternalName? {
+ val internalName = hypixelId.replace(':', '-')
+ return internalName.asInternalName().takeIf { it.getItemStackOrNull()?.getItemId() == internalName }
+ }
+
+ fun getInternalNameFromHypixelId(hypixelId: String): NEUInternalName =
+ getInternalNameFromHypixelIdOrNull(hypixelId)
+ ?: error("hypixel item id does not match internal name: $hypixelId")
+
+
@Deprecated("Moved to ItemPriceUtils", ReplaceWith(""))
fun NEUInternalName.getPrice(
priceSource: ItemPriceSource = ItemPriceSource.BAZAAR_INSTANT_BUY,
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
index b39493741..c9e193329 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
@@ -191,6 +191,8 @@ object SkyBlockItemModifierUtils {
fun ItemStack.getNewYearCake() = getAttributeInt("new_years_cake")
+ fun ItemStack.getPersonalCompactorActive() = getAttributeByte("PERSONAL_DELETOR_ACTIVE") == 1.toByte()
+
fun ItemStack.getEnchantments(): Map<String, Int>? = getExtraAttributes()
?.takeIf { it.hasKey("enchantments") }
?.run {
@@ -253,7 +255,7 @@ object SkyBlockItemModifierUtils {
list
}
- private fun ItemStack.getAttributeString(label: String) =
+ fun ItemStack.getAttributeString(label: String) =
getExtraAttributes()?.getString(label)?.takeUnless { it.isBlank() }
private fun ItemStack.getAttributeInt(label: String) =
@@ -262,9 +264,11 @@ object SkyBlockItemModifierUtils {
private fun ItemStack.getAttributeLong(label: String) =
getExtraAttributes()?.getLong(label)?.takeUnless { it == 0L }
- private fun ItemStack.getAttributeBoolean(label: String): Boolean {
- return getExtraAttributes()?.getBoolean(label) ?: false
- }
+ private fun ItemStack.getAttributeBoolean(label: String) =
+ getExtraAttributes()?.getBoolean(label) ?: false
+
+ private fun ItemStack.getAttributeByte(label: String) =
+ getExtraAttributes()?.getByte(label) ?: 0
fun ItemStack.getExtraAttributes() = tagCompound?.getCompoundTag("ExtraAttributes")
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 a49f58b00..91abc636d 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
@@ -201,6 +201,7 @@ interface Renderable {
highlightsOnHoverSlots: List<Int> = listOf(),
stack: ItemStack? = null,
color: LorenzColor? = null,
+ spacedTitle: Boolean = false,
bypassChecks: Boolean = false,
snapsToTopIfToLong: Boolean = true,
condition: () -> Boolean = { true },
@@ -231,6 +232,7 @@ interface Renderable {
stack = stack,
borderColor = color,
snapsToTopIfToLong = snapsToTopIfToLong,
+ spacedTitle = spacedTitle,
)
GlStateManager.popMatrix()
}
@@ -839,6 +841,25 @@ interface Renderable {
}
}
+ fun paddingContainer(
+ content: Renderable,
+ topSpacing: Int = 0,
+ bottomSpacing: Int = 0,
+ leftSpacing: Int = 0,
+ rightSpacing: Int = 0,
+ ) = object : Renderable {
+ override val width = content.width + leftSpacing + rightSpacing
+ override val height = content.height + topSpacing + bottomSpacing
+ override val horizontalAlign = content.horizontalAlign
+ override val verticalAlign = content.verticalAlign
+
+ override fun render(posX: Int, posY: Int) {
+ GlStateManager.translate(leftSpacing.toFloat(), topSpacing.toFloat(), 0f)
+ content.render(posX + leftSpacing, posY + topSpacing)
+ GlStateManager.translate(-leftSpacing.toFloat(), -topSpacing.toFloat(), 0f)
+ }
+ }
+
fun scrollList(
list: List<Renderable>,
height: Int,
@@ -1063,11 +1084,56 @@ interface Renderable {
}
}
+ fun drawInsideFixedSizedImage(
+ input: Renderable,
+ texture: ResourceLocation,
+ width: Int = input.width,
+ height: Int = input.height,
+ alpha: Int = 255,
+ padding: Int = 2,
+ uMin: Float = 0f,
+ uMax: Float = 1f,
+ vMin: Float = 0f,
+ vMax: Float = 1f,
+ horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
+ verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
+ ) = object : Renderable {
+ override val width = width
+ override val height = height
+ override val horizontalAlign = horizontalAlign
+ override val verticalAlign = verticalAlign
+
+ override fun render(posX: Int, posY: Int) {
+ Minecraft.getMinecraft().textureManager.bindTexture(texture)
+ GlStateManager.color(1f, 1f, 1f, alpha / 255f)
+ Utils.drawTexturedRect(
+ 0f,
+ 0f,
+ width.toFloat(),
+ height.toFloat(),
+ uMin,
+ uMax,
+ vMin,
+ vMax,
+ GL11.GL_NEAREST
+ )
+ GlStateManager.color(1f, 1f, 1f, 1f)
+
+ GlStateManager.translate(padding.toFloat(), padding.toFloat(), 0f)
+ input.render(posX + padding, posY + padding)
+ GlStateManager.translate(-padding.toFloat(), -padding.toFloat(), 0f)
+ }
+ }
+
fun image(
texture: ResourceLocation,
width: Int,
height: Int,
alpha: Int = 255,
+ uMin: Float = 0f,
+ uMax: Float = 1f,
+ vMin: Float = 0f,
+ vMax: Float = 1f,
horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
) = object : Renderable {
@@ -1079,7 +1145,17 @@ interface Renderable {
override fun render(posX: Int, posY: Int) {
Minecraft.getMinecraft().textureManager.bindTexture(texture)
GlStateManager.color(1f, 1f, 1f, alpha / 255f)
- Utils.drawTexturedRect(0f, 0f, width.toFloat(), height.toFloat(), GL11.GL_NEAREST)
+ Utils.drawTexturedRect(
+ 0f,
+ 0f,
+ width.toFloat(),
+ height.toFloat(),
+ uMin,
+ uMax,
+ vMin,
+ vMax,
+ GL11.GL_NEAREST
+ )
GlStateManager.color(1f, 1f, 1f, 1f)
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableInventory.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableInventory.kt
new file mode 100644
index 000000000..6f783a485
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableInventory.kt
@@ -0,0 +1,120 @@
+package at.hannibal2.skyhanni.utils.renderables
+
+import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
+import at.hannibal2.skyhanni.utils.RenderUtils.VerticalAlignment
+import net.minecraft.item.ItemStack
+import net.minecraft.util.ResourceLocation
+import kotlin.math.ceil
+
+object RenderableInventory {
+
+ private val inventoryTextures by lazy { ResourceLocation("skyhanni", "gui/slot.png") }
+ private const val TEXTURE_WIDTH = 90
+ private const val TEXTURE_HEIGHT = 54
+
+ private enum class SlotsUv(val uMin: Int, val uMax: Int, val vMin: Int, val vMax: Int) {
+ TOP_LEFT_CORNER(14, 18, 32, 36),
+ TOP_BORDER(18, 36, 32, 36),
+ TOP_RIGHT_CORNER(36, 40, 32, 36),
+ LEFT_BORDER(68, 72, 18, 36),
+ CENTER(0, 18, 0, 18),
+ RIGHT_BORDER(72, 76, 18, 36),
+ BOTTOM_LEFT_CORNER(14, 18, 36, 40),
+ BOTTOM_BORDER(18, 36, 36, 40),
+ BOTTOM_RIGHT_CORNER(36, 40, 36, 40),
+ HALF_EMPTY(54, 63, 0, 18),
+ EMPTY(18, 36, 0, 18),
+ ;
+
+ fun getUvCoords(): FloatArray {
+ return floatArrayOf(
+ (uMin.toFloat() / TEXTURE_WIDTH),
+ (uMax.toFloat() / TEXTURE_WIDTH),
+ (vMin.toFloat() / TEXTURE_HEIGHT),
+ (vMax.toFloat() / TEXTURE_HEIGHT),
+ )
+ }
+
+ fun height() = vMax - vMin
+ fun width() = uMax - uMin
+ }
+
+ private fun createUvList(size: Int, maxSize: Int) = buildList {
+ val length = if (size >= maxSize) maxSize else size
+ val lastLength = if (size % maxSize == 0) maxSize else size % maxSize
+ val isWeird = lastLength % 2 != length % 2
+
+ val rows = ceil(size.toDouble() / maxSize).toInt()
+
+ for (i in 0 until rows + 2) {
+ val row = mutableListOf<SlotsUv>()
+ if (i == 0) { // top border
+ row.add(SlotsUv.TOP_LEFT_CORNER)
+ row.addAll(List(length) { SlotsUv.TOP_BORDER })
+ row.add(SlotsUv.TOP_RIGHT_CORNER)
+ } else if (i == rows + 1) { // last border
+ row.add(SlotsUv.BOTTOM_LEFT_CORNER)
+ row.addAll(List(length) { SlotsUv.BOTTOM_BORDER })
+ row.add(SlotsUv.BOTTOM_RIGHT_CORNER)
+ } else if (i == rows && rows != 1) { // last row
+ val spaces = if (isWeird) (length - lastLength) - 1 else length - lastLength
+ row.add(SlotsUv.LEFT_BORDER)
+ row.addAll(List(spaces / 2) { SlotsUv.EMPTY })
+ if (isWeird) row.add(SlotsUv.HALF_EMPTY)
+ row.addAll(List(lastLength) { SlotsUv.CENTER })
+ if (isWeird) row.add(SlotsUv.HALF_EMPTY)
+ row.addAll(List(spaces / 2) { SlotsUv.EMPTY })
+ row.add(SlotsUv.RIGHT_BORDER)
+ } else {
+ row.add(SlotsUv.LEFT_BORDER)
+ row.addAll(List(length) { SlotsUv.CENTER })
+ row.add(SlotsUv.RIGHT_BORDER)
+ }
+ add(row.toList())
+ }
+ }
+
+ fun fakeInventory(
+ items: List<ItemStack?>,
+ maxRowSize: Int,
+ scale: Double,
+ horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
+ verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
+ ): Renderable {
+ val uvList = createUvList(items.size, maxRowSize)
+ var index = 0
+ val finalList = uvList.map { uvRow ->
+ uvRow.map { uv ->
+ val uvArray = uv.getUvCoords()
+ val renderable = if (uv == SlotsUv.CENTER) {
+ (items[index]?.let { item ->
+ Renderable.itemStack(
+ item,
+ scale,
+ 0,
+ 0,
+ )
+ } ?: Renderable.placeholder((16 * scale).toInt(), (16 * scale).toInt())).also { index++ }
+ } else Renderable.placeholder(0, 0)
+ Renderable.drawInsideFixedSizedImage(
+ renderable,
+ inventoryTextures,
+ (uv.width() * scale).toInt(),
+ (uv.height() * scale).toInt(),
+ padding = scale.toInt(),
+ uMin = uvArray[0],
+ uMax = uvArray[1],
+ vMin = uvArray[2],
+ vMax = uvArray[3],
+ )
+ }
+ }
+
+ return Renderable.verticalContainer(
+ finalList.map { Renderable.horizontalContainer(it, 0) },
+ 0,
+ horizontalAlign = horizontalAlign,
+ verticalAlign = verticalAlign,
+ )
+ }
+}
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 0d2c88785..b37c89bb5 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt
@@ -14,7 +14,6 @@ import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
import net.minecraftforge.fml.common.gameevent.TickEvent.RenderTickEvent
-import java.awt.Color
@SkyHanniModule
object RenderableTooltips {
@@ -35,8 +34,9 @@ object RenderableTooltips {
stack: ItemStack? = null,
borderColor: LorenzColor? = null,
snapsToTopIfToLong: Boolean = true,
+ spacedTitle: Boolean = false
) {
- tooltip = DeferredTooltip(tips, stack, borderColor, snapsToTopIfToLong)
+ tooltip = DeferredTooltip(tips, stack, borderColor, snapsToTopIfToLong, spacedTitle)
}
private fun drawHoveringText() {
@@ -45,9 +45,10 @@ object RenderableTooltips {
if (tips.isEmpty()) return
val x = Utils.getMouseX() + 12
- val y = Utils.getMouseY() - if (tips.size > 1) 2 else -7
- val borderColorStart = Color(tooltip.getBorderColor()).darker().rgb and 0x00FFFFFF or (200 shl 24)
+ val y = Utils.getMouseY() - if (tips.size > 1) 1 else -7
+ val borderColorStart = tooltip.getBorderColor()
val scaled = ScaledResolution(Minecraft.getMinecraft())
+ val isSpacedTitle = tooltip.isSpacedTitle()
val tooltipTextWidth = tips.maxOf { it.width }
val tooltipHeight = tips.sumOf { it.height }
@@ -58,11 +59,11 @@ object RenderableTooltips {
if (tooltip.snapsToTopIfToLong && tooltipHeight + 8 > scaled.scaledHeight)
4 // Snap to Top if to Long
else
- scaled.scaledHeight - tooltipHeight - 4 // Limit Bottom
+ scaled.scaledHeight - tooltipHeight - 6 // Limit Bottom
}
else -> {
- y - 12 // normal
+ y - 10 // normal
}
}
val tooltipX = if (x + tooltipTextWidth + 4 > scaled.scaledWidth) {
@@ -81,19 +82,19 @@ object RenderableTooltips {
RenderUtils.drawGradientRect(
left = -3,
top = -4,
- right = tooltipTextWidth + 3,
+ right = tooltipTextWidth + 2,
bottom = -3,
)
RenderUtils.drawGradientRect(
left = -3,
top = tooltipHeight + 3,
- right = tooltipTextWidth + 3,
+ right = tooltipTextWidth + 2,
bottom = tooltipHeight + 4,
)
RenderUtils.drawGradientRect(
left = -3,
top = -3,
- right = tooltipTextWidth + 3,
+ right = tooltipTextWidth + 2,
bottom = tooltipHeight + 3,
)
RenderUtils.drawGradientRect(
@@ -103,9 +104,9 @@ object RenderableTooltips {
bottom = tooltipHeight + 3,
)
RenderUtils.drawGradientRect(
- left = tooltipTextWidth + 3,
+ left = tooltipTextWidth + 2,
top = -3,
- right = tooltipTextWidth + 4,
+ right = tooltipTextWidth + 3,
bottom = tooltipHeight + 3,
)
val borderColorEnd = borderColorStart and 0xFEFEFE shr 1 or (borderColorStart and -0x1000000)
@@ -118,9 +119,9 @@ object RenderableTooltips {
endColor = borderColorEnd
)
RenderUtils.drawGradientRect(
- left = tooltipTextWidth + 2,
+ left = tooltipTextWidth + 1,
top = -3 + 1,
- right = tooltipTextWidth + 3,
+ right = tooltipTextWidth + 2,
bottom = tooltipHeight + 3 - 1,
startColor = borderColorStart,
endColor = borderColorEnd
@@ -128,7 +129,7 @@ object RenderableTooltips {
RenderUtils.drawGradientRect(
left = -3,
top = -3,
- right = tooltipTextWidth + 3,
+ right = tooltipTextWidth + 2,
bottom = -3 + 1,
startColor = borderColorStart,
endColor = borderColorStart
@@ -136,25 +137,24 @@ object RenderableTooltips {
RenderUtils.drawGradientRect(
left = -3,
top = tooltipHeight + 2,
- right = tooltipTextWidth + 3,
+ right = tooltipTextWidth + 2,
bottom = tooltipHeight + 3,
startColor = borderColorEnd,
endColor = borderColorEnd
)
- GlStateManager.disableDepth()
- GlStateManager.translate(0f, 0f, -zLevel)
+ GlStateManager.translate(-1f, -1f, 0f)
var yTranslateSum = 0
- for (line in tips) {
+ tips.forEachIndexed { index, line ->
line.renderXAligned(tooltipX, tooltipY, tooltipTextWidth)
- val yShift = line.height
+ var yShift = line.height
+ if (index == 0 && isSpacedTitle) yShift += 2
GlStateManager.translate(0f, yShift.toFloat(), 0f)
yTranslateSum += yShift
}
- GlStateManager.translate(-tooltipX.toFloat(), -tooltipY.toFloat() + yTranslateSum.toFloat(), 0f)
+ GlStateManager.translate(-tooltipX.toFloat() + 1, -tooltipY.toFloat() + 1 + yTranslateSum.toFloat(), -zLevel)
GlStateManager.enableLighting()
- GlStateManager.enableDepth()
RenderHelper.enableStandardItemLighting()
GlStateManager.enableRescaleNormal()
GlStateManager.disableLighting()
@@ -164,13 +164,17 @@ object RenderableTooltips {
private data class DeferredTooltip(
val tips: List<Renderable>,
val stack: ItemStack? = null,
- val borderColor: LorenzColor? = null,
+ private val borderColor: LorenzColor? = null,
val snapsToTopIfToLong: Boolean = true,
+ private val spacedTitle: Boolean = false,
) {
- fun getBorderColor(): Int {
- return Minecraft.getMinecraft().fontRendererObj.getColorCode(
- borderColor?.chatColorCode ?: stack?.getLore()?.lastOrNull()?.take(4)?.get(1) ?: 'f'
- )
+ fun getBorderColor(): Int =
+ (borderColor?.chatColorCode ?: stack?.getLore()?.lastOrNull()?.take(4)?.get(1))
+ ?.let { Minecraft.getMinecraft().fontRendererObj.getColorCode(it) }
+ ?: 0x505000FF
+
+ fun isSpacedTitle(): Boolean {
+ return spacedTitle
}
}
diff --git a/src/main/resources/assets/skyhanni/gui/slot.png b/src/main/resources/assets/skyhanni/gui/slot.png
new file mode 100644
index 000000000..7e15b97d1
--- /dev/null
+++ b/src/main/resources/assets/skyhanni/gui/slot.png
Binary files differ