Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement: Cake Tracker Scrollable and AH Tips #2939

Merged
merged 8 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -53,6 +52,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 @@ -157,7 +157,7 @@ object CakeTracker {

@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
ConditionalUtils.onToggle(config.maxDisplayRows) {
ConditionalUtils.onToggle(config.maxHeight) {
lastKnownCakeDataHash = 0
}
}
Expand Down Expand Up @@ -286,25 +286,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 @@ -317,6 +323,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 @@ -417,59 +426,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
Loading