mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-23 14:31:30 +11:00
c5557e744d
## Description - Move all packets out of `valence_core` and into the places where they're actually used. This has a few benefits: - Avoids compiling code for packets that go unused when feature flags are disabled. - Code is distributed more uniformly across crates, improving compilation times. - Improves local reasoning when everything relevant to a module is defined in the same place. - Easier to share code between the packet consumer and the packet. - Tweak `Packet` macro syntax. - Update `syn` to 2.0. - Reorganize some code in `valence_client` (needs further work). - Impl `WritePacket` for `Instance`. - Remove packet enums such as `S2cPlayPacket` and `C2sPlayPacket`. - Replace `assert_packet_count` and `assert_packet_order` macros with non-macro methods. To prevent this PR from getting out of hand, I've disabled the packet inspector and stresser until they have been rewritten to account for these changes.
225 lines
6.5 KiB
Rust
225 lines
6.5 KiB
Rust
//! The weather system.
|
|
//!
|
|
//! This module contains the systems and components needed to handle
|
|
//! weather.
|
|
//!
|
|
//! # Components
|
|
//!
|
|
//! The components may be attached to clients or instances.
|
|
//!
|
|
//! - [`Rain`]: When attached, raining begin and rain level set events are
|
|
//! emitted. When removed, the end raining event is emitted.
|
|
//! - [`Thunder`]: When attached, thunder level set event is emitted. When
|
|
//! removed, the thunder level set to zero event is emitted.
|
|
//!
|
|
//! New joined players are handled, so that they are get weather events from
|
|
//! the instance.
|
|
|
|
use super::*;
|
|
use crate::packet::{GameEventKind, GameStateChangeS2c};
|
|
|
|
#[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
|
struct UpdateWeatherPerInstanceSet;
|
|
|
|
#[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
|
struct UpdateWeatherPerClientSet;
|
|
|
|
pub(super) fn build(app: &mut App) {
|
|
app.configure_set(
|
|
UpdateWeatherPerInstanceSet
|
|
.in_base_set(CoreSet::PostUpdate)
|
|
.before(WriteUpdatePacketsToInstancesSet),
|
|
)
|
|
.configure_set(
|
|
UpdateWeatherPerClientSet
|
|
.in_base_set(CoreSet::PostUpdate)
|
|
.before(FlushPacketsSet),
|
|
)
|
|
.add_systems(
|
|
(
|
|
handle_rain_begin_per_instance,
|
|
handle_rain_change_per_instance,
|
|
handle_rain_end_per_instance,
|
|
handle_thunder_change_per_instance,
|
|
handle_thunder_end_per_instance,
|
|
)
|
|
.chain()
|
|
.in_set(UpdateWeatherPerInstanceSet)
|
|
.before(UpdateWeatherPerClientSet),
|
|
)
|
|
.add_systems(
|
|
(
|
|
handle_rain_begin_per_client,
|
|
handle_rain_change_per_client,
|
|
handle_rain_end_per_client,
|
|
handle_thunder_change_per_client,
|
|
handle_thunder_end_per_client,
|
|
)
|
|
.chain()
|
|
.in_set(UpdateWeatherPerClientSet),
|
|
)
|
|
.add_system(
|
|
handle_weather_for_joined_player
|
|
.before(UpdateWeatherPerClientSet)
|
|
.in_base_set(CoreSet::PostUpdate),
|
|
);
|
|
}
|
|
|
|
/// Contains the rain level.
|
|
///
|
|
/// Valid values are within `0.0..=1.0`.
|
|
#[derive(Component)]
|
|
pub struct Rain(pub f32);
|
|
|
|
/// Contains the thunder level.
|
|
///
|
|
/// Valid values are within `0.0..=1.0`.
|
|
#[derive(Component)]
|
|
pub struct Thunder(pub f32);
|
|
|
|
fn handle_weather_for_joined_player(
|
|
mut clients: Query<(&mut Client, &Location), Added<Client>>,
|
|
weathers: Query<(Option<&Rain>, Option<&Thunder>), With<Instance>>,
|
|
) {
|
|
for (mut client, loc) in &mut clients {
|
|
if let Ok((rain, thunder)) = weathers.get(loc.0) {
|
|
if let Some(level) = rain {
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::BeginRaining,
|
|
value: 0.0,
|
|
});
|
|
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::RainLevelChange,
|
|
value: level.0,
|
|
});
|
|
}
|
|
|
|
if let Some(level) = thunder {
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::ThunderLevelChange,
|
|
value: level.0,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn handle_rain_begin_per_instance(mut instances: Query<&mut Instance, Added<Rain>>) {
|
|
for mut instance in &mut instances {
|
|
instance.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::BeginRaining,
|
|
value: f32::default(),
|
|
});
|
|
}
|
|
}
|
|
|
|
fn handle_rain_change_per_instance(mut instances: Query<(&mut Instance, &Rain), Changed<Rain>>) {
|
|
for (mut instance, rain) in &mut instances {
|
|
instance.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::RainLevelChange,
|
|
value: rain.0,
|
|
});
|
|
}
|
|
}
|
|
|
|
fn handle_rain_end_per_instance(
|
|
mut instances: Query<&mut Instance>,
|
|
mut removed: RemovedComponents<Rain>,
|
|
) {
|
|
for entity in &mut removed {
|
|
if let Ok(mut instance) = instances.get_mut(entity) {
|
|
instance.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::EndRaining,
|
|
value: 0.0,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
fn handle_thunder_change_per_instance(
|
|
mut instances: Query<(&mut Instance, &Thunder), Changed<Thunder>>,
|
|
) {
|
|
for (mut instance, thunder) in &mut instances {
|
|
instance.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::ThunderLevelChange,
|
|
value: thunder.0,
|
|
});
|
|
}
|
|
}
|
|
|
|
fn handle_thunder_end_per_instance(
|
|
mut instances: Query<&mut Instance>,
|
|
mut removed: RemovedComponents<Thunder>,
|
|
) {
|
|
for entity in &mut removed {
|
|
if let Ok(mut instance) = instances.get_mut(entity) {
|
|
instance.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::ThunderLevelChange,
|
|
value: 0.0,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
fn handle_rain_begin_per_client(mut clients: Query<&mut Client, (Added<Rain>, Without<Instance>)>) {
|
|
for mut client in &mut clients {
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::BeginRaining,
|
|
value: 0.0,
|
|
});
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
fn handle_rain_change_per_client(
|
|
mut clients: Query<(&mut Client, &Rain), (Changed<Rain>, Without<Instance>)>,
|
|
) {
|
|
for (mut client, rain) in &mut clients {
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::RainLevelChange,
|
|
value: rain.0,
|
|
});
|
|
}
|
|
}
|
|
|
|
fn handle_rain_end_per_client(
|
|
mut clients: Query<&mut Client>,
|
|
mut removed: RemovedComponents<Rain>,
|
|
) {
|
|
for entity in &mut removed {
|
|
if let Ok(mut client) = clients.get_mut(entity) {
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::EndRaining,
|
|
value: f32::default(),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
fn handle_thunder_change_per_client(
|
|
mut clients: Query<(&mut Client, &Thunder), (Changed<Thunder>, Without<Instance>)>,
|
|
) {
|
|
for (mut client, thunder) in &mut clients {
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::ThunderLevelChange,
|
|
value: thunder.0,
|
|
});
|
|
}
|
|
}
|
|
|
|
fn handle_thunder_end_per_client(
|
|
mut clients: Query<&mut Client, Without<Instance>>,
|
|
mut removed: RemovedComponents<Thunder>,
|
|
) {
|
|
for entity in &mut removed {
|
|
if let Ok(mut client) = clients.get_mut(entity) {
|
|
client.write_packet(&GameStateChangeS2c {
|
|
kind: GameEventKind::ThunderLevelChange,
|
|
value: 0.0,
|
|
});
|
|
}
|
|
}
|
|
}
|