Skip to content

Commit

Permalink
Improvement: Cake Tracker Scrollable and AH Tips (#2939)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidArthurCole authored Dec 5, 2024
1 parent 55c4e40 commit e2c7ca7
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ public class CakeTrackerConfig {
@Expose
@ConfigOption(
name = "Note",
desc = "§cNote7:" +
"\nThis feature is not compatible with the NEU Storage Overlay." +
"\nBackpacks/Ender Chest will not be scanned correctly with it enabled."
desc = "This feature is not compatible with the NEU Storage Overlay." +
"Backpacks/Ender Chest will not be scanned correctly with it enabled."
)
@ConfigEditorInfoText
public boolean incompatibleNote = false;
Expand Down Expand Up @@ -73,9 +72,9 @@ public enum CakeTrackerDisplayOrderType {

@Expose
@ConfigOption(
name = "Maximum Rows",
desc = "The maximum number of rows to display in the tracker, before a cutoff is imposed."
name = "Max Height",
desc = "Maximum height of the tracker."
)
@ConfigEditorSlider(minValue = 5, maxValue = 40, minStep = 1)
public Property<Integer> maxDisplayRows = Property.of(20);
@ConfigEditorSlider(minValue = 50, maxValue = 500, minStep = 10)
public Property<Float> maxHeight = Property.of(250F);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import at.hannibal2.skyhanni.features.inventory.patternGroup
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.ConditionalUtils
import at.hannibal2.skyhanni.utils.ConfigUtils.jumpToEditor
import at.hannibal2.skyhanni.utils.HypixelCommands
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.InventoryUtils.getUpperItems
Expand Down Expand Up @@ -112,6 +111,7 @@ object CakeTracker {

private val storage get() = ProfileStorageData.profileSpecific?.cakeData
private val config get() = SkyHanniMod.feature.inventory.cakeTracker
private val maxTrackerHeight: Float get() = config.maxHeight.get()

private var currentYear = 0
private var inCakeInventory = false
Expand Down Expand Up @@ -170,7 +170,7 @@ object CakeTracker {

@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
ConditionalUtils.onToggle(config.maxDisplayRows) {
ConditionalUtils.onToggle(config.maxHeight) {
lastKnownCakeDataHash = 0
}
}
Expand Down Expand Up @@ -299,25 +299,31 @@ object CakeTracker {

fun getRenderable(displayType: DisplayType): Renderable {
val colorCode = if (displayType == DisplayType.OWNED_CAKES) "§a" else "§c"
val baseRenderable = getHoverable(colorCode)
return if (displayType == DisplayType.MISSING_CAKES) Renderable.link(
val baseRenderable = getHoverable(displayType, colorCode)
return if (displayType == DisplayType.MISSING_CAKES && config.priceOnHover) Renderable.link(
baseRenderable,
{ HypixelCommands.auctionSearch("New Year Cake (Year $start)") },
) else baseRenderable
}

fun getHoverable(colorCode: String): Renderable {
fun getHoverable(displayType: DisplayType, colorCode: String): Renderable {
val displayString =
if (isSingular) "§fYear $colorCode$start"
else "§fYears $colorCode$start§f-$colorCode$end"

return if (!config.priceOnHover) Renderable.string(displayString)
else Renderable.hoverTips(displayString, getPriceHoverTooltip(colorCode))
else Renderable.hoverTips(
displayString,
getPriceHoverTooltip(displayType, colorCode)
)
}

fun getPriceHoverTooltip(colorCode: String): List<String> {
fun getPriceHoverTooltip(displayType: DisplayType, colorCode: String): List<String> {
return if (isSingular) {
listOf("${colorCode}Year $start§7: ${getCakePriceString(start)}")
listOf(
"${colorCode}Year $start§7: ${getCakePriceString(start)}",
"§eClick to search auction house",
)
} else buildList {
val largerNumber = if (start > end) start else end
val smallerNumber = if (start < end) start else end
Expand All @@ -330,6 +336,9 @@ object CakeTracker {
if (rangeLength >= 5) add("§7§o... and ${rangeLength - 5} more")
add("")
add("§aTotal§7: §6${numericalRange.sumOf(::getCakePrice).addSeparators()}")
if (displayType == DisplayType.MISSING_CAKES) {
add("§eClick to search auction house")
}
}
}
}
Expand Down Expand Up @@ -430,59 +439,46 @@ object CakeTracker {
val colorCode = if (config.displayType == DisplayType.OWNED_CAKES) "§c" else "§a"
val verbiage = if (config.displayType == DisplayType.OWNED_CAKES) "missing" else "owned"
add(Renderable.string("$colorCode§lAll cakes $verbiage!"))
} else addCakeRanges(cakeList, config.displayOrderType, config.displayType)
} else add(
Renderable.scrollList(
getCakeRanges(cakeList, config.displayOrderType, config.displayType),
height = maxTrackerHeight.toInt() + 2, // +2 to account for tips
velocity = 20.0,
showScrollableTipsInList = true
)
)
}

private fun MutableList<Renderable>.addCakeRanges(
private fun getCakeRanges(
cakeList: Set<Int>,
orderType: DisplayOrder,
displayType: DisplayType,
) {
): List<Renderable> = buildList {
val sortedCakes = when (orderType) {
DisplayOrder.OLDEST_FIRST -> cakeList.sorted()
DisplayOrder.NEWEST_FIRST -> cakeList.sortedDescending()
}

// Combine consecutive years into ranges
// + 3 is to account for the header and selector boxes
val maxDisplayRows = config.maxDisplayRows.get() + 3
var start = sortedCakes.first()
var end = start
var hiddenRows = 0

for (year in sortedCakes.drop(1)) { // Skip the first item to prevent duplicate addition
if ((orderType == DisplayOrder.OLDEST_FIRST && year == end + 1) ||
(orderType == DisplayOrder.NEWEST_FIRST && year == end - 1)
) {
end = year
} else {
if (this.size < maxDisplayRows) {
val range = if (start != end) CakeRange(start, end) else CakeRange(start)
add(range.getRenderable(displayType))
} else {
hiddenRows++
start = year
end = start
continue
}
val oldestFirstAtEnd = orderType == DisplayOrder.OLDEST_FIRST && year == end + 1
val newestFirstAtEnd = orderType == DisplayOrder.NEWEST_FIRST && year == end - 1

if (oldestFirstAtEnd || newestFirstAtEnd) end = year
else {
val range = if (start != end) CakeRange(start, end) else CakeRange(start)
add(range.getRenderable(displayType))
start = year
end = start
}
}

if (this.size < maxDisplayRows) {
val lastRange = if (start != end) CakeRange(start, end) else CakeRange(start)
add(lastRange.getRenderable(displayType))
} else {
hiddenRows++
}
val lastRange =
if (start != end) CakeRange(start, end)
else CakeRange(start)

if (hiddenRows > 0) add(
Renderable.clickAndHover(
"§7§o($hiddenRows hidden rows)",
tips = listOf("§eClick to configure # of displayed rows"),
onClick = { config::maxDisplayRows.jumpToEditor() },
),
)
add(lastRange.getRenderable(displayType))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,12 @@ interface Renderable {
bypassChecks: Boolean = false,
horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
showScrollableTipsInList: Boolean = false
) = object : Renderable {
override val width = list.maxOf { it.width }
private val scrollUpTip = string("§7§oMore items above (scroll)")
private val scrollDownTip = string("§7§oMore items below (scroll)")

override var width = list.maxOf { it.width }
override val height = height
override val horizontalAlign = horizontalAlign
override val verticalAlign = verticalAlign
Expand All @@ -1001,6 +1005,23 @@ interface Renderable {
var renderY = 0
var virtualY = 0
var found = false

// If showScrollableTipsInList is true, and we are scrolled 'down', display a tip indicating
// there are more items above
if (showScrollableTipsInList && scroll.asInt() > 0) {
width = maxOf(width, scrollUpTip.width)
scrollUpTip.renderXAligned(posX, posY, width)
GlStateManager.translate(0f, scrollUpTip.height.toFloat(), 0f)
renderY += scrollUpTip.height
virtualY += scrollUpTip.height
}

val atScrollEnd = scroll.asInt() == virtualHeight - height
if (!atScrollEnd) {
virtualY += scrollDownTip.height
renderY += scrollDownTip.height
}

for (renderable in list) {
if ((virtualY..virtualY + renderable.height) in scroll.asInt()..end) {
renderable.renderXAligned(posX, posY + renderY, width)
Expand All @@ -1016,6 +1037,15 @@ interface Renderable {
}
virtualY += renderable.height
}

// If showScrollableTipsInList is true, and we are scrolled 'up', display a tip indicating
// there are more items below
if (showScrollableTipsInList && virtualY > end) {
width = maxOf(width, scrollDownTip.width)
scrollDownTip.renderXAligned(posX, posY + height - scrollDownTip.height, width)
GlStateManager.translate(0f, scrollDownTip.height.toFloat(), 0f)
}

GlStateManager.translate(0f, -renderY.toFloat(), 0f)
}
}
Expand Down

0 comments on commit e2c7ca7

Please sign in to comment.