render scoreboard score below player name

This commit is contained in:
Moritz Zwerger 2023-11-06 15:26:31 +01:00
parent 9e326271e6
commit 199b8a7587
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
15 changed files with 70 additions and 21 deletions

View File

@ -0,0 +1,46 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.entities.feature.text
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
import de.bixilon.minosoft.data.scoreboard.ScoreboardPositions
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.rendering.entities.renderer.living.player.PlayerRenderer
class EntityScoreboardFeature(renderer: PlayerRenderer<*>) : BillboardTextFeature(renderer, null) {
override fun update(millis: Long, delta: Float) {
updateScore()
super.update(millis, delta)
}
private fun updateScore() {
// TODO: self, offset name, render distance (10), performance
this.text = getScore()
}
private fun getScore(): ChatComponent? {
val objective = renderer.renderer.connection.scoreboard.positions[ScoreboardPositions.BELOW_NAME] ?: return null
val score = objective.scores[renderer.entity.unsafeCast<PlayerEntity>().additional.name] ?: return null
val text = BaseComponent()
text += TextComponent(score.value)
text += " "
text += objective.displayName
return text
}
}

View File

@ -22,6 +22,7 @@ import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
import de.bixilon.minosoft.gui.rendering.entities.factory.RegisteredEntityModelFactory
import de.bixilon.minosoft.gui.rendering.entities.feature.text.EntityScoreboardFeature
import de.bixilon.minosoft.gui.rendering.entities.model.human.PlayerModel
import de.bixilon.minosoft.gui.rendering.entities.renderer.living.LivingEntityRenderer
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
@ -38,6 +39,8 @@ open class PlayerRenderer<E : PlayerEntity>(renderer: EntitiesRenderer, entity:
var skin: DynamicTexture? = null
private var refresh = true
val scoreboard = EntityScoreboardFeature(this).register()
init {
entity.additional::properties.observe(this) { refresh = true }
}

View File

@ -85,7 +85,7 @@ class PlayConnection(
val registries = Registries().apply { updateFlattened(version.flattened) }
val world = World(this)
val tabList = TabList()
val scoreboardManager = ScoreboardManager(this)
val scoreboard = ScoreboardManager(this)
val bossbarManager = BossbarManager()
val util = ConnectionUtil(this)
val ticker = ConnectionTicker(this)

View File

@ -26,7 +26,7 @@ class ObjectivePositionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
private val name: String? = buffer.readNullString()
override fun handle(connection: PlayConnection) {
val scoreboardManager = connection.scoreboardManager
val scoreboardManager = connection.scoreboard
if (name == null) {
scoreboardManager.positions -= position
connection.events.fire(ObjectivePositionSetEvent(connection, position, null))

View File

@ -60,7 +60,7 @@ class CreateObjectiveS2CP(
override fun handle(connection: PlayConnection) {
val objective = ScoreboardObjective(name, displayName, unit)
connection.scoreboardManager.objectives[name] = objective
connection.scoreboard.objectives[name] = objective
connection.events.fire(ScoreboardObjectiveCreateEvent(connection, objective))
}

View File

@ -31,13 +31,13 @@ class RemoveObjectiveS2CP(
}
override fun handle(connection: PlayConnection) {
connection.scoreboardManager.objectives.remove(objective)
connection.scoreboard.objectives.remove(objective)
for ((position, objective) in connection.scoreboardManager.positions.toSynchronizedMap()) {
for ((position, objective) in connection.scoreboard.positions.toSynchronizedMap()) {
if (objective.name != this.objective) {
continue
}
connection.scoreboardManager.positions -= position
connection.scoreboard.positions -= position
connection.events.fire(ObjectivePositionSetEvent(connection, position, null))
}
}

View File

@ -58,7 +58,7 @@ class UpdateObjectiveS2CP(
}
override fun handle(connection: PlayConnection) {
val objective = connection.scoreboardManager.objectives[objective] ?: return
val objective = connection.scoreboard.objectives[objective] ?: return
objective.displayName = displayName
objective.unit = unit

View File

@ -35,8 +35,8 @@ class PutScoreboardScoreS2CP(
override fun handle(connection: PlayConnection) {
check(objective != null) { "Can not update null objective!" }
val objective = connection.scoreboardManager.objectives[objective] ?: return
val score = ScoreboardScore(entity, objective, connection.scoreboardManager.getTeam(entity), value)
val objective = connection.scoreboard.objectives[objective] ?: return
val score = ScoreboardScore(entity, objective, connection.scoreboard.getTeam(entity), value)
objective.scores[entity] = score
connection.events.fire(ScoreboardScorePutEvent(connection, score))

View File

@ -28,8 +28,8 @@ class RemoveScoreboardScoreS2CP(
) : ScoreboardScoreS2CP {
override fun handle(connection: PlayConnection) {
val objective = connection.scoreboardManager.objectives[objective] ?: let {
for ((_, objective) in connection.scoreboardManager.objectives.toSynchronizedMap()) {
val objective = connection.scoreboard.objectives[objective] ?: let {
for ((_, objective) in connection.scoreboard.objectives.toSynchronizedMap()) {
val score = objective.scores.remove(entity) ?: continue
connection.events.fire(ScoreboardScoreRemoveEvent(connection, score))

View File

@ -35,14 +35,14 @@ class AddTeamMemberS2CP(
override fun handle(connection: PlayConnection) {
val team = connection.scoreboardManager.teams[name] ?: return
val team = connection.scoreboard.teams[name] ?: return
team.members += members
for (member in members) {
connection.tabList.name[member]?.team = team
}
connection.scoreboardManager.updateScoreTeams(team, members)
connection.scoreboard.updateScoreTeams(team, members)
connection.events.fire(TeamMemberAddEvent(connection, team, members))
}

View File

@ -118,13 +118,13 @@ class CreateTeamS2CP(
color = color,
members = members.toSynchronizedSet(),
)
connection.scoreboardManager.teams[name] = team
connection.scoreboard.teams[name] = team
for (member in members) {
connection.tabList.name[member]?.team = team
}
connection.scoreboardManager.updateScoreTeams(team, members)
connection.scoreboard.updateScoreTeams(team, members)
connection.events.fire(TeamCreateEvent(connection, team))
}

View File

@ -35,7 +35,7 @@ class RemoveTeamMemberS2CP(
override fun handle(connection: PlayConnection) {
val team = connection.scoreboardManager.teams[name] ?: return
val team = connection.scoreboard.teams[name] ?: return
team.members -= members
for (member in members) {
@ -46,7 +46,7 @@ class RemoveTeamMemberS2CP(
item.team = team
}
connection.scoreboardManager.updateScoreTeams(team, members, true)
connection.scoreboard.updateScoreTeams(team, members, true)
connection.events.fire(TeamMemberRemoveEvent(connection, team, members))
}

View File

@ -22,9 +22,9 @@ import de.bixilon.minosoft.util.logging.LogMessageType
class RemoveTeamS2CP(val name: String) : TeamsS2CP {
override fun handle(connection: PlayConnection) {
val team = connection.scoreboardManager.teams.remove(name) ?: return
val team = connection.scoreboard.teams.remove(name) ?: return
connection.scoreboardManager.updateScoreTeams(team, team.members, true)
connection.scoreboard.updateScoreTeams(team, team.members, true)
connection.events.fire(ScoreboardTeamRemoveEvent(connection, team))
}

View File

@ -94,7 +94,7 @@ class UpdateTeamS2CP(
override fun handle(connection: PlayConnection) {
val team = connection.scoreboardManager.teams[name] ?: return
val team = connection.scoreboard.teams[name] ?: return
team.displayName = displayName
team.prefix = prefix

View File

@ -77,7 +77,7 @@ class TabListS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
connection.tabList.uuid[uuid] = item
connection.tabList.name[name] = item
for (team in connection.scoreboardManager.teams.toSynchronizedMap().values) {
for (team in connection.scoreboard.teams.toSynchronizedMap().values) {
if (team.members.contains(data.name)) {
item.team = team
break