Skip to content

Commit

Permalink
add tablist api
Browse files Browse the repository at this point in the history
  • Loading branch information
LukynkaCZE committed Dec 5, 2024
1 parent f6a8069 commit 440631d
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 41 deletions.
23 changes: 14 additions & 9 deletions src/main/kotlin/io/github/dockyardmc/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,22 @@ import io.github.dockyardmc.commands.Commands
import io.github.dockyardmc.commands.PlayerArgument
import io.github.dockyardmc.commands.simpleSuggestion
import io.github.dockyardmc.datagen.EventsDocumentationGenerator
import io.github.dockyardmc.entity.EntityManager.spawnEntity
import io.github.dockyardmc.entity.Parrot
import io.github.dockyardmc.entity.TestZombie
import io.github.dockyardmc.entity.Warden
import io.github.dockyardmc.events.Events
import io.github.dockyardmc.events.PlayerJoinEvent
import io.github.dockyardmc.events.PlayerLeaveEvent
import io.github.dockyardmc.events.PlayerSpawnEvent
import io.github.dockyardmc.extentions.broadcastMessage
import io.github.dockyardmc.inventory.give
import io.github.dockyardmc.item.ConsumableAnimation
import io.github.dockyardmc.item.ConsumableItemComponent
import io.github.dockyardmc.item.ItemStack
import io.github.dockyardmc.player.systems.GameMode
import io.github.dockyardmc.registry.*
import io.github.dockyardmc.registry.Blocks
import io.github.dockyardmc.registry.Items
import io.github.dockyardmc.registry.PotionEffects
import io.github.dockyardmc.registry.Sounds
import io.github.dockyardmc.sounds.Sound
import io.github.dockyardmc.utils.DebugSidebar
import io.github.dockyardmc.utils.randomInt
import io.github.dockyardmc.world.WorldManager
import io.github.dockyardmc.world.generators.FlatWorldGenerator

// This is just testing/development environment.
// To properly use dockyard, visit https://dockyardmc.github.io/Wiki/wiki/quick-start.html
Expand All @@ -50,6 +46,7 @@ fun main(args: Array<String>) {
}
}


