valence_weather/
lib.rs
1#![doc = include_str!("../README.md")]
2
3use bevy_app::prelude::*;
4use bevy_ecs::prelude::*;
5use derive_more::{Deref, DerefMut};
6use valence_server::client::{Client, FlushPacketsSet, UpdateClientsSet, VisibleChunkLayer};
7use valence_server::protocol::packets::play::game_state_change_s2c::GameEventKind;
8use valence_server::protocol::packets::play::GameStateChangeS2c;
9use valence_server::protocol::WritePacket;
10use valence_server::ChunkLayer;
11
12pub struct WeatherPlugin;
13
14impl Plugin for WeatherPlugin {
15 fn build(&self, app: &mut App) {
16 app.add_systems(
17 PostUpdate,
18 (
19 init_weather_on_layer_join,
20 change_client_rain_level,
21 change_client_thunder_level,
22 )
23 .before(FlushPacketsSet),
24 )
25 .add_systems(
26 PostUpdate,
27 (change_layer_rain_level, change_layer_thunder_level).before(UpdateClientsSet),
28 );
29 }
30}
31
32#[derive(Bundle, Default, PartialEq, PartialOrd)]
35pub struct WeatherBundle {
36 pub rain: Rain,
37 pub thunder: Thunder,
38}
39
40#[derive(Component, Default, PartialEq, PartialOrd, Deref, DerefMut)]
43pub struct Rain(pub f32);
44
45#[derive(Component, Default, PartialEq, PartialOrd, Deref, DerefMut)]
48pub struct Thunder(pub f32);
49
50fn init_weather_on_layer_join(
51 mut clients: Query<(&mut Client, &VisibleChunkLayer), Changed<VisibleChunkLayer>>,
52 layers: Query<(Option<&Rain>, Option<&Thunder>), With<ChunkLayer>>,
53) {
54 for (mut client, visible_chunk_layer) in &mut clients {
55 if let Ok((rain, thunder)) = layers.get(visible_chunk_layer.0) {
56 if let Some(rain) = rain {
57 if rain.0 != 0.0 {
58 client.write_packet(&GameStateChangeS2c {
59 kind: GameEventKind::RainLevelChange,
60 value: rain.0,
61 });
62 }
63 }
64
65 if let Some(thunder) = thunder {
66 if thunder.0 != 0.0 {
67 client.write_packet(&GameStateChangeS2c {
68 kind: GameEventKind::ThunderLevelChange,
69 value: thunder.0,
70 });
71 }
72 }
73 }
74 }
75}
76
77fn change_layer_rain_level(
78 mut layers: Query<(&mut ChunkLayer, &Rain), (Changed<Rain>, Without<Client>)>,
79) {
80 for (mut layer, rain) in &mut layers {
81 layer.write_packet(&GameStateChangeS2c {
82 kind: GameEventKind::RainLevelChange,
83 value: rain.0,
84 });
85 }
86}
87
88fn change_layer_thunder_level(
89 mut layers: Query<(&mut ChunkLayer, &Thunder), (Changed<Thunder>, Without<Client>)>,
90) {
91 for (mut layer, thunder) in &mut layers {
92 layer.write_packet(&GameStateChangeS2c {
93 kind: GameEventKind::ThunderLevelChange,
94 value: thunder.0,
95 });
96 }
97}
98
99fn change_client_rain_level(mut clients: Query<(&mut Client, &Rain), Changed<Rain>>) {
100 for (mut client, rain) in &mut clients {
101 client.write_packet(&GameStateChangeS2c {
102 kind: GameEventKind::RainLevelChange,
103 value: rain.0,
104 });
105 }
106}
107
108fn change_client_thunder_level(mut clients: Query<(&mut Client, &Thunder), Changed<Thunder>>) {
109 for (mut client, thunder) in &mut clients {
110 client.write_packet(&GameStateChangeS2c {
111 kind: GameEventKind::RainLevelChange,
112 value: thunder.0,
113 });
114 }
115}