From 9b91629f33034dab27fe10f953bd39b6477fcac2 Mon Sep 17 00:00:00 2001 From: core Date: Wed, 2 Jul 2025 23:31:44 -0400 Subject: [PATCH] chore(lint): lint/format --- crates/unified/Cargo.toml | 2 +- crates/unified/src/client/incoming_parts.rs | 21 +- crates/unified/src/client/incoming_planets.rs | 30 ++- crates/unified/src/client/key_input.rs | 6 +- crates/unified/src/client/mod.rs | 177 ++++++++++------- crates/unified/src/client/starfield.rs | 188 +++++++++++++----- crates/unified/src/client_plugins.rs | 25 +-- crates/unified/src/config/mod.rs | 2 +- crates/unified/src/config/planet.rs | 11 +- crates/unified/src/config/world.rs | 4 +- crates/unified/src/ecs.rs | 5 +- crates/unified/src/main.rs | 46 +++-- crates/unified/src/server/gravity.rs | 19 +- crates/unified/src/server/mod.rs | 97 +++++---- crates/unified/src/server/planets.rs | 88 +++++--- crates/unified/src/server/player.rs | 100 +++++++--- crates/unified/src/server/world_config.rs | 26 +-- crates/unified/src/server_plugins.rs | 26 +-- crates/unified/src/shared_plugins.rs | 20 +- 19 files changed, 541 insertions(+), 352 deletions(-) diff --git a/crates/unified/Cargo.toml b/crates/unified/Cargo.toml index 0b116a9baae8fbfa8116469b9c17c342d7523e6d..83daeb138ce2841bb2571b6e0ee10865b0c568b4 100644 --- a/crates/unified/Cargo.toml +++ b/crates/unified/Cargo.toml @@ -27,6 +27,6 @@ getrandom = { version = "0.3", features = [] } tokio = { version = "1", features = ["rt-multi-thread"] } [features] -default = [] +default = ["native"] native = ["bevy/file_watcher", "bevy_replicon_renet2/native_transport", "bevy_replicon_renet2/ws_server_transport"] wasm = ["getrandom/wasm_js", "bevy_replicon_renet2/ws_client_transport"] \ No newline at end of file diff --git a/crates/unified/src/client/incoming_parts.rs b/crates/unified/src/client/incoming_parts.rs index aac1ffb105e468e2885e2d74c7d48a4cab226278..809dadc91dc065f33af57ab0b64e21c1e04abc30 100644 --- a/crates/unified/src/client/incoming_parts.rs +++ b/crates/unified/src/client/incoming_parts.rs @@ -1,19 +1,23 @@ +use crate::ecs::Part; use bevy::prelude::*; use bevy_rapier2d::dynamics::MassProperties; use bevy_rapier2d::prelude::{AdditionalMassProperties, ReadMassProperties, RigidBody}; -use crate::config::planet::Planet; -use crate::ecs::Part; pub fn incoming_parts_plugin(app: &mut App) { app.add_systems(Update, (handle_incoming_parts, handle_updated_parts)); } -fn handle_incoming_parts(mut commands: Commands, mut new_parts: Query<(Entity, &Part), Added>, asset_server: Res) { +fn handle_incoming_parts( + mut commands: Commands, + new_parts: Query<(Entity, &Part), Added>, + asset_server: Res, +) { for (new_entity, new_part) in new_parts.iter() { let mut sprite = Sprite::from_image(asset_server.load(&new_part.sprite)); sprite.custom_size = Some(Vec2::new(new_part.width, new_part.height)); - commands.entity(new_entity) + commands + .entity(new_entity) .insert(sprite) .insert(AdditionalMassProperties::MassProperties(MassProperties { local_center_of_mass: Vec2::ZERO, @@ -25,12 +29,17 @@ fn handle_incoming_parts(mut commands: Commands, mut new_parts: Query<(Entity, & info!(?new_part, "prepared new part"); } } -fn handle_updated_parts(mut commands: Commands, mut updated_parts: Query<(Entity, &Part), Changed>, asset_server: Res) { +fn handle_updated_parts( + mut commands: Commands, + updated_parts: Query<(Entity, &Part), Changed>, + asset_server: Res, +) { for (updated_entity, updated_part) in updated_parts.iter() { let mut sprite = Sprite::from_image(asset_server.load(&updated_part.sprite)); sprite.custom_size = Some(Vec2::new(updated_part.width, updated_part.height)); - commands.entity(updated_entity) + commands + .entity(updated_entity) .remove::() .remove::() .insert(sprite) diff --git a/crates/unified/src/client/incoming_planets.rs b/crates/unified/src/client/incoming_planets.rs index d2c3baf8327f393767bd8c2dc1fd9779445f39f5..1ca421495b66caef5e049121e60cac7eacd23e0f 100644 --- a/crates/unified/src/client/incoming_planets.rs +++ b/crates/unified/src/client/incoming_planets.rs @@ -1,33 +1,45 @@ +use crate::config::planet::Planet; use bevy::prelude::*; use bevy_rapier2d::prelude::AdditionalMassProperties; -use crate::config::planet::Planet; pub fn incoming_planets_plugin(app: &mut App) { app.add_systems(Update, (handle_incoming_planets, handle_updated_planets)); } - -fn handle_incoming_planets(mut commands: Commands, mut new_planets: Query<(Entity, &Planet), Added>, asset_server: Res) { +fn handle_incoming_planets( + mut commands: Commands, + new_planets: Query<(Entity, &Planet), Added>, + asset_server: Res, +) { for (new_entity, new_planet) in new_planets.iter() { let mut sprite = Sprite::from_image(asset_server.load(&new_planet.sprite)); - sprite.custom_size = Some(Vec2::new(new_planet.radius*2.0, new_planet.radius*2.0)); + sprite.custom_size = Some(Vec2::new(new_planet.radius * 2.0, new_planet.radius * 2.0)); - commands.entity(new_entity) + commands + .entity(new_entity) .insert(sprite) .insert(AdditionalMassProperties::Mass(new_planet.mass)); info!(?new_planet, "prepared new planet"); } } -fn handle_updated_planets(mut commands: Commands, mut updated_planets: Query<(Entity, &Planet), Changed>, asset_server: Res) { +fn handle_updated_planets( + mut commands: Commands, + updated_planets: Query<(Entity, &Planet), Changed>, + asset_server: Res, +) { for (updated_entity, updated_planet) in updated_planets.iter() { let mut sprite = Sprite::from_image(asset_server.load(&updated_planet.sprite)); - sprite.custom_size = Some(Vec2::new(updated_planet.radius*2.0, updated_planet.radius*2.0)); + sprite.custom_size = Some(Vec2::new( + updated_planet.radius * 2.0, + updated_planet.radius * 2.0, + )); - commands.entity(updated_entity) + commands + .entity(updated_entity) .remove::() .remove::() .insert(sprite) .insert(AdditionalMassProperties::Mass(updated_planet.mass)); info!(?updated_planet, "updated planet"); } -} \ No newline at end of file +} diff --git a/crates/unified/src/client/key_input.rs b/crates/unified/src/client/key_input.rs index 07375c318b04843ae74700c96294bb2d0b075f05..6755843c9bf1874476f2f01e0bd1cdfc4608557d 100644 --- a/crates/unified/src/client/key_input.rs +++ b/crates/unified/src/client/key_input.rs @@ -1,4 +1,8 @@ -use bevy::{app::{App, Update}, ecs::{event::EventWriter, system::Res}, input::{keyboard::KeyCode, ButtonInput}}; +use bevy::{ + app::{App, Update}, + ecs::{event::EventWriter, system::Res}, + input::{ButtonInput, keyboard::KeyCode}, +}; use crate::ecs::ThrustEvent; diff --git a/crates/unified/src/client/mod.rs b/crates/unified/src/client/mod.rs index 92abe5da54db354da1480e5a747cdff1391d3ea8..c840e55da91d64b8292ccbad99946aa5a2cfa5a2 100644 --- a/crates/unified/src/client/mod.rs +++ b/crates/unified/src/client/mod.rs @@ -1,88 +1,105 @@ -mod incoming_planets; mod incoming_parts; +mod incoming_planets; mod key_input; mod starfield; -use std::net::{IpAddr, SocketAddr, UdpSocket}; -use std::time::SystemTime; -use bevy::core_pipeline::bloom::Bloom; +use crate::client::incoming_parts::incoming_parts_plugin; +use crate::client::incoming_planets::incoming_planets_plugin; +use crate::client::key_input::key_input_plugin; +use crate::client::starfield::starfield_plugin; +use crate::ecs::{CursorWorldCoordinates, MainCamera, Player}; use bevy::core_pipeline::fxaa::Fxaa; -use bevy::core_pipeline::tonemapping::Tonemapping; use bevy::prelude::*; use bevy::window::PrimaryWindow; -use bevy_rapier2d::prelude::RigidBody; -use bevy_replicon::prelude::{ConnectedClient, RepliconChannels}; +use bevy_replicon::prelude::RepliconChannels; use bevy_replicon::shared::server_entity_map::ServerEntityMap; -use bevy_replicon_renet2::netcode::{ClientAuthentication, NetcodeClientTransport}; +use bevy_replicon_renet2::RenetChannelsExt; #[cfg(not(target_arch = "wasm32"))] use bevy_replicon_renet2::netcode::NativeSocket; +use bevy_replicon_renet2::netcode::{ClientAuthentication, NetcodeClientTransport}; #[cfg(target_arch = "wasm32")] -use bevy_replicon_renet2::netcode::{WebSocketClientConfig, WebSocketClient, ClientSocket}; +use bevy_replicon_renet2::netcode::{ClientSocket, WebSocketClient, WebSocketClientConfig}; use bevy_replicon_renet2::renet2::{ConnectionConfig, RenetClient}; -use bevy_replicon_renet2::RenetChannelsExt; -use crate::client::incoming_parts::incoming_parts_plugin; -use crate::client::incoming_planets::incoming_planets_plugin; -use crate::client::key_input::key_input_plugin; -use crate::client::starfield::starfield_plugin; -use crate::ecs::{Ball, CursorWorldCoordinates, Ground, MainCamera, Player, SendBallHere}; +use std::net::{IpAddr, SocketAddr, UdpSocket}; +use std::time::SystemTime; pub struct ClientPlugin { #[cfg(target_arch = "wasm32")] pub server: url::Url, #[cfg(not(target_arch = "wasm32"))] - pub server: SocketAddr + pub server: SocketAddr, } impl Plugin for ClientPlugin { fn build(&self, app: &mut App) { - let server = self.server.clone(); - app - .insert_resource(CursorWorldCoordinates(None)) - .add_systems(Startup, move |mut commands: Commands, channels: Res| { - let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); - let client_id = current_time.as_millis() as u64; + let server = self.server; + app.insert_resource(CursorWorldCoordinates(None)) + .add_systems( + Startup, + move |mut commands: Commands, channels: Res| { + let current_time = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); + let client_id = current_time.as_millis() as u64; - #[cfg(target_arch = "wasm32")] { - let socket_config = WebSocketClientConfig { - server_url: server.clone(), - }; - let socket = WebSocketClient::new(socket_config).unwrap(); - let client = RenetClient::new( - ConnectionConfig::from_channels(channels.server_configs(), channels.client_configs()), - socket.is_reliable() - ); - let authentication = ClientAuthentication::Unsecure { - socket_id: 1, - server_addr: socket.server_address(), - client_id: current_time.as_millis() as u64, - user_data: None, - protocol_id: 0 - }; - let mut transport = NetcodeClientTransport::new(current_time, authentication, socket).unwrap(); - commands.insert_resource(client); - commands.insert_resource(transport); - } - #[cfg(not(target_arch = "wasm32"))] { - let bind = match server.ip() { - IpAddr::V4(_) => "127.0.0.1:0", - IpAddr::V6(_) => "[::1]:0", - }; - let client_socket = NativeSocket::new(UdpSocket::bind(bind).unwrap()).unwrap(); - let authentication = ClientAuthentication::Unsecure { - socket_id: 0, - server_addr: server, - client_id: current_time.as_millis() as u64, - user_data: None, - protocol_id: 0 - }; - let client = RenetClient::new( - ConnectionConfig::from_channels(channels.server_configs(), channels.client_configs()), - false - ); - let mut transport = NetcodeClientTransport::new(current_time, authentication, client_socket).unwrap(); - commands.insert_resource(client); - commands.insert_resource(transport); - } - }) + #[cfg(target_arch = "wasm32")] + { + let socket_config = WebSocketClientConfig { + server_url: server.clone(), + }; + let socket = WebSocketClient::new(socket_config).unwrap(); + let client = RenetClient::new( + ConnectionConfig::from_channels( + channels.server_configs(), + channels.client_configs(), + ), + socket.is_reliable(), + ); + let authentication = ClientAuthentication::Unsecure { + socket_id: 1, + server_addr: socket.server_address(), + client_id: current_time.as_millis() as u64, + user_data: None, + protocol_id: 0, + }; + let mut transport = + NetcodeClientTransport::new(current_time, authentication, socket) + .unwrap(); + commands.insert_resource(client); + commands.insert_resource(transport); + } + #[cfg(not(target_arch = "wasm32"))] + { + let bind = match server.ip() { + IpAddr::V4(_) => "127.0.0.1:0", + IpAddr::V6(_) => "[::1]:0", + }; + let client_socket = + NativeSocket::new(UdpSocket::bind(bind).unwrap()).unwrap(); + let authentication = ClientAuthentication::Unsecure { + socket_id: 0, + server_addr: server, + client_id: current_time.as_millis() as u64, + user_data: None, + protocol_id: 0, + }; + let client = RenetClient::new( + ConnectionConfig::from_channels( + channels.server_configs(), + channels.client_configs(), + ), + false, + ); + let transport = NetcodeClientTransport::new( + current_time, + authentication, + client_socket, + ) + .unwrap(); + commands.insert_resource(client); + commands.insert_resource(transport); + } + }, + ) .add_systems(Startup, setup_graphics) .add_systems(Update, update_cursor_position) .add_systems(Update, follow_camera) @@ -97,8 +114,11 @@ impl Plugin for ClientPlugin { #[derive(Component)] pub struct Me; - -fn find_me(mut commands: Commands, q_clients: Query<(Entity, &Player), Added>, entity_map: Res) { +fn find_me( + mut commands: Commands, + q_clients: Query<(Entity, &Player), Added>, + entity_map: Res, +) { for (entity, player) in q_clients.iter() { let this_id_clientside = entity_map.to_client().get(&player.client).unwrap(); if *this_id_clientside == entity { @@ -107,33 +127,38 @@ fn find_me(mut commands: Commands, q_clients: Query<(Entity, &Player), Added, Without)>, mut player: Query<&Transform, With>) { +fn follow_camera( + mut camera: Query<&mut Transform, (With, Without)>, + player: Query<&Transform, With>, +) { let mut camera = camera.single_mut().unwrap(); - let Ok(player) = player.single() else { return; }; + let Ok(player) = player.single() else { + return; + }; camera.translation = player.translation; } fn update_cursor_position( q_windows: Query<&Window, With>, q_camera: Query<(&Camera, &GlobalTransform), With>, - mut coords: ResMut + mut coords: ResMut, ) { let (camera, camera_transform) = q_camera.single().unwrap(); let window = q_windows.single().unwrap(); - if let Some(world_position) = window.cursor_position() + if let Some(world_position) = window + .cursor_position() .and_then(|cursor| camera.viewport_to_world(camera_transform, cursor).ok()) - .map(|ray| ray.origin.truncate()) { + .map(|ray| ray.origin.truncate()) + { coords.0 = Some(world_position); } else { coords.0 = None; diff --git a/crates/unified/src/client/starfield.rs b/crates/unified/src/client/starfield.rs index b31ea875c6789fe95f018076bca2882f31f2fe52..f51f5cad56f26df8c5f4208f17725cb718659499 100644 --- a/crates/unified/src/client/starfield.rs +++ b/crates/unified/src/client/starfield.rs @@ -1,14 +1,29 @@ -use bevy::{app::{App, Startup, Update}, asset::{AssetEvent, AssetServer, Assets}, color::Color, ecs::{event::EventReader, query::{With, Without}, system::{Commands, Query, Res, ResMut}}, image::Image, math::{Vec2, Vec3}, sprite::{Sprite, SpriteImageMode}, transform::components::Transform, window::{Window, WindowResized}}; +use bevy::{ + app::{App, Startup, Update}, + asset::{AssetEvent, AssetServer, Assets}, + ecs::{ + event::EventReader, + query::{With, Without}, + system::{Commands, Query, Res}, + }, + image::Image, + math::{Vec2, Vec3}, + sprite::{Sprite, SpriteImageMode}, + transform::components::Transform, + window::{Window, WindowResized}, +}; -use crate::{client::Me, ecs::{StarfieldBack, StarfieldFront, StarfieldMid}}; +use crate::{ + client::Me, + ecs::{StarfieldBack, StarfieldFront, StarfieldMid}, +}; const BACK_STARFIELD_SIZE: f32 = 256.0; const MID_STARFIELD_SIZE: f32 = 384.0; const FRONT_STARFIELD_SIZE: f32 = 512.0; pub fn starfield_plugin(app: &mut App) { - app - .add_systems(Startup, setup_starfield) + app.add_systems(Startup, setup_starfield) .add_systems(Update, fix_starfield) .add_systems(Update, resize_starfield) .add_systems(Update, update_starfield); @@ -17,53 +32,77 @@ pub fn starfield_plugin(app: &mut App) { pub fn setup_starfield( mut commands: Commands, asset_server: Res, - window: Query<&Window> + window: Query<&Window>, ) { let starfield_handle = asset_server.load("textures/starfield.png"); let starfield_transp_handle = asset_server.load("textures/starfield_transp.png"); let window = window.iter().next().unwrap(); - commands.spawn(Sprite { - image: starfield_handle, - custom_size: Some(window.size() + Vec2::splat(BACK_STARFIELD_SIZE)), - image_mode: SpriteImageMode::Tiled { - tile_x: true, - tile_y: true, - stretch_value: 1.0, - }, - ..Default::default() - }) + commands + .spawn(Sprite { + image: starfield_handle, + custom_size: Some(window.size() + Vec2::splat(BACK_STARFIELD_SIZE)), + image_mode: SpriteImageMode::Tiled { + tile_x: true, + tile_y: true, + stretch_value: 1.0, + }, + ..Default::default() + }) .insert(Transform::from_xyz(0.0, 0.0, 5.0)) .insert(StarfieldBack); - commands.spawn(Sprite { - image: starfield_transp_handle.clone(), - custom_size: Some(window.size() + Vec2::splat(MID_STARFIELD_SIZE)), - image_mode: SpriteImageMode::Tiled { - tile_x: true, - tile_y: true, - stretch_value: 1.0, - }, - ..Default::default() - }) + commands + .spawn(Sprite { + image: starfield_transp_handle.clone(), + custom_size: Some(window.size() + Vec2::splat(MID_STARFIELD_SIZE)), + image_mode: SpriteImageMode::Tiled { + tile_x: true, + tile_y: true, + stretch_value: 1.0, + }, + ..Default::default() + }) .insert(Transform::from_xyz(0.0, 0.0, 4.5)) .insert(StarfieldMid); - commands.spawn(Sprite { - image: starfield_transp_handle, - custom_size: Some(window.size() + Vec2::splat(FRONT_STARFIELD_SIZE)), - image_mode: SpriteImageMode::Tiled { - tile_x: true, - tile_y: true, - stretch_value: 1.0, - }, - ..Default::default() - }) + commands + .spawn(Sprite { + image: starfield_transp_handle, + custom_size: Some(window.size() + Vec2::splat(FRONT_STARFIELD_SIZE)), + image_mode: SpriteImageMode::Tiled { + tile_x: true, + tile_y: true, + stretch_value: 1.0, + }, + ..Default::default() + }) .insert(Transform::from_xyz(0.0, 0.0, 4.0)) .insert(StarfieldFront); } pub fn fix_starfield( - mut starfield_back: Query<&mut Sprite, (With, Without, Without)>, - mut starfield_mid: Query<&mut Sprite, (With, Without, Without)>, - mut starfield_front: Query<&mut Sprite, (With, Without, Without)>, + mut starfield_back: Query< + &mut Sprite, + ( + With, + Without, + Without, + ), + >, + mut starfield_mid: Query< + &mut Sprite, + ( + With, + Without, + Without, + ), + >, + mut starfield_front: Query< + &mut Sprite, + ( + With, + Without, + Without, + ), + >, assets: Res>, mut asset_events: EventReader>, ) { @@ -101,39 +140,86 @@ pub fn fix_starfield( } pub fn resize_starfield( - mut starfield_back: Query<&mut Sprite, (With, Without, Without)>, - mut starfield_mid: Query<&mut Sprite, (With, Without, Without)>, - mut starfield_front: Query<&mut Sprite, (With, Without, Without)>, + mut starfield_back: Query< + &mut Sprite, + ( + With, + Without, + Without, + ), + >, + mut starfield_mid: Query< + &mut Sprite, + ( + With, + Without, + Without, + ), + >, + mut starfield_front: Query< + &mut Sprite, + ( + With, + Without, + Without, + ), + >, mut resize_event: EventReader, ) { for event in resize_event.read() { starfield_back.single_mut().unwrap().custom_size = - Some(Vec2::new(event.width, event.height) + Vec2::splat(BACK_STARFIELD_SIZE*2.0)); + Some(Vec2::new(event.width, event.height) + Vec2::splat(BACK_STARFIELD_SIZE * 2.0)); starfield_mid.single_mut().unwrap().custom_size = - Some(Vec2::new(event.width, event.height) + Vec2::splat(MID_STARFIELD_SIZE*2.0)); + Some(Vec2::new(event.width, event.height) + Vec2::splat(MID_STARFIELD_SIZE * 2.0)); starfield_front.single_mut().unwrap().custom_size = - Some(Vec2::new(event.width, event.height) + Vec2::splat(FRONT_STARFIELD_SIZE*2.0)); + Some(Vec2::new(event.width, event.height) + Vec2::splat(FRONT_STARFIELD_SIZE * 2.0)); } } pub fn update_starfield( - mut starfield_back: Query<&mut Transform, (With, Without, Without, Without)>, - mut starfield_mid: Query<&mut Transform, (With, Without, Without, Without)>, - mut starfield_front: Query<&mut Transform, (With, Without, Without, Without)>, + mut starfield_back: Query< + &mut Transform, + ( + With, + Without, + Without, + Without, + ), + >, + mut starfield_mid: Query< + &mut Transform, + ( + With, + Without, + Without, + Without, + ), + >, + mut starfield_front: Query< + &mut Transform, + ( + With, + Without, + Without, + Without, + ), + >, player: Query<&Transform, (With, Without)>, ) { - let Some(player) = player.iter().next() else { return }; + let Some(player) = player.iter().next() else { + return; + }; let mut starfield_back_pos = starfield_back.single_mut().unwrap(); let mut starfield_mid_pos = starfield_mid.single_mut().unwrap(); let mut starfield_front_pos = starfield_front.single_mut().unwrap(); //starfield_pos.translation = (player.translation / STARFIELD_SIZE).round() * STARFIELD_SIZE; starfield_back_pos.translation = player.translation - + (-player.translation/3.0) % BACK_STARFIELD_SIZE + + (-player.translation / 3.0) % BACK_STARFIELD_SIZE - Vec3::new(0.0, 0.0, 5.0); starfield_mid_pos.translation = player.translation - + (-player.translation/2.5) % MID_STARFIELD_SIZE + + (-player.translation / 2.5) % MID_STARFIELD_SIZE - Vec3::new(0.0, 0.0, 4.5); starfield_front_pos.translation = player.translation - + (-player.translation/2.0) % FRONT_STARFIELD_SIZE + + (-player.translation / 2.0) % FRONT_STARFIELD_SIZE - Vec3::new(0.0, 0.0, 4.0); } diff --git a/crates/unified/src/client_plugins.rs b/crates/unified/src/client_plugins.rs index 252bc169c9cf12341ea4faf5f21c460a124133f1..c673a615b50c4ae5bb5e747675a218fd2d7e9388 100644 --- a/crates/unified/src/client_plugins.rs +++ b/crates/unified/src/client_plugins.rs @@ -1,31 +1,26 @@ -use std::net::SocketAddr; -use bevy::app::{PluginGroup, PluginGroupBuilder}; +use crate::client::ClientPlugin; use bevy::DefaultPlugins; +use bevy::app::{PluginGroup, PluginGroupBuilder}; use bevy::log::LogPlugin; -use bevy_rapier2d::render::RapierDebugRenderPlugin; use bevy_replicon::RepliconPlugins; use bevy_replicon_renet2::RepliconRenetClientPlugin; -use crate::client::ClientPlugin; +use std::net::SocketAddr; pub struct ClientPluginGroup { #[cfg(target_arch = "wasm32")] pub server: url::Url, #[cfg(not(target_arch = "wasm32"))] - pub server: SocketAddr + pub server: SocketAddr, } impl PluginGroup for ClientPluginGroup { fn build(self) -> PluginGroupBuilder { PluginGroupBuilder::start::() - .add_group( - DefaultPlugins - .build() - .disable::() - ) - .add_group( - RepliconPlugins - ) + .add_group(DefaultPlugins.build().disable::()) + .add_group(RepliconPlugins) .add(RepliconRenetClientPlugin) - .add(ClientPlugin { server: self.server }) - //.add(RapierDebugRenderPlugin::default()) + .add(ClientPlugin { + server: self.server, + }) + //.add(RapierDebugRenderPlugin::default()) } } diff --git a/crates/unified/src/config/mod.rs b/crates/unified/src/config/mod.rs index 52015ba72b64e37e084ea00539995d8d9d08a4c8..5ca33e5ff42d7f9bbdbbf779ce937252a92323d8 100644 --- a/crates/unified/src/config/mod.rs +++ b/crates/unified/src/config/mod.rs @@ -1,2 +1,2 @@ +pub mod planet; pub mod world; -pub mod planet; \ No newline at end of file diff --git a/crates/unified/src/config/planet.rs b/crates/unified/src/config/planet.rs index 048e30dc5f51d72e9d1d229c3b932451bcdaeb11..30786b411a76552fa714a2e17c6a537f5614edca 100644 --- a/crates/unified/src/config/planet.rs +++ b/crates/unified/src/config/planet.rs @@ -1,20 +1,16 @@ use bevy::asset::Asset; -use bevy::math::Vec3; use bevy::prelude::{Bundle, Component, Transform, TypePath}; use bevy_rapier2d::prelude::{AdditionalMassProperties, Collider, ReadMassProperties, RigidBody}; use serde::{Deserialize, Serialize}; #[derive(Deserialize, Asset, TypePath, Component, Serialize, Clone, Debug)] -#[require( - ReadMassProperties, - RigidBody::Fixed -)] +#[require(ReadMassProperties, RigidBody::Fixed)] pub struct Planet { pub name: String, pub sprite: String, pub radius: f32, pub mass: f32, - pub default_transform: [f32; 3] + pub default_transform: [f32; 3], } #[derive(Bundle)] @@ -25,8 +21,7 @@ pub struct PlanetBundle { pub additional_mass_properties: AdditionalMassProperties, } - #[derive(Deserialize, Asset, TypePath)] pub struct PlanetConfigCollection { pub planets: Vec, -} \ No newline at end of file +} diff --git a/crates/unified/src/config/world.rs b/crates/unified/src/config/world.rs index a45fd2d5591154b6f1aaf6fe94d21641f7df35c9..8ecf0bdaf52c9d9b8dc5d143175fa215b679244f 100644 --- a/crates/unified/src/config/world.rs +++ b/crates/unified/src/config/world.rs @@ -11,14 +11,14 @@ pub struct GlobalWorldConfig { #[derive(Deserialize, Asset, TypePath, Clone)] pub struct WorldConfig { - pub gravity: f32 + pub gravity: f32, } #[derive(Deserialize, Asset, TypePath, Clone)] pub struct PartConfig { pub default_width: f32, pub default_height: f32, - pub default_mass: f32 + pub default_mass: f32, } #[derive(Deserialize, Asset, TypePath, Clone)] diff --git a/crates/unified/src/ecs.rs b/crates/unified/src/ecs.rs index 9b5a46f72bac48d7d486ee3ab81b23d98b88efe4..77a0d2095445287197ef1c8c0df5658ab72f6005 100644 --- a/crates/unified/src/ecs.rs +++ b/crates/unified/src/ecs.rs @@ -1,7 +1,6 @@ use bevy::math::Vec2; use bevy::prelude::{Bundle, Component, Entity, Event, Resource, Transform}; use bevy_rapier2d::dynamics::AdditionalMassProperties; -use bevy_replicon::prelude::Replicated; use bevy_rapier2d::dynamics::RigidBody; use bevy_rapier2d::geometry::Collider; use bevy_rapier2d::prelude::*; @@ -39,7 +38,7 @@ pub struct Part { pub sprite: String, pub width: f32, pub height: f32, - pub mass: f32 + pub mass: f32, } #[derive(Bundle)] pub struct PartBundle { @@ -51,7 +50,7 @@ pub struct PartBundle { #[derive(Component, Serialize, Deserialize, Debug)] pub struct Player { - pub client: Entity + pub client: Entity, } #[derive(Component, Default, Serialize, Deserialize, Debug)] diff --git a/crates/unified/src/main.rs b/crates/unified/src/main.rs index 33af9ef86b97ed524c22a59b47f924071dea1c1e..8e01f5457ac5463b44078e98e676c2fd422166ee 100644 --- a/crates/unified/src/main.rs +++ b/crates/unified/src/main.rs @@ -1,22 +1,21 @@ -pub mod server_plugins; -pub mod shared_plugins; -pub mod server; pub mod client; -pub mod ecs; pub mod client_plugins; pub mod config; +pub mod ecs; +pub mod server; +pub mod server_plugins; +pub mod shared_plugins; +use crate::client_plugins::ClientPluginGroup; +use crate::server_plugins::ServerPluginGroup; +use crate::shared_plugins::SharedPluginGroup; +use bevy::log::{Level, tracing_subscriber}; +use bevy::prelude::*; +use clap::Parser; use std::net::SocketAddr; use std::process::exit; -use bevy::log::{tracing_subscriber, Level, LogPlugin}; -use clap::Parser; -use bevy::prelude::*; use tracing_subscriber::EnvFilter; -use tracing_subscriber::filter::Directive; use tracing_subscriber::util::SubscriberInitExt; -use crate::client_plugins::ClientPluginGroup; -use crate::server_plugins::ServerPluginGroup; -use crate::shared_plugins::SharedPluginGroup; #[derive(Parser, Debug)] #[command(version, about)] @@ -27,7 +26,7 @@ enum Cli { server: url::Url, #[cfg(not(target_arch = "wasm32"))] #[arg(short, long)] - server: SocketAddr + server: SocketAddr, }, Server { #[arg(short = 'w', long)] @@ -37,8 +36,8 @@ enum Cli { #[arg(short = 'r', long)] tick_rate: f64, #[arg(short = 'C', long)] - max_clients: usize - } + max_clients: usize, + }, } fn main() -> AppExit { @@ -55,18 +54,21 @@ fn main() -> AppExit { .add_directive("bevy_replicon=warn".parse().unwrap()) .add_directive("bevy_replicon_renet2=warn".parse().unwrap()) .add_directive("naga=warn".parse().unwrap()) - .add_directive("wgpu_hal::vulkan=error".parse().unwrap()) + .add_directive("wgpu_hal::vulkan=error".parse().unwrap()), ) .finish() .init(); match cli { Cli::Client { server } => { - app.add_plugins(ClientPluginGroup { - server - }); - }, - Cli::Server { bind_ws, bind_native, tick_rate, max_clients } => { + app.add_plugins(ClientPluginGroup { server }); + } + Cli::Server { + bind_ws, + bind_native, + tick_rate, + max_clients, + } => { if cfg!(target_family = "wasm") { eprintln!("the server cannot run on webassembly"); exit(1); @@ -76,7 +78,7 @@ fn main() -> AppExit { bind_ws, bind_native, tick_rate, - max_clients + max_clients, }); } } @@ -84,4 +86,4 @@ fn main() -> AppExit { app.add_plugins(SharedPluginGroup); app.run() -} \ No newline at end of file +} diff --git a/crates/unified/src/server/gravity.rs b/crates/unified/src/server/gravity.rs index 3e3ac8dd3e5eee2ac214bcc4e861297baedde7f5..55f2c45af658f179bfba148812a7bcc691ba4a85 100644 --- a/crates/unified/src/server/gravity.rs +++ b/crates/unified/src/server/gravity.rs @@ -1,9 +1,9 @@ -use bevy::math::FloatPow; -use bevy::prelude::*; -use bevy_rapier2d::prelude::*; use crate::config::planet::Planet; use crate::ecs::Part; use crate::server::world_config::WorldConfigResource; +use bevy::math::FloatPow; +use bevy::prelude::*; +use bevy_rapier2d::prelude::*; pub fn newtonian_gravity_plugin(app: &mut App) { app.add_systems(Update, update_gravity); @@ -15,16 +15,18 @@ fn update_gravity( &Transform, &ReadMassProperties, &mut ExternalForce, - &mut ExternalImpulse + &mut ExternalImpulse, ), - With + With, >, planet_query: Query<(&Transform, &ReadMassProperties), With>, world_config: Res, ) { - let Some(world_config) = &world_config.config else { return; }; + let Some(world_config) = &world_config.config else { + return; + }; - for (part_transform, part_mass, mut forces, mut impulses) in &mut part_query { + for (part_transform, part_mass, mut forces, impulses) in &mut part_query { let part_mass = part_mass.mass; let part_translation = part_transform.translation; @@ -34,7 +36,8 @@ fn update_gravity( let distance = planet_translation.distance(part_translation); - let force = world_config.world.gravity * ((part_mass * planet_mass) / distance.squared()); + let force = + world_config.world.gravity * ((part_mass * planet_mass) / distance.squared()); let direction = (planet_translation - part_translation).normalize() * force; forces.force += direction.xy(); } diff --git a/crates/unified/src/server/mod.rs b/crates/unified/src/server/mod.rs index 6445f5033ab2b1f68210fb0fd1b2e48620dec113..42bde803782d4bc9f3bfa8c6b5dd8267a4ee7fea 100644 --- a/crates/unified/src/server/mod.rs +++ b/crates/unified/src/server/mod.rs @@ -1,25 +1,27 @@ +mod gravity; pub mod planets; pub mod player; mod world_config; -mod gravity; +use bevy::prelude::*; +use bevy_replicon::prelude::RepliconChannels; +use bevy_replicon_renet2::netcode::{ + BoxedSocket, NetcodeServerTransport, ServerAuthentication, ServerSetupConfig, +}; use std::net::{SocketAddr, UdpSocket}; use std::time::{SystemTime, UNIX_EPOCH}; -use bevy::prelude::*; -use bevy_rapier2d::prelude::{Collider, Restitution, RigidBody, Velocity}; -use bevy_replicon::prelude::{FromClient, Replicated, RepliconChannels}; -use bevy_replicon_renet2::netcode::{NetcodeServerTransport, ServerAuthentication, ServerSetupConfig, BoxedSocket}; #[cfg(not(target_arch = "wasm32"))] -use bevy_replicon_renet2::netcode::{NativeSocket, WebSocketAcceptor, WebSocketServerConfig, WebSocketServer}; +use bevy_replicon_renet2::netcode::{ + NativeSocket, WebSocketAcceptor, WebSocketServer, WebSocketServerConfig, +}; -use bevy_replicon_renet2::renet2::{ConnectionConfig, RenetServer}; -use bevy_replicon_renet2::RenetChannelsExt; -use crate::ecs::{Ball, Ground, SendBallHere}; use crate::server::gravity::newtonian_gravity_plugin; use crate::server::planets::planets_plugin; use crate::server::player::player_management_plugin; use crate::server::world_config::world_config_plugin; +use bevy_replicon_renet2::RenetChannelsExt; +use bevy_replicon_renet2::renet2::{ConnectionConfig, RenetServer}; pub struct ServerPlugin { pub bind_ws: SocketAddr, @@ -28,48 +30,57 @@ pub struct ServerPlugin { } impl Plugin for ServerPlugin { fn build(&self, app: &mut App) { - let bind_ws = self.bind_ws.clone(); - let bind_native = self.bind_native.clone(); - let max_clients = self.max_clients.clone(); - - app - .add_systems(FixedPreUpdate, bevy_replicon::server::increment_tick) // !!important!! do not remove or move - .add_systems(Startup, move |mut commands: Commands, channels: Res| { - - let server = RenetServer::new(ConnectionConfig::from_channels( - channels.server_configs(), - channels.client_configs() - )); + let bind_ws = self.bind_ws; + let bind_native = self.bind_native; + let max_clients = self.max_clients; - #[cfg(not(target_arch = "wasm32"))] { - let server_config = ServerSetupConfig { - current_time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap(), - max_clients: max_clients, - protocol_id: 0, - authentication: ServerAuthentication::Unsecure, - socket_addresses: vec![vec![bind_native], vec![bind_ws]] - }; + app.add_systems(FixedPreUpdate, bevy_replicon::server::increment_tick) // !!important!! do not remove or move + .add_systems( + Startup, + move |mut commands: Commands, channels: Res| { + let server = RenetServer::new(ConnectionConfig::from_channels( + channels.server_configs(), + channels.client_configs(), + )); - let rt = tokio::runtime::Runtime::new().unwrap(); + #[cfg(not(target_arch = "wasm32"))] + { + let server_config = ServerSetupConfig { + current_time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap(), + max_clients, + protocol_id: 0, + authentication: ServerAuthentication::Unsecure, + socket_addresses: vec![vec![bind_native], vec![bind_ws]], + }; - let ws_config = WebSocketServerConfig { - acceptor: WebSocketAcceptor::Plain { has_tls_proxy: true }, - listen: bind_ws, - max_clients - }; - let ws_server = WebSocketServer::new(ws_config, rt.handle().clone()).unwrap(); + let rt = tokio::runtime::Runtime::new().unwrap(); - let native_socket = NativeSocket::new(UdpSocket::bind(bind_native).unwrap()).unwrap(); + let ws_config = WebSocketServerConfig { + acceptor: WebSocketAcceptor::Plain { + has_tls_proxy: true, + }, + listen: bind_ws, + max_clients, + }; + let ws_server = + WebSocketServer::new(ws_config, rt.handle().clone()).unwrap(); - let transport = NetcodeServerTransport::new_with_sockets(server_config, vec![BoxedSocket::new(native_socket), BoxedSocket::new(ws_server)]).unwrap(); + let native_socket = + NativeSocket::new(UdpSocket::bind(bind_native).unwrap()).unwrap(); - commands.insert_resource(server); - commands.insert_resource(transport); + let transport = NetcodeServerTransport::new_with_sockets( + server_config, + vec![BoxedSocket::new(native_socket), BoxedSocket::new(ws_server)], + ) + .unwrap(); - info!("websocket/native server listening"); + commands.insert_resource(server); + commands.insert_resource(transport); - } - }) + info!("websocket/native server listening"); + } + }, + ) .add_plugins(planets_plugin) .add_plugins(world_config_plugin) .add_plugins(newtonian_gravity_plugin) diff --git a/crates/unified/src/server/planets.rs b/crates/unified/src/server/planets.rs index 5cf3952f25beb6ba28b51a5e7d8da1bf27cd1f08..ee456f5e8afb6781047b55d33ba33edc589da52c 100644 --- a/crates/unified/src/server/planets.rs +++ b/crates/unified/src/server/planets.rs @@ -1,35 +1,40 @@ +use crate::config::planet::{Planet, PlanetBundle, PlanetConfigCollection}; use bevy::asset::Handle; use bevy::prelude::*; use bevy_rapier2d::dynamics::AdditionalMassProperties; use bevy_rapier2d::prelude::Collider; use bevy_replicon::prelude::Replicated; -use crate::config::planet::{Planet, PlanetBundle, PlanetConfigCollection}; pub fn planets_plugin(app: &mut App) { - app - .init_resource::() + app.init_resource::() .add_systems(Startup, start_loading_planets) .add_systems(Update, update_planets); } #[derive(Resource, Default)] pub struct PlanetConfigResource { - handle: Option> + handle: Option>, } fn start_loading_planets(assets: Res, mut planets: ResMut) { planets.handle = Some(assets.load("config/planets.pc.toml")); } - pub fn update_planets( mut commands: Commands, mut ev_config: EventReader>, - mut assets: ResMut>, - mut planets: ResMut, - mut q_planets: Query<(Entity, &mut Planet, &mut Transform, &mut AdditionalMassProperties)> + assets: ResMut>, + planets: ResMut, + mut q_planets: Query<( + Entity, + &mut Planet, + &mut Transform, + &mut AdditionalMassProperties, + )>, ) { - let Some(handle) = planets.handle.as_ref() else { return; }; + let Some(handle) = planets.handle.as_ref() else { + return; + }; let waiting_for_asset_id = handle.id(); @@ -40,47 +45,70 @@ pub fn update_planets( info!("planet config loaded - creating planets"); let planet_config = assets.get(*id).unwrap(); for planet in &planet_config.planets { - commands.spawn(PlanetBundle { - planet: planet.clone(), - transform: Transform::from_xyz(planet.default_transform[0], planet.default_transform[1], planet.default_transform[2]), - collider: Collider::ball(planet.radius), - additional_mass_properties: AdditionalMassProperties::Mass(planet.mass), - }).insert(Replicated); + commands + .spawn(PlanetBundle { + planet: planet.clone(), + transform: Transform::from_xyz( + planet.default_transform[0], + planet.default_transform[1], + planet.default_transform[2], + ), + collider: Collider::ball(planet.radius), + additional_mass_properties: AdditionalMassProperties::Mass( + planet.mass, + ), + }) + .insert(Replicated); info!(?planet, "new planet spawned"); } } - }, + } AssetEvent::Modified { id } => { if *id == waiting_for_asset_id { info!("planet config modified - reloading planets"); let planet_config = assets.get(*id).unwrap(); for planet in &planet_config.planets { - let existing_planet = q_planets.iter_mut().find(|(_, p, _, _)| p.name == planet.name); + let existing_planet = q_planets + .iter_mut() + .find(|(_, p, _, _)| p.name == planet.name); - if let Some((existing, mut e_planet, mut e_transform, mut e_mass)) = existing_planet { - commands.entity(existing) + if let Some((existing, mut e_planet, mut e_transform, mut e_mass)) = + existing_planet + { + commands + .entity(existing) .remove::() .insert(Collider::ball(planet.radius)); *e_planet = planet.clone(); - e_transform.translation = Vec3::new(planet.default_transform[0], planet.default_transform[1], planet.default_transform[2]); + e_transform.translation = Vec3::new( + planet.default_transform[0], + planet.default_transform[1], + planet.default_transform[2], + ); *e_mass = AdditionalMassProperties::Mass(planet.mass); info!(?planet, "planet hot-reloaded"); } else { - commands.spawn(PlanetBundle { - planet: planet.clone(), - transform: Transform::from_xyz(planet.default_transform[0], planet.default_transform[1], planet.default_transform[2]), - collider: Collider::ball(planet.radius), - additional_mass_properties: AdditionalMassProperties::Mass(planet.mass), - }).insert(Replicated); + commands + .spawn(PlanetBundle { + planet: planet.clone(), + transform: Transform::from_xyz( + planet.default_transform[0], + planet.default_transform[1], + planet.default_transform[2], + ), + collider: Collider::ball(planet.radius), + additional_mass_properties: AdditionalMassProperties::Mass( + planet.mass, + ), + }) + .insert(Replicated); info!(?planet, "new planet spawned"); } - - } } - }, + } _ => {} } } -} \ No newline at end of file +} diff --git a/crates/unified/src/server/player.rs b/crates/unified/src/server/player.rs index 5ea5ca5b2c93c3ec8c22fea2b640e78ce02aa57c..2d57b53ff21cf12f7e39f4c9fccffb3a508b43b6 100644 --- a/crates/unified/src/server/player.rs +++ b/crates/unified/src/server/player.rs @@ -1,21 +1,20 @@ use std::f32::consts::PI; -use bevy::prelude::*; -use bevy_rapier2d::prelude::{AdditionalMassProperties, Collider, ExternalForce, ExternalImpulse, MassProperties, ReadMassProperties, RigidBody, Sensor}; -use bevy_replicon::prelude::{ConnectedClient, FromClient, Replicated}; use crate::config::planet::Planet; use crate::ecs::{Part, PartBundle, Player, PlayerThrust, ThrustEvent}; use crate::server::world_config::WorldConfigResource; +use bevy::prelude::*; +use bevy_rapier2d::prelude::{ + AdditionalMassProperties, Collider, ExternalForce, ExternalImpulse, MassProperties, +}; +use bevy_replicon::prelude::{ConnectedClient, FromClient, Replicated}; pub fn player_management_plugin(app: &mut App) { - app - .add_systems(PreUpdate, reset_movement) + app.add_systems(PreUpdate, reset_movement) .add_systems(Update, (handle_new_players, player_thrust)); } -fn reset_movement( - mut players: Query<(&mut ExternalForce, &mut ExternalImpulse)> -) { +fn reset_movement(mut players: Query<(&mut ExternalForce, &mut ExternalImpulse)>) { for (mut force, mut impulse) in &mut players { force.force = Vec2::ZERO; force.torque = 0.0; @@ -23,33 +22,49 @@ fn reset_movement( } } -fn handle_new_players(mut commands: Commands, q_new_clients: Query>, world_config: Res, planets: Query<(&Transform, &Planet)>) { - let Some(wc) = &world_config.config else { return; }; +fn handle_new_players( + mut commands: Commands, + q_new_clients: Query>, + world_config: Res, + planets: Query<(&Transform, &Planet)>, +) { + let Some(wc) = &world_config.config else { + return; + }; for joined_player in &q_new_clients { // find earth - let (earth_pos, earth_planet) = planets.iter().find(|p| p.1.name == "Earth").expect("earth is missing? (check that the planet is named 'Earth')"); + let (earth_pos, earth_planet) = planets + .iter() + .find(|p| p.1.name == "Earth") + .expect("earth is missing? (check that the planet is named 'Earth')"); let angle = rand::random::() * std::f32::consts::TAU; let offset = earth_planet.radius + 150.0; - let mut new_transform = Transform::from_xyz(angle.cos() * offset, angle.sin() * offset, 0.0); + let mut new_transform = + Transform::from_xyz(angle.cos() * offset, angle.sin() * offset, 0.0); new_transform.rotate_z(angle); new_transform.translation += earth_pos.translation; - - commands.entity(joined_player) + commands + .entity(joined_player) .insert(PartBundle { part: Part { sprite: "textures/hearty.png".to_string(), width: wc.part.default_width, height: wc.part.default_height, - mass: wc.part.default_mass + mass: wc.part.default_mass, }, transform: new_transform, - collider: Collider::cuboid(wc.part.default_width / 2.0, wc.part.default_height / 2.0), - additional_mass_properties: AdditionalMassProperties::MassProperties(MassProperties { - local_center_of_mass: Vec2::ZERO, - mass: wc.part.default_mass, - principal_inertia: 7.5, - }) + collider: Collider::cuboid( + wc.part.default_width / 2.0, + wc.part.default_height / 2.0, + ), + additional_mass_properties: AdditionalMassProperties::MassProperties( + MassProperties { + local_center_of_mass: Vec2::ZERO, + mass: wc.part.default_mass, + principal_inertia: 7.5, + }, + ), }) .insert(Replicated) .insert(ExternalForce::default()) @@ -67,8 +82,13 @@ fn player_thrust( ) { use ThrustEvent::*; for event in thrust_event.read() { - let FromClient { client_entity, event } = event; - let Ok((_, _, mut thrust)) = players.get_mut(*client_entity) else { continue }; + let FromClient { + client_entity, + event, + } = event; + let Ok((_, _, mut thrust)) = players.get_mut(*client_entity) else { + continue; + }; match *event { Up(on) => thrust.up = on, Down(on) => thrust.down = on, @@ -77,7 +97,9 @@ fn player_thrust( } } for (transform, mut force, thrust) in &mut players { - let Some(world_config) = &world_config.config else { return; }; + let Some(world_config) = &world_config.config else { + return; + }; let forward = (transform.rotation * Vec3::Y).xy(); let mut external_force = ExternalForce::default(); @@ -98,25 +120,37 @@ fn player_thrust( thrusters[1] = 1.0; thrusters[3] = 1.0; } - let half_size = Vec2::new(world_config.part.default_width/2.0, world_config.part.default_height/2.0).length(); + let half_size = Vec2::new( + world_config.part.default_width / 2.0, + world_config.part.default_height / 2.0, + ) + .length(); external_force += ExternalForce::at_point( - -forward*thrusters[0]*world_config.hearty.thrust, - transform.translation.xy() + half_size*Vec2::new((1.0*PI/4.0).cos(), (1.0*PI/4.0).sin()).rotate(forward), + -forward * thrusters[0] * world_config.hearty.thrust, + transform.translation.xy() + + half_size + * Vec2::new((1.0 * PI / 4.0).cos(), (1.0 * PI / 4.0).sin()).rotate(forward), transform.translation.xy(), ); external_force += ExternalForce::at_point( - forward*thrusters[1]*world_config.hearty.thrust, - transform.translation.xy() + half_size*Vec2::new((3.0*PI/4.0).cos(), (3.0*PI/4.0).sin()).rotate(forward), + forward * thrusters[1] * world_config.hearty.thrust, + transform.translation.xy() + + half_size + * Vec2::new((3.0 * PI / 4.0).cos(), (3.0 * PI / 4.0).sin()).rotate(forward), transform.translation.xy(), ); external_force += ExternalForce::at_point( - forward*thrusters[2]*world_config.hearty.thrust, - transform.translation.xy() + half_size*Vec2::new((5.0*PI/4.0).cos(), (5.0*PI/4.0).sin()).rotate(forward), + forward * thrusters[2] * world_config.hearty.thrust, + transform.translation.xy() + + half_size + * Vec2::new((5.0 * PI / 4.0).cos(), (5.0 * PI / 4.0).sin()).rotate(forward), transform.translation.xy(), ); external_force += ExternalForce::at_point( - -forward*thrusters[3]*world_config.hearty.thrust, - transform.translation.xy() + half_size*Vec2::new((7.0*PI/4.0).cos(), (7.0*PI/4.0).sin()).rotate(forward), + -forward * thrusters[3] * world_config.hearty.thrust, + transform.translation.xy() + + half_size + * Vec2::new((7.0 * PI / 4.0).cos(), (7.0 * PI / 4.0).sin()).rotate(forward), transform.translation.xy(), ); *force += external_force; diff --git a/crates/unified/src/server/world_config.rs b/crates/unified/src/server/world_config.rs index 0a104e27b541f055c02960cb096ffbfa858018a3..37f2a7e84851128ca2cfab5189c37400da70c31a 100644 --- a/crates/unified/src/server/world_config.rs +++ b/crates/unified/src/server/world_config.rs @@ -1,14 +1,9 @@ +use crate::config::world::GlobalWorldConfig; use bevy::asset::Handle; use bevy::prelude::*; -use bevy_rapier2d::dynamics::AdditionalMassProperties; -use bevy_rapier2d::prelude::Collider; -use bevy_replicon::prelude::Replicated; -use crate::config::planet::{Planet, PlanetBundle, PlanetConfigCollection}; -use crate::config::world::{GlobalWorldConfig, WorldConfig}; pub fn world_config_plugin(app: &mut App) { - app - .init_resource::() + app.init_resource::() .add_systems(Startup, start_loading_planets) .add_systems(Update, update_planets); } @@ -16,21 +11,22 @@ pub fn world_config_plugin(app: &mut App) { #[derive(Resource, Default)] pub struct WorldConfigResource { handle: Option>, - pub config: Option + pub config: Option, } fn start_loading_planets(assets: Res, mut planets: ResMut) { planets.handle = Some(assets.load("config/world.wc.toml")); } - pub fn update_planets( - mut commands: Commands, + commands: Commands, mut ev_config: EventReader>, - mut assets: ResMut>, + assets: ResMut>, mut resource: ResMut, ) { - let Some(handle) = resource.handle.as_ref() else { return; }; + let Some(handle) = resource.handle.as_ref() else { + return; + }; let waiting_for_asset_id = handle.id(); @@ -42,15 +38,15 @@ pub fn update_planets( let world_config = assets.get(*id).unwrap(); resource.config = Some(world_config.clone()); } - }, + } AssetEvent::Modified { id } => { if *id == waiting_for_asset_id { info!("world config modified - reloading"); let world_config = assets.get(*id).unwrap(); resource.config = Some(world_config.clone()); } - }, + } _ => {} } } -} \ No newline at end of file +} diff --git a/crates/unified/src/server_plugins.rs b/crates/unified/src/server_plugins.rs index 8219309e8dc478bc1c4d54383ff4d93c3f4e3e9a..d85d043e0ed0a46e78488dd0211e709c6ac7f29a 100644 --- a/crates/unified/src/server_plugins.rs +++ b/crates/unified/src/server_plugins.rs @@ -1,5 +1,5 @@ -use std::net::SocketAddr; -use std::time::Duration; +use crate::config::planet::PlanetConfigCollection; +use crate::config::world::GlobalWorldConfig; use bevy::app::{PluginGroup, PluginGroupBuilder, ScheduleRunnerPlugin, TaskPoolPlugin}; use bevy::asset::AssetPlugin; use bevy::diagnostic::FrameCountPlugin; @@ -7,14 +7,14 @@ use bevy::time::TimePlugin; use bevy_common_assets::toml::TomlAssetPlugin; use bevy_replicon::RepliconPlugins; use bevy_replicon_renet2::RepliconRenetServerPlugin; -use crate::config::planet::{Planet, PlanetConfigCollection}; -use crate::config::world::{GlobalWorldConfig, WorldConfig}; +use std::net::SocketAddr; +use std::time::Duration; pub struct ServerPluginGroup { pub bind_ws: SocketAddr, pub bind_native: SocketAddr, pub tick_rate: f64, - pub max_clients: usize + pub max_clients: usize, } impl PluginGroup for ServerPluginGroup { fn build(self) -> PluginGroupBuilder { @@ -22,15 +22,11 @@ impl PluginGroup for ServerPluginGroup { .add(TaskPoolPlugin::default()) .add(FrameCountPlugin) .add(TimePlugin) - .add(ScheduleRunnerPlugin::run_loop( - Duration::from_secs_f64(1.0 / self.tick_rate) - )) - .add_group( - RepliconPlugins - ) - .add( - RepliconRenetServerPlugin - ) + .add(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64( + 1.0 / self.tick_rate, + ))) + .add_group(RepliconPlugins) + .add(RepliconRenetServerPlugin) /* Assets */ .add(AssetPlugin::default()) .add(TomlAssetPlugin::::new(&["wc.toml"])) @@ -41,4 +37,4 @@ impl PluginGroup for ServerPluginGroup { max_clients: self.max_clients, }) } -} \ No newline at end of file +} diff --git a/crates/unified/src/shared_plugins.rs b/crates/unified/src/shared_plugins.rs index c34e90f4a3cdfc708f60422868b152d5a19046a0..1485692b33c7fc8e8350dec47c0b104e2fa03e3f 100644 --- a/crates/unified/src/shared_plugins.rs +++ b/crates/unified/src/shared_plugins.rs @@ -1,26 +1,23 @@ +use crate::config::planet::Planet; +use crate::ecs::{Ball, Ground, Part, Player, SendBallHere, ThrustEvent}; use bevy::app::{App, PluginGroup, PluginGroupBuilder}; use bevy::prelude::*; use bevy_rapier2d::prelude::*; -use bevy_replicon::prelude::{AppRuleExt, Channel, ClientEventAppExt, FromClient, ServerEventAppExt}; -use crate::config::planet::Planet; -use crate::ecs::{Ball, Ground, Part, Player, SendBallHere, ThrustEvent}; +use bevy_replicon::prelude::{AppRuleExt, Channel, ClientEventAppExt}; pub struct SharedPluginGroup; impl PluginGroup for SharedPluginGroup { fn build(self) -> PluginGroupBuilder { PluginGroupBuilder::start::() - .add( - RapierPhysicsPlugin::::pixels_per_meter(100.0) - ) + .add(RapierPhysicsPlugin::::pixels_per_meter(100.0)) .add(register_everything) .add(physics_setup_plugin) } } pub fn register_everything(app: &mut App) { - app - .add_client_event::(Channel::Ordered) + app.add_client_event::(Channel::Ordered) .add_client_event::(Channel::Ordered) .replicate::() .replicate::() @@ -31,14 +28,11 @@ pub fn register_everything(app: &mut App) { .replicate::(); } -fn physics_setup_plugin(mut app: &mut App) { +fn physics_setup_plugin(app: &mut App) { app.add_systems(Startup, setup_physics); } - -fn setup_physics( - mut rapier_config: Query<&mut RapierConfiguration> -) { +fn setup_physics(mut rapier_config: Query<&mut RapierConfiguration>) { let mut cfg = rapier_config.single_mut().unwrap(); cfg.gravity = Vec2::ZERO; }