mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-10 06:41:30 +11:00
Abstract scoreboard display position (#286)
## Description The scoreboard display packet has a position field that can contain one of the following: - 0: List - 1: Sidebar - 2: BelowName - 3..=18: Team specific sidebar indexed as 3 + team color (according to wiki.vg) I'm not really sure how team specific sidebars are supposed to work, so left that as a byte, maybe that can have some more abstraction? ## Test Plan <details> <summary>Playground</summary> ```rust use valence::client::despawn_disconnected_clients; use valence::client::event::default_event_handler; use valence::prelude::*; use valence::protocol::packet::s2c::play::scoreboard_display::ScoreboardPosition; use valence::protocol::packet::s2c::play::scoreboard_objective_update::{Mode, RenderType}; use valence::protocol::packet::s2c::play::scoreboard_player_update::Action; use valence::protocol::packet::s2c::play::{ ScoreboardDisplayS2c, ScoreboardObjectiveUpdateS2c, ScoreboardPlayerUpdateS2c, }; use valence::protocol::var_int::VarInt; const SPAWN_Y: i32 = 64; pub fn build_app(app: &mut App) { app.add_plugin(ServerPlugin::new(())) .add_system(default_event_handler.in_schedule(EventLoopSchedule)) .add_startup_system(setup) .add_system(init_clients) .add_system(scoreboard) .add_system(despawn_disconnected_clients) .add_systems(PlayerList::default_systems()); } fn setup(mut commands: Commands, server: Res<Server>) { let mut instance = server.new_instance(DimensionId::default()); for z in -5..5 { for x in -5..5 { instance.insert_chunk([x, z], Chunk::default()); } } for z in -25..25 { for x in -25..25 { instance.set_block([x, SPAWN_Y, z], BlockState::GRASS_BLOCK); } } commands.spawn(instance); } fn init_clients( mut clients: Query<&mut Client, Added<Client>>, instances: Query<Entity, With<Instance>>, ) { for mut client in &mut clients { client.set_position([0.0, SPAWN_Y as f64 + 1.0, 0.0]); client.set_instance(instances.single()); client.set_game_mode(GameMode::Creative); } } // Add new systems here! fn scoreboard(mut clients: Query<&mut Client, Added<Client>>) { for mut client in &mut clients { client.write_packet(&ScoreboardObjectiveUpdateS2c { objective_name: "sidebar", mode: Mode::Create { objective_display_name: "Sidebar".into_text(), render_type: RenderType::Integer, }, }); client.write_packet(&ScoreboardPlayerUpdateS2c { action: Action::Update { objective_score: VarInt(42), objective_name: "sidebar", }, entity_name: "name", }); client.write_packet(&ScoreboardDisplayS2c { position: ScoreboardPosition::Sidebar, // Position is now an Enum score_name: "sidebar", }); } } ``` </details> --------- Co-authored-by: Ryan Johnson <ryanj00a@gmail.com>
This commit is contained in:
parent
41907261e3
commit
68cf6e83a0
|
@ -1,7 +1,74 @@
|
||||||
use crate::{Decode, Encode};
|
use crate::{Decode, Encode};
|
||||||
|
|
||||||
|
use super::team::TeamColor;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Encode, Decode)]
|
#[derive(Copy, Clone, Debug, Encode, Decode)]
|
||||||
pub struct ScoreboardDisplayS2c<'a> {
|
pub struct ScoreboardDisplayS2c<'a> {
|
||||||
pub position: u8,
|
pub position: ScoreboardPosition,
|
||||||
pub score_name: &'a str,
|
pub score_name: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
pub enum ScoreboardPosition {
|
||||||
|
List,
|
||||||
|
Sidebar,
|
||||||
|
BelowName,
|
||||||
|
SidebarTeam(TeamColor),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for ScoreboardPosition {
|
||||||
|
fn encode(&self, w: impl std::io::Write) -> anyhow::Result<()> {
|
||||||
|
match self {
|
||||||
|
ScoreboardPosition::List => 0u8.encode(w),
|
||||||
|
ScoreboardPosition::Sidebar => 1u8.encode(w),
|
||||||
|
ScoreboardPosition::BelowName => 2u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Black) => 3u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue) => 4u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen) => 5u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan) => 6u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::DarkRed) => 7u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Purple) => 8u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Gold) => 9u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Gray) => 10u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::DarkGray) => 11u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Blue) => 12u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen) => 13u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Cyan) => 14u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Red) => 15u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Pink) => 16u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::Yellow) => 17u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(TeamColor::White) => 18u8.encode(w),
|
||||||
|
ScoreboardPosition::SidebarTeam(_) => {
|
||||||
|
Err(anyhow::anyhow!("Invalid scoreboard display position"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Decode<'a> for ScoreboardPosition {
|
||||||
|
fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
|
||||||
|
let value = u8::decode(r)?;
|
||||||
|
match value {
|
||||||
|
0 => Ok(ScoreboardPosition::List),
|
||||||
|
1 => Ok(ScoreboardPosition::Sidebar),
|
||||||
|
2 => Ok(ScoreboardPosition::BelowName),
|
||||||
|
3 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Black)),
|
||||||
|
4 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue)),
|
||||||
|
5 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen)),
|
||||||
|
6 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan)),
|
||||||
|
7 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkRed)),
|
||||||
|
8 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Purple)),
|
||||||
|
9 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gold)),
|
||||||
|
10 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gray)),
|
||||||
|
11 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGray)),
|
||||||
|
12 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Blue)),
|
||||||
|
13 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen)),
|
||||||
|
14 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Cyan)),
|
||||||
|
15 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Red)),
|
||||||
|
16 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Pink)),
|
||||||
|
17 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Yellow)),
|
||||||
|
18 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::White)),
|
||||||
|
_ => Err(anyhow::anyhow!("Invalid scoreboard display position")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue