aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-06-11 02:43:14 +0200
committernea <nea@nea.moe>2023-06-11 02:43:14 +0200
commita36c8f1c0eae969dcee8cf690f12d9121350212d (patch)
treeea93f19bf5f77f8b5e42a7b56162d9b6492b7fed /src/main/kotlin/moe/nea
parent040f7c7275568d783bfa5e4ed20412f72d126549 (diff)
downloadFirmament-a36c8f1c0eae969dcee8cf690f12d9121350212d.tar.gz
Firmament-a36c8f1c0eae969dcee8cf690f12d9121350212d.tar.bz2
Firmament-a36c8f1c0eae969dcee8cf690f12d9121350212d.zip
Add collection info to skill page
Diffstat (limited to 'src/main/kotlin/moe/nea')
-rw-r--r--src/main/kotlin/moe/nea/firmament/Firmament.kt4
-rw-r--r--src/main/kotlin/moe/nea/firmament/apis/Profiles.kt57
-rw-r--r--src/main/kotlin/moe/nea/firmament/commands/rome.kt7
-rw-r--r--src/main/kotlin/moe/nea/firmament/gui/WTitledItem.kt26
-rw-r--r--src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt13
-rw-r--r--src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt100
-rw-r--r--src/main/kotlin/moe/nea/firmament/repo/HypixelStaticData.kt (renamed from src/main/kotlin/moe/nea/firmament/repo/ItemCostData.kt)23
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt10
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/MC.kt1
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/colorconversion.kt5
10 files changed, 209 insertions, 37 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/Firmament.kt b/src/main/kotlin/moe/nea/firmament/Firmament.kt
index f130742..2e1cd05 100644
--- a/src/main/kotlin/moe/nea/firmament/Firmament.kt
+++ b/src/main/kotlin/moe/nea/firmament/Firmament.kt
@@ -50,7 +50,7 @@ import net.minecraft.util.Identifier
import moe.nea.firmament.commands.registerFirmamentCommand
import moe.nea.firmament.dbus.FirmamentDbusObject
import moe.nea.firmament.features.FeatureManager
-import moe.nea.firmament.repo.ItemCostData
+import moe.nea.firmament.repo.HypixelStaticData
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.data.IDataHolder
@@ -119,7 +119,7 @@ object Firmament {
RepoManager.initialize()
SBData.init()
FeatureManager.autoload()
- ItemCostData.spawnPriceLoop()
+ HypixelStaticData.spawnDataCollectionLoop()
ClientCommandRegistrationCallback.EVENT.register(this::registerCommands)
ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
runBlocking {
diff --git a/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt b/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt
index 4d4f370..ae23349 100644
--- a/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt
+++ b/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt
@@ -20,6 +20,32 @@ import moe.nea.firmament.util.json.InstantAsLongSerializer
@Serializable
+data class CollectionSkillData(
+ val items: Map<CollectionType, CollectionInfo>
+)
+
+@Serializable
+data class CollectionResponse(
+ val success: Boolean,
+ val collections: Map<Skill, CollectionSkillData>
+)
+
+@Serializable
+data class CollectionInfo(
+ val name: String,
+ val maxTiers: Int,
+ val tiers: List<CollectionTier>
+)
+
+@Serializable
+data class CollectionTier(
+ val tier: Int,
+ val amountRequired: Long,
+ val unlocks: List<String>,
+)
+
+
+@Serializable
data class Profiles(
val success: Boolean,
val profiles: List<Profile>?
@@ -35,18 +61,18 @@ data class Profile(
val members: Map<UUID, Member>,
)
-enum class Skill(val accessor: KProperty1<Member, Double>, val color: DyeColor) {
- FARMING(Member::experienceSkillFarming, DyeColor.YELLOW),
- FORAGING(Member::experienceSkillForaging, DyeColor.BROWN),
- MINING(Member::experienceSkillMining, DyeColor.LIGHT_GRAY),
- ALCHEMY(Member::experienceSkillAlchemy, DyeColor.PURPLE),
- TAMING(Member::experienceSkillTaming, DyeColor.GREEN),
- FISHING(Member::experienceSkillFishing, DyeColor.BLUE),
- RUNECRAFTING(Member::experienceSkillRunecrafting, DyeColor.PINK),
- CARPENTRY(Member::experienceSkillCarpentry, DyeColor.ORANGE),
- COMBAT(Member::experienceSkillCombat, DyeColor.RED),
- SOCIAL(Member::experienceSkillSocial, DyeColor.WHITE),
- ENCHANTING(Member::experienceSkillEnchanting, DyeColor.MAGENTA),
+enum class Skill(val accessor: KProperty1<Member, Double>, val color: DyeColor, val icon: SkyblockId) {
+ FARMING(Member::experienceSkillFarming, DyeColor.YELLOW, SkyblockId("ROOKIE_HOE")),
+ FORAGING(Member::experienceSkillForaging, DyeColor.BROWN, SkyblockId("TREECAPITATOR_AXE")),
+ MINING(Member::experienceSkillMining, DyeColor.LIGHT_GRAY, SkyblockId("DIAMOND_PICKAXE")),
+ ALCHEMY(Member::experienceSkillAlchemy, DyeColor.PURPLE, SkyblockId("BREWING_STAND")),
+ TAMING(Member::experienceSkillTaming, DyeColor.GREEN, SkyblockId("SUPER_EGG")),
+ FISHING(Member::experienceSkillFishing, DyeColor.BLUE, SkyblockId("FARMER_ROD")),
+ RUNECRAFTING(Member::experienceSkillRunecrafting, DyeColor.PINK, SkyblockId("MUSIC_RUNE;1")),
+ CARPENTRY(Member::experienceSkillCarpentry, DyeColor.ORANGE, SkyblockId("WORKBENCH")),
+ COMBAT(Member::experienceSkillCombat, DyeColor.RED, SkyblockId("UNDEAD_SWORD")),
+ SOCIAL(Member::experienceSkillSocial, DyeColor.WHITE, SkyblockId("EGG_HUNT")),
+ ENCHANTING(Member::experienceSkillEnchanting, DyeColor.MAGENTA, SkyblockId("ENCHANTMENT_TABLE")),
;
fun getMaximumLevel(leveling: Leveling) = leveling.maximumLevels[name.lowercase()] ?: TODO("Repo error")
@@ -59,6 +85,12 @@ enum class Skill(val accessor: KProperty1<Member, Double>, val color: DyeColor)
}
@Serializable
+@JvmInline
+value class CollectionType(val string: String) {
+ val skyblockId get() = SkyblockId(string.replace(":", "-").replace("MUSHROOM_COLLECTION", "HUGE_MUSHROOM_2"))
+}
+
+@Serializable
data class Member(
val pets: List<Pet> = listOf(),
@SerialName("coop_invitation")
@@ -85,6 +117,7 @@ data class Member(
val experienceSkillRunecrafting: Double = 0.0,
@SerialName("experience_skill_carpentry")
val experienceSkillCarpentry: Double = 0.0,
+ val collection: Map<CollectionType, Long> = mapOf()
)
@Serializable
diff --git a/src/main/kotlin/moe/nea/firmament/commands/rome.kt b/src/main/kotlin/moe/nea/firmament/commands/rome.kt
index ff8c21e..2237abd 100644
--- a/src/main/kotlin/moe/nea/firmament/commands/rome.kt
+++ b/src/main/kotlin/moe/nea/firmament/commands/rome.kt
@@ -19,14 +19,13 @@
package moe.nea.firmament.commands
import com.mojang.brigadier.CommandDispatcher
-import com.mojang.brigadier.arguments.StringArgumentType.getString
import com.mojang.brigadier.arguments.StringArgumentType.string
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import net.minecraft.text.Text
import moe.nea.firmament.features.world.FairySouls
import moe.nea.firmament.gui.config.AllConfigsGui
import moe.nea.firmament.gui.profileviewer.ProfileViewer
-import moe.nea.firmament.repo.ItemCostData
+import moe.nea.firmament.repo.HypixelStaticData
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.MC
@@ -74,7 +73,7 @@ fun firmamentCommand() = literal("firmament") {
thenExecute {
val itemName = SkyblockId(get(item))
source.sendFeedback(Text.translatable("firmament.price", itemName.neuItem))
- val bazaarData = ItemCostData.bazaarData[itemName]
+ val bazaarData = HypixelStaticData.bazaarData[itemName]
if (bazaarData != null) {
source.sendFeedback(Text.translatable("firmament.price.bazaar"))
source.sendFeedback(
@@ -108,7 +107,7 @@ fun firmamentCommand() = literal("firmament") {
)
)
}
- val lowestBin = ItemCostData.lowestBin[itemName]
+ val lowestBin = HypixelStaticData.lowestBin[itemName]
if (lowestBin != null) {
source.sendFeedback(
Text.translatable(
diff --git a/src/main/kotlin/moe/nea/firmament/gui/WTitledItem.kt b/src/main/kotlin/moe/nea/firmament/gui/WTitledItem.kt
new file mode 100644
index 0000000..ff9e894
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/gui/WTitledItem.kt
@@ -0,0 +1,26 @@
+package moe.nea.firmament.gui
+
+import io.github.cottonmc.cotton.gui.client.BackgroundPainter
+import io.github.cottonmc.cotton.gui.widget.TooltipBuilder
+import io.github.cottonmc.cotton.gui.widget.WItem
+import net.minecraft.client.gui.DrawContext
+import net.minecraft.client.item.TooltipContext
+import net.minecraft.item.ItemStack
+import net.minecraft.text.Text
+import moe.nea.firmament.util.MC
+
+class WTitledItem(val stack: ItemStack, val countString: Text = Text.empty()) : WItem(stack) {
+ override fun paint(context: DrawContext, x: Int, y: Int, mouseX: Int, mouseY: Int) {
+ BackgroundPainter.SLOT.paintBackground(context, x, y, this)
+ super.paint(context, x, y, mouseX, mouseY)
+ context.matrices.push()
+ context.matrices.translate(0F, 0F, 200F)
+ context.drawText(MC.font, countString, x + 19 - 2 - MC.font.getWidth(countString), y + 6 + 3, 0xFFFFFF, true)
+ context.matrices.push()
+ }
+
+ override fun addTooltip(tooltip: TooltipBuilder) {
+ tooltip.add(*stack.getTooltip(null, TooltipContext.BASIC).toTypedArray())
+ }
+
+}
diff --git a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt
index 62889bd..20e11e7 100644
--- a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt
+++ b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt
@@ -14,8 +14,10 @@ import net.minecraft.client.item.TooltipContext
import net.minecraft.item.Items
import net.minecraft.text.Text
import moe.nea.firmament.gui.WTightScrollPanel
+import moe.nea.firmament.gui.WTitledItem
import moe.nea.firmament.rei.PetData
import moe.nea.firmament.rei.SBItemStack
+import moe.nea.firmament.repo.RepoManager
object PetsPage : ProfilePage {
override fun getElements(profileViewer: ProfileViewer): WWidget {
@@ -26,16 +28,7 @@ object PetsPage : ProfilePage {
it.setGaps(8, 8)
for ((i, pet) in profileViewer.member.pets.withIndex()) {
val stack = SBItemStack(pet.itemId, PetData(pet.tier, pet.type.name, pet.exp)).asItemStack()
- it.add(object : WItem(stack) {
- override fun paint(context: DrawContext?, x: Int, y: Int, mouseX: Int, mouseY: Int) {
- BackgroundPainter.SLOT.paintBackground(context, x, y, this)
- super.paint(context, x, y, mouseX, mouseY)
- }
-
- override fun addTooltip(tooltip: TooltipBuilder) {
- tooltip.add(*stack.getTooltip(null, TooltipContext.BASIC).toTypedArray())
- }
- }, i % 5, i / 5, 1, 1)
+ it.add(WTitledItem(stack), i % 5, i / 5, 1, 1)
}
it.layout()
})), 0, 1, 8, 8)
diff --git a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt
index c750101..2de217e 100644
--- a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt
+++ b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt
@@ -1,20 +1,39 @@
package moe.nea.firmament.gui.profileviewer
import io.github.cottonmc.cotton.gui.widget.TooltipBuilder
+import io.github.cottonmc.cotton.gui.widget.WBox
import io.github.cottonmc.cotton.gui.widget.WGridPanel
+import io.github.cottonmc.cotton.gui.widget.WPanel
+import io.github.cottonmc.cotton.gui.widget.WTabPanel
import io.github.cottonmc.cotton.gui.widget.WText
import io.github.cottonmc.cotton.gui.widget.WWidget
+import io.github.cottonmc.cotton.gui.widget.data.Axis
+import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment
import io.github.cottonmc.cotton.gui.widget.data.Insets
import io.github.cottonmc.cotton.gui.widget.icon.Icon
import io.github.cottonmc.cotton.gui.widget.icon.ItemIcon
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
+import net.minecraft.text.Style
import net.minecraft.text.Text
+import net.minecraft.util.Formatting
+import moe.nea.firmament.apis.CollectionInfo
+import moe.nea.firmament.apis.CollectionType
+import moe.nea.firmament.apis.Member
import moe.nea.firmament.apis.Skill
import moe.nea.firmament.gui.WBar
+import moe.nea.firmament.gui.WFixedPanel
+import moe.nea.firmament.gui.WTitledItem
+import moe.nea.firmament.hud.horizontal
+import moe.nea.firmament.rei.FirmamentReiPlugin.Companion.asItemEntry
+import moe.nea.firmament.rei.SBItemEntryDefinition
+import moe.nea.firmament.repo.HypixelStaticData
+import moe.nea.firmament.repo.ItemCache.asItemStack
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.FirmFormatters
+import moe.nea.firmament.util.modifyLore
import moe.nea.firmament.util.toShedaniel
+import moe.nea.firmament.util.toTextColor
object SkillPage : ProfilePage {
@@ -37,14 +56,83 @@ object SkillPage : ProfilePage {
}
}
+ private fun collectionItem(type: CollectionType, info: CollectionInfo, skill: Skill, member: Member): WWidget {
+ val collectionCount = member.collection[type] ?: 0
+ val unlockedTiers = info.tiers.count { it.amountRequired <= collectionCount }
+ return WTitledItem(
+ SBItemEntryDefinition.getEntry(type.skyblockId).asItemEntry().value.copy()
+ .also {
+ it.setCustomName(
+ Text.literal(info.name).fillStyle(
+ Style.EMPTY.withItalic(false).withBold(true)
+ .withColor(skill.color.toTextColor())
+ )
+ )
+ it.modifyLore { old ->
+ listOf(
+ Text.literal("${info.name} Collection: $collectionCount / ${info.tiers.last().amountRequired}"),
+ Text.literal("Tiers unlocked: $unlockedTiers")
+ ).map {
+ it.fillStyle(
+ Style.EMPTY.withItalic(false).withColor(Formatting.GRAY)
+ )
+ }
+ }
+ }, countString = Text.literal("$unlockedTiers").styled {
+ if (unlockedTiers == info.maxTiers)
+ it.withColor(Formatting.YELLOW)
+ else it
+ }
+ )
+ }
+
+ private fun collectionPanel(profileViewer: ProfileViewer): WTabPanel {
+ return WTabPanel().also {
+ val data = HypixelStaticData.collectionData
+ val panels = mutableListOf<WPanel>()
+ for ((skill, collections) in data.entries) {
+ val panel = WBox(Axis.HORIZONTAL).also {
+ it.horizontalAlignment = HorizontalAlignment.CENTER
+ it.add(WFixedPanel(WGridPanel().also {
+ it.insets = Insets.ROOT_PANEL
+ it.setGaps(2, 2)
+ var x = 0
+ var y = 0
+ for (item in collections.items) {
+ it.add(collectionItem(item.key, item.value, skill, profileViewer.member), x, y, 1, 1)
+ x++
+ if (x == 5) {
+ x = 0
+ y++
+ }
+ }
+ }))
+ }
+ panels.add(panel)
+ it.add(panel) {
+ it.tooltip(
+ Text.translatable("firmament.pv.skills.${skill.name.lowercase()}")
+ .styled { it.withColor(skill.color.toTextColor()) })
+ it.icon(ItemIcon(RepoManager.getNEUItem(skill.icon).asItemStack()))
+ }
+ }
+ it.layout()
+ val tabWidth = it.width
+ panels.forEach { it.setSize(tabWidth - Insets.ROOT_PANEL.horizontal, it.height) }
+ }
+ }
+
override fun getElements(profileViewer: ProfileViewer): WWidget {
- return WGridPanel().also {
+ return WBox(Axis.HORIZONTAL).also {
it.insets = Insets.ROOT_PANEL
- it.add(WText(Text.literal(profileViewer.account.getDisplayName())), 0, 0, 6, 1)
- for ((i, skill) in Skill.values().withIndex()) {
- it.add(WText(Text.translatable("firmament.pv.skills.${skill.name.lowercase()}")), 0, i + 1, 4, 1)
- it.add(skillBar(profileViewer, skill), 4, i + 1, 4, 1)
- }
+ it.add(WGridPanel().also {
+ it.add(WText(Text.literal(profileViewer.account.getDisplayName())), 0, 0, 8, 1)
+ for ((i, skill) in Skill.values().withIndex()) {
+ it.add(WText(Text.translatable("firmament.pv.skills.${skill.name.lowercase()}")), 0, i + 1, 4, 1)
+ it.add(skillBar(profileViewer, skill), 4, i + 1, 4, 1)
+ }
+ })
+ it.add(collectionPanel(profileViewer))
}
}
diff --git a/src/main/kotlin/moe/nea/firmament/repo/ItemCostData.kt b/src/main/kotlin/moe/nea/firmament/repo/HypixelStaticData.kt
index a1084b9..f2a2668 100644
--- a/src/main/kotlin/moe/nea/firmament/repo/ItemCostData.kt
+++ b/src/main/kotlin/moe/nea/firmament/repo/HypixelStaticData.kt
@@ -12,18 +12,23 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.time.Duration.Companion.minutes
import moe.nea.firmament.Firmament
+import moe.nea.firmament.apis.CollectionResponse
+import moe.nea.firmament.apis.CollectionSkillData
+import moe.nea.firmament.apis.Skill
import moe.nea.firmament.keybindings.IKeyBinding
import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.async.waitForInput
-object ItemCostData {
- private val logger = LogManager.getLogger("Firmament.ItemCostData")
+object HypixelStaticData {
+ private val logger = LogManager.getLogger("Firmament.HypixelStaticData")
private val moulberryBaseUrl = "https://moulberry.codes"
private val hypixelApiBaseUrl = "https://api.hypixel.net"
var lowestBin: Map<SkyblockId, Double> = mapOf()
private set
var bazaarData: Map<SkyblockId, BazaarData> = mapOf()
private set
+ var collectionData: Map<Skill, CollectionSkillData> = mapOf()
+ private set
@Serializable
data class BazaarData(
@@ -53,7 +58,9 @@ object ItemCostData {
fun getPriceOfItem(item: SkyblockId): Double? = bazaarData[item]?.quickStatus?.buyPrice ?: lowestBin[item]
- fun spawnPriceLoop() {
+
+ fun spawnDataCollectionLoop() {
+ Firmament.coroutineScope.launch { updateCollectionData() }
Firmament.coroutineScope.launch {
while (true) {
logger.info("Updating NEU prices")
@@ -83,4 +90,14 @@ object ItemCostData {
bazaarData = response.products.mapKeys { it.key.toRepoId() }
}
+ private suspend fun updateCollectionData() {
+ val response =
+ Firmament.httpClient.get("$hypixelApiBaseUrl/resources/skyblock/collections").body<CollectionResponse>()
+ if (!response.success) {
+ logger.warn("Retrieved unsuccessful collection data")
+ }
+ collectionData = response.collections
+ logger.info("Downloaded ${collectionData.values.sumOf { it.items.values.size }} collections")
+ }
+
}
diff --git a/src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt b/src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt
index 25fb7d3..78627cd 100644
--- a/src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt
@@ -33,6 +33,16 @@ fun ItemStack.appendLore(args: List<Text>) {
}
}
+fun ItemStack.modifyLore(update: (List<Text>) -> List<Text>) {
+ val compoundTag = getOrCreateSubNbt("display")
+ val loreList = compoundTag.getOrCreateList("Lore", NbtString.STRING_TYPE)
+ val parsed = loreList.map { Text.Serializer.fromJson(it.asString())!! }
+ val updated = update(parsed)
+ loreList.clear()
+ loreList.addAll(updated.map { NbtString.of(Text.Serializer.toJson(it)) })
+}
+
+
fun NbtCompound.getOrCreateList(label: String, tag: Byte): NbtList = getList(label, tag.toInt()).also {
put(label, it)
}
diff --git a/src/main/kotlin/moe/nea/firmament/util/MC.kt b/src/main/kotlin/moe/nea/firmament/util/MC.kt
index 53bad8b..e9ab6c9 100644
--- a/src/main/kotlin/moe/nea/firmament/util/MC.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/MC.kt
@@ -24,6 +24,7 @@ import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.util.math.BlockPos
object MC {
+ inline val font get() = MinecraftClient.getInstance().textRenderer
inline val soundManager get() = MinecraftClient.getInstance().soundManager
inline val player get() = MinecraftClient.getInstance().player
inline val world get() = MinecraftClient.getInstance().world
diff --git a/src/main/kotlin/moe/nea/firmament/util/colorconversion.kt b/src/main/kotlin/moe/nea/firmament/util/colorconversion.kt
index c19eefa..5da9f22 100644
--- a/src/main/kotlin/moe/nea/firmament/util/colorconversion.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/colorconversion.kt
@@ -1,6 +1,11 @@
package moe.nea.firmament.util
+import net.minecraft.text.TextColor
import net.minecraft.util.DyeColor
fun DyeColor.toShedaniel(): me.shedaniel.math.Color =
me.shedaniel.math.Color.ofOpaque(this.signColor)
+
+fun DyeColor.toTextColor(): TextColor =
+ TextColor.fromRgb(this.signColor)
+