valence/crates/valence_protocol
AviiNL 68cf6e83a0
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>
2023-03-12 04:51:49 -07:00
..
benches Refactor valence_protocol (#253) 2023-02-23 22:16:22 -08:00
build Provide API for getting the wall variant of blocks (#255) 2023-02-23 21:21:27 -08:00
src Abstract scoreboard display position (#286) 2023-03-12 04:51:49 -07:00
Cargo.toml ECS Rewrite (#184) 2023-02-11 09:51:53 -08:00