Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boss Bar API #371

Merged
merged 26 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
174bf05
Created valence_boss_bar crates and created the BossBar entity
Jun 16, 2023
9f0e790
Changed BossBarViewers struct's wrapped value
Jun 16, 2023
18924d8
Added boss bar despawn handler; Added project in workspace; Organized…
Jun 17, 2023
cfb7dca
Removed boss_bar test file from the module tree (it's not done yet)
Jun 17, 2023
eeda50f
Turned BossBar component into a Bundle; Edited the despawn handler
Jun 17, 2023
1992d1d
Added unit tests; Changed BossBarViewers component; Added Boss bar at…
Jun 17, 2023
ff97d90
Merge branch 'valence-rs:main' into main
pepperoni21 Jun 17, 2023
8991cc7
Code documentation; Removed useless methods
Jun 17, 2023
9b5039d
Handled player disconnection; Renaming
Jun 17, 2023
fa6a53b
Trying to fix clippy errors
Jun 17, 2023
d78e79a
Merge branch 'valence-rs:main' into main
pepperoni21 Jun 18, 2023
e9314f8
Formatted code
Jun 18, 2023
ac6cd66
Edited BossBarViewers properties names
Jun 18, 2023
1731842
Fixed Cargo.toml file; Boss bar viewers are now stored in BTreeSet; R…
Jun 19, 2023
dad2eab
Ran cargo fmt and fixed clippy warnings
Jun 19, 2023
f8ef4a7
Merge branch 'main' into main
pepperoni21 Jun 19, 2023
e17c859
Updated crates/README.md
Jun 19, 2023
6a42f92
Removed boss_bar dependency from playground
Jun 19, 2023
a79e6ac
Made BossBarViewers' old_viewers field pub(crate)
Jun 19, 2023
e0cd195
Fixed systems; Added client disconnection test
Jun 19, 2023
96a98d1
Improved code
Jun 19, 2023
7826698
Ordered client_disconnection system before boss_bar_viewers_update
Jun 19, 2023
dd3c75f
Exported boss_bar in the main valence crate; Added an example
Jun 20, 2023
6b62de6
Formatted code
Jun 20, 2023
6eb672f
Merge remote-tracking branch 'upstream/main'
Jun 20, 2023
4c77468
Fixed clippy error
Jun 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/valence/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,9 @@ impl_packet_list!(A, B, C, D, E, F, G, H, I);
impl_packet_list!(A, B, C, D, E, F, G, H, I, J);
impl_packet_list!(A, B, C, D, E, F, G, H, I, J, K);

mod boss_bar;
mod client;
mod example;
mod inventory;
mod weather;
mod world_border;
mod world_border;
177 changes: 154 additions & 23 deletions crates/valence/src/tests/boss_bar.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,178 @@
use bevy_app::App;
use bevy_ecs::entity::Entity;
use valence_boss_bar::components::{BossBar, BossBarColor, BossBarDivision, BossBarFlags};
use valence_boss_bar::components::{
BossBarBundle, BossBarColor, BossBarDivision, BossBarFlags, BossBarHealth, BossBarStyle,
BossBarTitle, BossBarViewers,
};
use valence_boss_bar::packet::BossBarS2c;
use valence_core::despawn::Despawned;
use valence_core::text::Text;
use valence_instance::Instance;

use super::{MockClientHelper, scenario_single_client, create_mock_client};
use super::{scenario_single_client, MockClientHelper};

/*#[test]
#[test]
fn test_intialize_on_join() {
let mut app = App::new();
let (_, instance_ent) = prepare(&mut app);
let (client_ent, mut client_helper, instance_ent) = prepare(&mut app);

let (mut client, mut client_helper) = create_mock_client();
let client_ent = app.world.spawn(client).id();
// Fetch the boss bar component
let mut boss_bar = app.world.get_mut::<BossBarViewers>(instance_ent).unwrap();
// Add our mock client to the viewers list
boss_bar.current_viewers.push(client_ent);

}*/
app.update();

// Check if a boss bar packet was sent
let frames = client_helper.collect_sent();
frames.assert_count::<BossBarS2c>(1);
}

