Profile Viewer Skill Page v1

This commit is contained in:
nea
2023-06-01 23:10:09 +02:00
parent 6e3c41fbaf
commit 7c60db4fbf
6 changed files with 115 additions and 42 deletions

View File

@@ -10,6 +10,7 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
import kotlin.reflect.KProperty1 import kotlin.reflect.KProperty1
import net.minecraft.util.DyeColor
import moe.nea.firmament.util.json.DashlessUUIDSerializer import moe.nea.firmament.util.json.DashlessUUIDSerializer
import moe.nea.firmament.util.json.InstantAsLongSerializer import moe.nea.firmament.util.json.InstantAsLongSerializer
@@ -30,18 +31,18 @@ data class Profile(
val members: Map<UUID, Member>, val members: Map<UUID, Member>,
) )
enum class Skill(val accessor: KProperty1<Member, Double>) { enum class Skill(val accessor: KProperty1<Member, Double>, val color: DyeColor) {
FARMING(Member::experienceSkillFarming), FARMING(Member::experienceSkillFarming, DyeColor.YELLOW),
FORAGING(Member::experienceSkillForaging), FORAGING(Member::experienceSkillForaging, DyeColor.BROWN),
MINING(Member::experienceSkillMining), MINING(Member::experienceSkillMining, DyeColor.LIGHT_GRAY),
ALCHEMY(Member::experienceSkillAlchemy), ALCHEMY(Member::experienceSkillAlchemy, DyeColor.PURPLE),
TAMING(Member::experienceSkillTaming), TAMING(Member::experienceSkillTaming, DyeColor.GREEN),
FISHING(Member::experienceSkillFishing), FISHING(Member::experienceSkillFishing, DyeColor.BLUE),
RUNECRAFTING(Member::experienceSkillRunecrafting), RUNECRAFTING(Member::experienceSkillRunecrafting, DyeColor.PINK),
CARPENTRY(Member::experienceSkillCarpentry), CARPENTRY(Member::experienceSkillCarpentry, DyeColor.ORANGE),
COMBAT(Member::experienceSkillCombat), COMBAT(Member::experienceSkillCombat, DyeColor.RED),
SOCIAL(Member::experienceSkillSocial), SOCIAL(Member::experienceSkillSocial, DyeColor.WHITE),
ENCHANTING(Member::experienceSkillEnchanting), ENCHANTING(Member::experienceSkillEnchanting, DyeColor.MAGENTA),
; ;
fun getMaximumLevel(leveling: Leveling) = leveling.maximumLevels[name.lowercase()] ?: TODO("Repo error") fun getMaximumLevel(leveling: Leveling) = leveling.maximumLevels[name.lowercase()] ?: TODO("Repo error")

View File

@@ -1,5 +1,6 @@
package moe.nea.firmament.gui package moe.nea.firmament.gui
import com.mojang.blaze3d.systems.RenderSystem
import io.github.cottonmc.cotton.gui.client.ScreenDrawing import io.github.cottonmc.cotton.gui.client.ScreenDrawing
import io.github.cottonmc.cotton.gui.widget.WWidget import io.github.cottonmc.cotton.gui.widget.WWidget
import io.github.cottonmc.cotton.gui.widget.data.Texture import io.github.cottonmc.cotton.gui.widget.data.Texture
@@ -7,17 +8,19 @@ import me.shedaniel.math.Color
import net.minecraft.client.util.math.MatrixStack import net.minecraft.client.util.math.MatrixStack
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
data class WBar( open class WBar(
var progress: Double, var progress: Double,
val total: Double, val total: Double,
val fillColor: Color, val fillColor: Color,
val emptyColor: Color, val emptyColor: Color,
) : WWidget() { ) : WWidget() {
val resource = Firmament.identifier("textures/gui/bar.png") companion object {
val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F) val resource = Firmament.identifier("textures/gui/bar.png")
val middle = Texture(resource, 4 / 64F, 0 / 64F, 4 / 64F, 8 / 64F) val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F)
val right = Texture(resource, 8 / 64F, 0 / 64F, 4 / 64F, 8 / 64F) val middle = Texture(resource, 4 / 64F, 0 / 64F, 8 / 64F, 8 / 64F)
val segmentOverlay = Texture(resource, 12 / 64F, 0 / 64F, 15 / 64F, 8 / 64F) val right = Texture(resource, 8 / 64F, 0 / 64F, 12 / 64F, 8 / 64F)
val segmentOverlay = Texture(resource, 12 / 64F, 0 / 64F, 15 / 64F, 8 / 64F)
}
override fun canResize(): Boolean { override fun canResize(): Boolean {
return true return true
@@ -65,5 +68,6 @@ data class WBar(
i += 4 i += 4
} }
drawSection(matrices, right, x + width - 4, y, 4, (width - 4) * total / width, total) drawSection(matrices, right, x + width - 4, y, 4, (width - 4) * total / width, total)
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
} }
} }

View File

@@ -0,0 +1,34 @@
package moe.nea.firmament.gui
import io.github.cottonmc.cotton.gui.widget.WPanel
import io.github.cottonmc.cotton.gui.widget.WWidget
import io.github.cottonmc.cotton.gui.widget.data.Axis
data class WCenteringPanel(
val child: WWidget,
val axis: Axis,
) : WPanel() {
init {
child.parent = this
}
override fun setSize(x: Int, y: Int) {
super.setSize(x, y)
if (!child.canResize()) return
if (axis == Axis.HORIZONTAL) {
child.setSize(child.width, y)
} else {
child.setSize(x, child.height)
}
}
override fun layout() {
super.layout()
child.setLocation(
axis.choose((child.width + width) / 2, child.x),
axis.choose(child.y, (child.height + height) / 2),
)
}
}

