Advancement's reset flag (#331)

## Description

Added a new reset flag, which resets all old advancements and don't show
a toast for already completed advancements

## Test Plan

Use example "advancements". Now it saves old progress of player
This commit is contained in:
Jenya705 2023-05-07 04:54:34 +02:00 committed by GitHub
parent 41bcd1eb2c
commit 161d523018
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 12 deletions

View file

@ -1,6 +1,9 @@
use std::collections::HashMap;
use valence::prelude::*; use valence::prelude::*;
use valence_advancement::bevy_hierarchy::{BuildChildren, Children, Parent}; use valence_advancement::bevy_hierarchy::{BuildChildren, Children, Parent};
use valence_advancement::ForceTabUpdate; use valence_advancement::ForceTabUpdate;
use valence_client::SpawnClientsSet;
#[derive(Component)] #[derive(Component)]
struct RootCriteria; struct RootCriteria;
@ -17,11 +20,23 @@ struct RootCriteriaDone(bool);
#[derive(Component)] #[derive(Component)]
struct TabChangeCount(u8); struct TabChangeCount(u8);
#[derive(Resource, Default)]
struct ClientSave(HashMap<Uuid, (bool, u8)>);
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.init_resource::<ClientSave>()
.add_startup_system(setup) .add_startup_system(setup)
.add_systems((init_clients, init_advancements, sneak, tab_change)) .add_systems((
init_clients,
init_advancements,
sneak,
tab_change,
load_clients
.after(SpawnClientsSet)
.in_base_set(CoreSet::PreUpdate),
))
.run(); .run();
} }
@ -149,33 +164,62 @@ fn setup(
} }
fn init_clients( fn init_clients(
mut commands: Commands, mut clients: Query<(&mut Location, &mut Position, &mut GameMode), Added<Client>>,
mut clients: Query<(Entity, &mut Location, &mut Position, &mut GameMode), Added<Client>>,
instances: Query<Entity, With<Instance>>, instances: Query<Entity, With<Instance>>,
) { ) {
for (client, mut loc, mut pos, mut game_mode) in &mut clients { for (mut loc, mut pos, mut game_mode) in &mut clients {
loc.0 = instances.single(); loc.0 = instances.single();
pos.set([0.5, 65.0, 0.5]); pos.set([0.5, 65.0, 0.5]);
*game_mode = GameMode::Creative; *game_mode = GameMode::Creative;
commands }
.entity(client) }
.insert((RootCriteriaDone(false), TabChangeCount(0)));
fn load_clients(
mut commands: Commands,
clients: Query<(Entity, &UniqueId), Added<Client>>,
mut client_save: ResMut<ClientSave>,
) {
for (client, uuid) in clients.iter() {
let (root_criteria_done, tab_change_count) =
client_save.0.entry(uuid.0).or_insert((false, 0));
commands.entity(client).insert((
RootCriteriaDone(*root_criteria_done),
TabChangeCount(*tab_change_count),
));
} }
} }
fn init_advancements( fn init_advancements(
mut clients: Query<&mut AdvancementClientUpdate, Added<AdvancementClientUpdate>>, mut clients: Query<
(
&mut AdvancementClientUpdate,
&RootCriteriaDone,
&TabChangeCount,
),
Added<AdvancementClientUpdate>,
>,
root_advancement_query: Query<Entity, (Without<Parent>, With<Advancement>)>, root_advancement_query: Query<Entity, (Without<Parent>, With<Advancement>)>,
children_query: Query<&Children>, children_query: Query<&Children>,
advancement_check_query: Query<(), With<Advancement>>, advancement_check_query: Query<(), With<Advancement>>,
root2_criteria: Query<Entity, With<Root2Criteria>>,
root_criteria: Query<Entity, With<RootCriteria>>,
) { ) {
for mut advancement_client_update in clients.iter_mut() { let root_c = root_criteria.single();
let root2_c = root2_criteria.single();
for (mut advancement_client_update, root_criteria, tab_change) in clients.iter_mut() {
for root_advancement in root_advancement_query.iter() { for root_advancement in root_advancement_query.iter() {
advancement_client_update.send_advancements( advancement_client_update.send_advancements(
root_advancement, root_advancement,
&children_query, &children_query,
&advancement_check_query, &advancement_check_query,
); );
if root_criteria.0 {
advancement_client_update.criteria_done(root_c);
}
if tab_change.0 > 5 {
advancement_client_update.criteria_done(root2_c);
}
} }
} }
} }
@ -184,6 +228,8 @@ fn sneak(
mut sneaking: EventReader<Sneaking>, mut sneaking: EventReader<Sneaking>,
mut client: Query<(&mut AdvancementClientUpdate, &mut RootCriteriaDone)>, mut client: Query<(&mut AdvancementClientUpdate, &mut RootCriteriaDone)>,
root_criteria: Query<Entity, With<RootCriteria>>, root_criteria: Query<Entity, With<RootCriteria>>,
client_uuid: Query<&UniqueId>,
mut client_save: ResMut<ClientSave>,
) { ) {
let root_criteria = root_criteria.single(); let root_criteria = root_criteria.single();
for sneaking in sneaking.iter() { for sneaking in sneaking.iter() {
@ -196,6 +242,11 @@ fn sneak(
true => advancement_client_update.criteria_done(root_criteria), true => advancement_client_update.criteria_done(root_criteria),
false => advancement_client_update.criteria_undone(root_criteria), false => advancement_client_update.criteria_undone(root_criteria),
} }
client_save
.0
.get_mut(&client_uuid.get(sneaking.client).unwrap().0)
.unwrap()
.0 = root_criteria_done.0;
} }
} }
@ -204,6 +255,8 @@ fn tab_change(
mut client: Query<(&mut AdvancementClientUpdate, &mut TabChangeCount)>, mut client: Query<(&mut AdvancementClientUpdate, &mut TabChangeCount)>,
root2_criteria: Query<Entity, With<Root2Criteria>>, root2_criteria: Query<Entity, With<Root2Criteria>>,
root: Query<Entity, With<RootAdvancement>>, root: Query<Entity, With<RootAdvancement>>,
client_uuid: Query<&UniqueId>,
mut client_save: ResMut<ClientSave>,
) { ) {
let root2_criteria = root2_criteria.single(); let root2_criteria = root2_criteria.single();
let root = root.single(); let root = root.single();
@ -223,5 +276,10 @@ fn tab_change(
} else if tab_change_count.0 >= 10 { } else if tab_change_count.0 >= 10 {
advancement_client_update.force_tab_update = ForceTabUpdate::Spec(root); advancement_client_update.force_tab_update = ForceTabUpdate::Spec(root);
} }
client_save
.0
.get_mut(&client_uuid.get(tab_change.client).unwrap().0)
.unwrap()
.1 = tab_change_count.0;
} }
} }