#[test]
fn test_despawn() {
let mut app = App::new();
let (client_ent, mut client_helper, instance_ent) = prepare(&mut app);

// Fetch the boss bar component
let mut boss_bar = app.world.get_mut::<BossBarViewers>(instance_ent).unwrap();
// Add our mock client to the viewers list
boss_bar.current_viewers.push(client_ent);

app.update();

// Despawn the boss bar
app.world.entity_mut(instance_ent).insert(Despawned);

app.update();

// Check if a boss bar packet was sent in addition to the ADD packet, which
// should be a Remove packet
let frames = client_helper.collect_sent();
frames.assert_count::<BossBarS2c>(2);
pepperoni21 marked this conversation as resolved.
Show resolved Hide resolved
}

#[test]
fn test_title_update() {
let mut app = App::new();
let (client_ent, mut client_helper, instance_ent) = prepare(&mut app);

// Fetch the boss bar component
let mut boss_bar = app.world.get_mut::<BossBarViewers>(instance_ent).unwrap();
// Add our mock client to the viewers list
boss_bar.current_viewers.push(client_ent);

app.update();

// Update the title
app.world
.entity_mut(instance_ent)
.insert(BossBarTitle(Text::text("Test 2")));

app.update();

// Check if a boss bar packet was sent in addition to the ADD packet, which
// should be an UpdateTitle packet
let frames = client_helper.collect_sent();
frames.assert_count::<BossBarS2c>(2);
}

#[test]
fn test_health_update() {
let mut app = App::new();
let (client_ent, mut client_helper, instance_ent) = prepare(&mut app);

// Fetch the boss bar component
let mut boss_bar = app.world.get_mut::<BossBarViewers>(instance_ent).unwrap();
// Add our mock client to the viewers list
boss_bar.current_viewers.push(client_ent);

app.update();

// Update the health
app.world
.entity_mut(instance_ent)
.insert(BossBarHealth(0.5));

app.update();

// Check if a boss bar packet was sent in addition to the ADD packet, which
// should be an UpdateHealth packet
let frames = client_helper.collect_sent();
frames.assert_count::<BossBarS2c>(2);
}

#[test]
fn test_style_update() {
let mut app = App::new();
let (client_ent, mut client_helper, instance_ent) = prepare(&mut app);

// Fetch the boss bar component
let mut boss_bar = app.world.get_mut::<BossBarViewers>(instance_ent).unwrap();
// Add our mock client to the viewers list
boss_bar.current_viewers.push(client_ent);

app.update();

// Update the style
app.world.entity_mut(instance_ent).insert(BossBarStyle {
color: BossBarColor::Red,
division: BossBarDivision::TenNotches,
});

app.update();

// Check if a boss bar packet was sent in addition to the ADD packet, which
// should be an UpdateStyle packet
let frames = client_helper.collect_sent();
frames.assert_count::<BossBarS2c>(2);
}

#[test]
fn test_flags_update() {
let mut app = App::new();
let (client_ent, mut client_helper, instance_ent) = prepare(&mut app);

// Fetch the boss bar component
let mut boss_bar = app.world.get_mut::<BossBarViewers>(instance_ent).unwrap();
// Add our mock client to the viewers list
boss_bar.current_viewers.push(client_ent);

app.update();

// Update the flags
let mut new_flags = BossBarFlags::new();
new_flags.set_create_fog(true);
app.world.entity_mut(instance_ent).insert(new_flags);

app.update();

// Check if a boss bar packet was sent in addition to the ADD packet, which
// should be an UpdateFlags packet
let frames = client_helper.collect_sent();
frames.assert_count::<BossBarS2c>(2);
}