View File

@@ -0,0 +1,7 @@
package moe.nea.firmament.gui.profileviewer
import io.github.cottonmc.cotton.gui.widget.WWidget
interface ProfilePage {
fun getElements(profileViewer: ProfileViewer): WWidget
}

View File

@@ -1,49 +1,36 @@
package moe.nea.firmament.gui.profileviewer package moe.nea.firmament.gui.profileviewer
import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription
import io.github.cottonmc.cotton.gui.widget.TooltipBuilder
import io.github.cottonmc.cotton.gui.widget.WGridPanel import io.github.cottonmc.cotton.gui.widget.WGridPanel
import io.github.cottonmc.cotton.gui.widget.WTabPanel import io.github.cottonmc.cotton.gui.widget.WTabPanel
import io.github.cottonmc.cotton.gui.widget.WText
import io.github.cottonmc.cotton.gui.widget.data.Insets import io.github.cottonmc.cotton.gui.widget.data.Insets
import io.github.cottonmc.cotton.gui.widget.icon.ItemIcon import io.github.cottonmc.cotton.gui.widget.icon.ItemIcon
import java.util.UUID import java.util.UUID
import net.minecraft.item.Items import net.minecraft.item.Items
import net.minecraft.text.Text import net.minecraft.text.Text
import net.minecraft.util.DyeColor
import moe.nea.firmament.apis.Member
import moe.nea.firmament.apis.Profile import moe.nea.firmament.apis.Profile
import moe.nea.firmament.apis.Skill import moe.nea.firmament.gui.WBar
import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.util.toShedaniel
class ProfileViewer( class ProfileViewer(
val primaryPlayer: UUID, val primaryPlayer: UUID,
val playerNames: Map<UUID, String>, val playerNames: Map<UUID, String>,
val profile: Profile, val profile: Profile,
) : LightweightGuiDescription() { ) : LightweightGuiDescription() {
val member: Member = profile.members[primaryPlayer] ?: error("Primary player not in profile")
val primaryName: String = playerNames[primaryPlayer] ?: error("Primary player has no name")
init { init {
val primaryMember = profile.members[primaryPlayer] ?: error("Primary player not in profile")
val panel = WTabPanel().also { rootPanel = it } val panel = WTabPanel().also { rootPanel = it }
panel.backgroundPainter panel.backgroundPainter
panel.add(WGridPanel().also { panel.add(SkillPage.getElements(this)) {
it.insets = Insets.ROOT_PANEL
it.add(WText(Text.literal(playerNames[primaryPlayer] ?: error("Primary player has no name"))), 0, 0, 6, 1)
for ((i, skill) in Skill.values().withIndex()) {
val leveling = RepoManager.neuRepo.constants.leveling
val exp = skill.accessor.get(primaryMember)
val maxLevel = skill.getMaximumLevel(leveling)
val level = skill.getLadder(leveling)
.runningFold(0.0) { a, b -> a + b }
.filter { it <= exp }.size
.coerceAtMost(maxLevel)
it.add(WText(Text.translatable("firmament.pv.skills.${skill.name.lowercase()}")), 0, i + 1, 5, 1)
it.add(object : WText(Text.literal("$level/$maxLevel")) {
override fun addTooltip(tooltip: TooltipBuilder) {
tooltip.add(Text.translatable("firmament.pv.skills.total", exp))
}
}, 5, i + 1, 2, 1)
}
}) {
it.icon(ItemIcon(Items.IRON_SWORD)) it.icon(ItemIcon(Items.IRON_SWORD))
it.title(Text.translatable("firmament.pv.skills")) it.title(Text.translatable("firmament.pv.skills"))
} }
} }
} }

View File

@@ -0,0 +1,40 @@
package moe.nea.firmament.gui.profileviewer
import io.github.cottonmc.cotton.gui.widget.TooltipBuilder
import io.github.cottonmc.cotton.gui.widget.WGridPanel
import io.github.cottonmc.cotton.gui.widget.WText
import io.github.cottonmc.cotton.gui.widget.WWidget
import io.github.cottonmc.cotton.gui.widget.data.Insets
import net.minecraft.text.Text
import moe.nea.firmament.apis.Skill
import moe.nea.firmament.gui.WBar
import moe.nea.firmament.repo.RepoManager
import moe.nea.firmament.util.toShedaniel
object SkillPage : ProfilePage {
override fun getElements(profileViewer: ProfileViewer): WWidget {
return WGridPanel().also {
it.insets = Insets.ROOT_PANEL
it.add(WText(Text.literal(profileViewer.primaryName /* with rank? */)), 0, 0, 6, 1)
for ((i, skill) in Skill.values().withIndex()) {
val leveling = RepoManager.neuRepo.constants.leveling
val exp = skill.accessor.get(profileViewer.member)
val maxLevel = skill.getMaximumLevel(leveling)
val level = skill.getLadder(leveling)
.runningFold(0.0) { a, b -> a + b }
.filter { it <= exp }.size
.coerceAtMost(maxLevel)
it.add(WText(Text.translatable("firmament.pv.skills.${skill.name.lowercase()}")), 0, i + 1, 4, 1)
it.add(object : WBar(
level.toDouble(), maxLevel.toDouble(),
skill.color.toShedaniel(), skill.color.toShedaniel().darker(2.0)
) {
override fun addTooltip(tooltip: TooltipBuilder) {
tooltip.add(Text.literal("$level/$maxLevel"))
tooltip.add(Text.translatable("firmament.pv.skills.total", exp))
}
}, 4, i + 1, 4, 1)
}
}
}
}