View file

@ -215,10 +215,11 @@ impl<'w, 's, 'a> Encode for AdvancementUpdateEncodeS2c<'w, 's, 'a> {
remove_advancements, remove_advancements,
progress, progress,
force_tab_update: _, force_tab_update: _,
reset,
} = &self.client_update; } = &self.client_update;
let mut pkt = GenericAdvancementUpdateS2c { let mut pkt = GenericAdvancementUpdateS2c {
reset: false, reset: *reset,
advancement_mapping: vec![], advancement_mapping: vec![],
identifiers: vec![], identifiers: vec![],
progress_mapping: vec![], progress_mapping: vec![],
@ -313,11 +314,18 @@ fn send_advancement_update_packet(
if advancement_client_update.new_advancements.is_empty() if advancement_client_update.new_advancements.is_empty()
&& advancement_client_update.progress.is_empty() && advancement_client_update.progress.is_empty()
&& advancement_client_update.remove_advancements.is_empty() && advancement_client_update.remove_advancements.is_empty()
&& !advancement_client_update.reset
{ {
continue; continue;
} }
let advancement_client_update = std::mem::take(advancement_client_update.as_mut()); let advancement_client_update = std::mem::replace(
advancement_client_update.as_mut(),
AdvancementClientUpdate {
reset: false,
..Default::default()
},
);
client.write_packet(&AdvancementUpdateEncodeS2c { client.write_packet(&AdvancementUpdateEncodeS2c {
queries: &update_single_query, queries: &update_single_query,
@ -403,7 +411,7 @@ pub enum ForceTabUpdate {
Spec(Entity), Spec(Entity),
} }
#[derive(Component, Default, Debug)] #[derive(Component, Debug)]
pub struct AdvancementClientUpdate { pub struct AdvancementClientUpdate {
/// Which advancement's descriptions send to client /// Which advancement's descriptions send to client
pub new_advancements: Vec<Entity>, pub new_advancements: Vec<Entity>,
@ -414,6 +422,22 @@ pub struct AdvancementClientUpdate {
pub progress: Vec<(Entity, Option<i64>)>, pub progress: Vec<(Entity, Option<i64>)>,
/// Forces client to open a tab /// Forces client to open a tab
pub force_tab_update: ForceTabUpdate, pub force_tab_update: ForceTabUpdate,
/// Defines if other advancements should be removed.
/// Also with this flag, client will not show a toast for advancements,
/// which are completed. When the packet is sent, turns to false
pub reset: bool,
}
impl Default for AdvancementClientUpdate {
fn default() -> Self {
Self {
new_advancements: vec![],
remove_advancements: vec![],
progress: vec![],
force_tab_update: ForceTabUpdate::default(),
reset: true,
}
}
} }
impl AdvancementClientUpdate { impl AdvancementClientUpdate {