fn prepare(app: &mut App) -> (MockClientHelper, Entity) {
let (_, mut client_helper) = scenario_single_client(app);
fn prepare(app: &mut App) -> (Entity, MockClientHelper, Entity) {
let (client_ent, mut client_helper) = scenario_single_client(app);

// Process a tick to get past the "on join" logic.
app.update();
client_helper.clear_sent();

// Get the instance entity.
let instance_ent = app
// Insert a boss bar into the world
let boss_bar = app
.world
.iter_entities()
.find(|e| e.contains::<Instance>())
.expect("could not find instance")
.spawn(BossBarBundle::new(
Text::text("Test"),
BossBarColor::Blue,
BossBarDivision::SixNotches,
BossBarFlags::new(),
))
.id();

// Insert a boss bar to the instance.
app.world.entity_mut(instance_ent).insert(
BossBar::new(Text::text(""),
BossBarColor::Red,
BossBarDivision::SixNotches,
BossBarFlags::new()));

for _ in 0..2 {
app.update();
}

client_helper.clear_sent();
(client_helper, instance_ent)
(client_ent, client_helper, boss_bar)
}
42 changes: 30 additions & 12 deletions crates/valence_boss_bar/src/components.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use bevy_ecs::prelude::{Component, Entity, Bundle};
use valence_core::{uuid::UniqueId, text::Text, protocol::{Encode, Decode}};
use bevy_ecs::prelude::{Bundle, Component, Entity};
use bitfield_struct::bitfield;
use valence_core::protocol::{Decode, Encode};
use valence_core::text::Text;
use valence_core::uuid::UniqueId;

/// The bundle of components that make up a boss bar.
#[derive(Bundle)]
pub struct BossBarBundle {
pub id: UniqueId,
Expand All @@ -13,35 +16,40 @@ pub struct BossBarBundle {
}

impl BossBarBundle {

pub fn new(title: Text, color: BossBarColor, division: BossBarDivision, flags: BossBarFlags) -> BossBarBundle {
pub fn new(
title: Text,
color: BossBarColor,
division: BossBarDivision,
flags: BossBarFlags,
) -> BossBarBundle {
BossBarBundle {
id: UniqueId::default(),
title: BossBarTitle(title),
health: BossBarHealth(1.0),
style: BossBarStyle {
color,
division,
},
style: BossBarStyle { color, division },
flags,
viewers: BossBarViewers(Vec::new()),
viewers: BossBarViewers::default(),
}
}

}

/// The title of a boss bar.
#[derive(Component, Clone)]
pub struct BossBarTitle(pub Text);

/// The health of a boss bar.
#[derive(Component)]
pub struct BossBarHealth(pub f32);

/// The style of a boss bar. This includes the color and division of the boss
/// bar.
#[derive(Component)]
pub struct BossBarStyle {
pub color: BossBarColor,
pub division: BossBarDivision,
}

/// The color of a boss bar.
#[derive(Component, Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
pub enum BossBarColor {
Pink,
Expand All @@ -53,6 +61,7 @@ pub enum BossBarColor {
White,
}

/// The division of a boss bar.
#[derive(Component, Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
pub enum BossBarDivision {
NoDivision,
Expand All @@ -62,6 +71,7 @@ pub enum BossBarDivision {
TwentyNotches,
}

/// The flags of a boss bar (darken sky, dragon bar, create fog).
#[bitfield(u8)]
#[derive(Component, PartialEq, Eq, Encode, Decode)]
pub struct BossBarFlags {
Expand All @@ -72,5 +82,13 @@ pub struct BossBarFlags {
_pad: u8,
}

#[derive(Component)]
pub struct BossBarViewers(pub Vec<Entity>);
/// The viewers of a boss bar.
#[derive(Component, Default)]
pub struct BossBarViewers {
/// The current viewers of the boss bar. It is the list that should be
/// updated.
pub current_viewers: Vec<Entity>,
pepperoni21 marked this conversation as resolved.
Show resolved Hide resolved
/// The viewers of the last tick in order to determine which viewers have
/// been added and removed.
pub last_viewers: Vec<Entity>,
}
pepperoni21 marked this conversation as resolved.
Show resolved Hide resolved
Loading