1+ package dev.slne.surf.api.paper.server.impl.scoreboard
2+
3+ import dev.slne.surf.api.core.util.mutableObjectListOf
4+ import dev.slne.surf.api.paper.scoreboard.SurfScoreboardBuilder
5+ import net.kyori.adventure.text.Component
6+ import net.kyori.adventure.text.format.TextColor
7+ import net.kyori.adventure.text.minimessage.MiniMessage
8+ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder
9+ import net.megavex.scoreboardlibrary.api.sidebar.component.SidebarComponent
10+ import net.megavex.scoreboardlibrary.api.sidebar.component.animation.CollectionSidebarAnimation
11+ import net.megavex.scoreboardlibrary.api.sidebar.component.animation.SidebarAnimation
12+ import java.util.function.Supplier
13+
14+ class SurfScoreboardBuilderImpl (private val title : Component ) : SurfScoreboardBuilder {
15+ private val sidebarComponentBuilder = SidebarComponent .builder()
16+ private val animations = mutableObjectListOf<SidebarAnimation <Component >>()
17+ private var maxLines = SurfScoreboardBuilder .DEFAULT_MAX_LINES
18+
19+ override fun maxLines (maxLines : Int ) = apply {
20+ require(maxLines in 1 .. 15 ) { " maxLines must be between 1 and 15" }
21+ this .maxLines = maxLines
22+ }
23+
24+ override fun addLine (line : Component ) = apply {
25+ sidebarComponentBuilder.addStaticLine(line)
26+ }
27+
28+ override fun addUpdatableLine (line : Supplier <Component >) = apply {
29+ sidebarComponentBuilder.addDynamicLine(line)
30+ }
31+
32+ override fun addAnimatedLine (animation : SidebarAnimation <SidebarComponent >) = apply {
33+ sidebarComponentBuilder.addAnimatedComponent(animation)
34+ }
35+
36+ override fun addAnimatedLine (frames : MutableList <Component >) = apply {
37+ check(frames.isNotEmpty()) { " frames cannot be empty" }
38+
39+ val animation = CollectionSidebarAnimation (frames)
40+ sidebarComponentBuilder.addAnimatedLine(animation)
41+ animations.add(animation)
42+ }
43+
44+ override fun addGradientLine (text : Component , start : TextColor , end : TextColor ) = apply {
45+ val gradient = createGradientAnimation(text, start.asHexString(), end.asHexString())
46+ sidebarComponentBuilder.addAnimatedLine(gradient)
47+ animations.add(gradient)
48+ }
49+
50+ override fun build () = SurfScoreboardImpl (
51+ title, maxLines, sidebarComponentBuilder.build(), animations
52+ )
53+
54+
55+ override fun buildAutoUpdatable () = SurfAutoUpdatableScoreboardImpl (
56+ title,
57+ maxLines,
58+ sidebarComponentBuilder.build(),
59+ animations
60+ )
61+
62+
63+ override fun buildAutoUpdatablePlayer () = SurfAutoUpdatablePlayerScoreboardImpl (
64+ title,
65+ maxLines,
66+ sidebarComponentBuilder.build(),
67+ animations
68+ )
69+
70+
71+ companion object {
72+ private fun createGradientAnimation (
73+ component : Component ,
74+ firstHex : String , secondHex : String
75+ ): SidebarAnimation <Component > {
76+ val step = 1f / 20f
77+ val textPlaceholder = Placeholder .component(" text" , component)
78+ val frames = mutableObjectListOf<Component >()
79+
80+ // Animation from left to right
81+ var phase = - 1f
82+ while (phase < 1 ) {
83+ frames.add(
84+ MiniMessage .miniMessage().deserialize(
85+ " <gradient:$firstHex :$secondHex :$phase ><text></gradient>" ,
86+ textPlaceholder
87+ )
88+ )
89+ phase + = step
90+ }
91+
92+ // Animation from right to left
93+ frames.addAll(frames.reversed())
94+
95+ return CollectionSidebarAnimation (frames)
96+ }
97+ }
98+ }
0 commit comments