Events.on<PlayerJoinEvent> {
val player = it.player

Expand All @@ -62,7 +59,15 @@ fun main(args: Array<String>) {
player.addPotionEffect(PotionEffects.NIGHT_VISION, -1, 0, false)

val item = ItemStack(Items.SWEET_BERRIES, 10)
item.components.add(ConsumableItemComponent(2f, ConsumableAnimation.EAT, Sound(Sounds.ENTITY_GENERIC_EAT), true, listOf()))
item.components.add(
ConsumableItemComponent(
2f,
ConsumableAnimation.EAT,
Sound(Sounds.ENTITY_GENERIC_EAT),
true,
listOf()
)
)

player.give(item)
}
Expand Down
34 changes: 15 additions & 19 deletions src/main/kotlin/io/github/dockyardmc/bossbar/Bossbar.kt
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
package io.github.dockyardmc.bossbar

import cz.lukynka.Bindable
import cz.lukynka.BindableList
import io.github.dockyardmc.events.EventPool
import io.github.dockyardmc.events.PlayerJoinEvent
import io.github.dockyardmc.extentions.sendPacket
import io.github.dockyardmc.player.*
import io.github.dockyardmc.protocol.packets.play.clientbound.BossbarPacketAction
import io.github.dockyardmc.protocol.packets.play.clientbound.ClientboundBossbarPacket
import io.github.dockyardmc.utils.Disposable
import io.github.dockyardmc.utils.Viewable
import java.util.*

class Bossbar(
val title: Bindable<String> = Bindable(""),
val progress: Bindable<Float> = Bindable(0f),
val color: Bindable<BossbarColor> = Bindable(BossbarColor.WHITE),
val notches: Bindable<BossbarNotches> = Bindable(BossbarNotches.NO_NOTCHES),
val viewers: BindableList<Player> = BindableList(),
): Disposable {
) : Disposable, Viewable() {

override var autoViewable: Boolean = false

constructor(
title: String = "",
progress: Float = 0f,
color: BossbarColor = BossbarColor.WHITE,
notches: BossbarNotches = BossbarNotches.NO_NOTCHES,
viewers: MutableList<Player> = mutableListOf(),
) :
this(
Bindable(title),
Bindable(progress),
Bindable(color),
Bindable(notches),
BindableList(viewers)
)

val eventPool = EventPool()
Expand All @@ -42,23 +40,21 @@ class Bossbar(
progress.valueChanged { viewers.sendPacket(ClientboundBossbarPacket(BossbarPacketAction.UPDATE_HEALTH, this)) }
color.valueChanged { viewers.sendPacket(ClientboundBossbarPacket(BossbarPacketAction.UPDATE_STYLE, this)) }
notches.valueChanged { viewers.sendPacket(ClientboundBossbarPacket(BossbarPacketAction.UPDATE_STYLE, this)) }

// player added to viewers
viewers.itemAdded {
val createPacket = ClientboundBossbarPacket(BossbarPacketAction.ADD, this)
it.item.sendPacket(createPacket)
}

// player removed from viewers
viewers.itemRemoved {
val removePacket = ClientboundBossbarPacket(BossbarPacketAction.REMOVE, this)
it.item.sendPacket(removePacket)
}
}

override fun dispose() {
eventPool.dispose()
viewers.values.forEach(viewers::remove)
viewers.toList().forEach(viewers::remove)
}

override fun addViewer(player: Player) {
val createPacket = ClientboundBossbarPacket(BossbarPacketAction.ADD, this)
player.sendPacket(createPacket)
}

override fun removeViewer(player: Player) {
val removePacket = ClientboundBossbarPacket(BossbarPacketAction.REMOVE, this)
player.sendPacket(removePacket)
}
}

Expand Down
19 changes: 10 additions & 9 deletions src/main/kotlin/io/github/dockyardmc/player/ProtocolEnums.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,32 @@ enum class Direction {

fun Entity.getDirection(noPitch: Boolean = false): Direction = getDirection(this.location, noPitch)

fun getDirection(location: Location, noPitch: Boolean = false): Direction = getDirection(location.yaw, location.pitch, noPitch)
fun getDirection(location: Location, noPitch: Boolean = false): Direction =
getDirection(location.yaw, location.pitch, noPitch)

fun getDirection(yaw: Float, pitch: Float, noPitch: Boolean = false): Direction {
val normalizedYaw = if (yaw < 0) yaw + 360 else yaw % 360

if(!noPitch) {
if (!noPitch) {
return when {
pitch < -45 -> Direction.UP
pitch > 45 -> Direction.DOWN
pitch < -45 -> Direction.UP
pitch > 45 -> Direction.DOWN
else -> throw IllegalStateException("Invalid pitch value: $yaw")
}
}

return when {
normalizedYaw < 45 || normalizedYaw >= 315 -> Direction.SOUTH
normalizedYaw in 45.0..135.0 -> Direction.WEST
normalizedYaw in 135.0..225.0 -> Direction.NORTH
normalizedYaw in 225.0..315.0 -> Direction.EAST
normalizedYaw < 45 || normalizedYaw >= 315 -> Direction.SOUTH
normalizedYaw in 45.0..135.0 -> Direction.WEST
normalizedYaw in 135.0..225.0 -> Direction.NORTH
normalizedYaw in 225.0..315.0 -> Direction.EAST

else -> throw IllegalStateException("Invalid yaw value: $yaw")
}
}

fun Direction.getOpposite(): Direction {
return when(this) {
return when (this) {
Direction.DOWN -> Direction.UP
Direction.SOUTH -> Direction.NORTH
Direction.WEST -> Direction.EAST
Expand Down
150 changes: 150 additions & 0 deletions src/main/kotlin/io/github/dockyardmc/player/Tablist.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package io.github.dockyardmc.player

import io.github.dockyardmc.scroll.extensions.toComponent
import io.github.dockyardmc.utils.Disposable
import io.github.dockyardmc.utils.Viewable

class Tablist: Disposable, Viewable() {

override var autoViewable: Boolean = false

private val headerLines: MutableMap<Int, TablistLine> = mutableMapOf()
val header: Map<Int, TablistLine> get() = headerLines.toMap()

private val footerLines: MutableMap<Int, TablistLine> = mutableMapOf()
val footer: Map<Int, TablistLine> get() = footerLines.toMap()

override fun addViewer(player: Player) {
update(player)
viewers.add(player)
}

override fun removeViewer(player: Player) {
player.tabListFooter.value = "".toComponent()
player.tabListHeader.value = "".toComponent()
viewers.remove(player)
}

fun setHeaderLine(line: Int, value: String) {
setHeaderLine(line, GlobalTablistLine(value))
}

fun setHeaderLine(line: Int, value: GlobalTablistLine) {
headerLines[line] = value
viewers.forEach(::update)
}

fun setPlayerHeaderLine(line: Int, value: (Player) -> String) {
setPlayerHeaderLine(line, PlayerTablistLine(value))
}

fun setPlayerHeaderLine(line: Int, value: PlayerTablistLine) {
headerLines[line] = value
viewers.forEach(::update)
}

fun setFooterLine(line: Int, value: String) {
setFooterLine(line, GlobalTablistLine(value))
}

fun setFooterLine(line: Int, value: GlobalTablistLine) {
footerLines[line] = value
viewers.forEach(::update)
}

fun setPlayerFooterLine(line: Int, value: (Player) -> String) {
setPlayerFooterLine(line, PlayerTablistLine(value))
}

fun setPlayerFooterLine(line: Int, value: PlayerTablistLine) {
footerLines[line] = value
viewers.forEach(::update)
}

override fun dispose() {
viewers.toList().forEach(::removeViewer)
viewers.clear()
headerLines.clear()
footerLines.clear()
}

private fun update(player: Player) {
val headerComponent = buildString {
headerLines.toList().sortedByDescending { it.first }.reversed().forEach { (index, line) ->
when(line) {
is GlobalTablistLine -> append("${line.value}<r>\n")
is PlayerTablistLine -> {
val playerLine = line.getValue(player)
append("$playerLine<r>\n")
}
}
}
}

val footerComponent = buildString {
footerLines.toList().sortedByDescending { it.first }.reversed().forEach { (index, line) ->
when(line) {
is GlobalTablistLine -> append("${line.value}\n")
is PlayerTablistLine -> {
val playerLine = line.getValue(player)
append("$playerLine\n")
}
}
}
}

player.tabListHeader.value = headerComponent.toComponent()
player.tabListFooter.value = footerComponent.toComponent()
}
}

class TablistBuilder {
val headerLines: MutableList<TablistLine> = mutableListOf()
val footerLines: MutableList<TablistLine> = mutableListOf()

fun addHeaderLine(line: String) {
headerLines.add(GlobalTablistLine(line))
}

fun addFooterLine(line: String) {
footerLines.add(GlobalTablistLine(line))
}

fun addPlayerHeaderLine(line: (Player) -> String) {
headerLines.add(PlayerTablistLine(line))
}

fun addPlayerFooterLine(line: (Player) -> String) {
footerLines.add(PlayerTablistLine(line))
}
}

fun tablist(builder: TablistBuilder.() -> Unit): Tablist {
val tablistBuilder = TablistBuilder()
builder.invoke(tablistBuilder)

val tablist = Tablist()
tablistBuilder.headerLines.forEachIndexed { index, line ->
when(line) {
is GlobalTablistLine -> tablist.setHeaderLine(index, line)
is PlayerTablistLine -> tablist.setPlayerHeaderLine(index, line)
}
}

tablistBuilder.footerLines.forEachIndexed { index, line ->
when(line) {
is GlobalTablistLine -> tablist.setFooterLine(index, line)
is PlayerTablistLine -> tablist.setPlayerFooterLine(index, line)
}
}

return tablist
}

interface TablistLine {}

data class GlobalTablistLine(val value: String): TablistLine

data class PlayerTablistLine(val value: (Player) -> String): TablistLine {
fun getValue(player: Player): String = value(player)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class ServerTickManager {
}
}


fun start() {
timer.start()
}
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/io/github/dockyardmc/sidebar/Sidebar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package io.github.dockyardmc.sidebar

import cz.lukynka.Bindable
import cz.lukynka.BindableList
import io.github.dockyardmc.events.Events
import io.github.dockyardmc.events.PlayerJoinEvent
import io.github.dockyardmc.extentions.sendPacket
import io.github.dockyardmc.player.Player
import io.github.dockyardmc.protocol.packets.play.clientbound.*
Expand Down
4 changes: 3 additions & 1 deletion src/main/kotlin/io/github/dockyardmc/utils/MathUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.github.dockyardmc.utils.ChunkUtils.floor
import io.github.dockyardmc.utils.vectors.Vector3f
import java.io.File
import java.security.MessageDigest
import java.util.Random
import kotlin.math.*

fun multiplyQuaternions(q1: Quaternion, q2: Quaternion): Quaternion {
Expand Down Expand Up @@ -74,7 +75,8 @@ fun isBetween(number: Int, min: Int, max: Int): Boolean {
return number in min..max
}

fun randomInt(min: Int, max: Int): Int = (min..max).shuffled().last()
fun randomInt(min: Int, max: Int): Int = Random().nextInt(min, max)

fun randomFloat(min: Float, max: Float): Float {
val random = java.util.Random()
return min + random.nextFloat() * (max - min)
Expand Down

0 comments on commit 440631d

Please sign in to comment.