M crates/unified/Cargo.toml => crates/unified/Cargo.toml +1 -0
@@ 27,6 27,7 @@ bevy = { version = "0.16", default-features = false, features = [
"multi_threaded",
"bevy_dev_tools",
"bevy_sprite_picking_backend",
+ "default_font",
"png"
] }
bevy_rapier2d = { version = "0.30", features = ["serde-serialize", "simd-stable"] }
M crates/unified/assets/config/parts/hearty.part.toml => crates/unified/assets/config/parts/hearty.part.toml +5 -1
@@ 8,6 8,10 @@ width = 50
height = 50
mass = 100
+[thruster]
+flow_rate = 0.1
+exhaust_speed = 250
+
[[joints]]
id = "Top"
target = { translation = [ 0.0, 50.0, 0.0 ], rotation = 0.0 }
@@ 27,4 31,4 @@ snap = { translation = [ 0.0, -25.0, 0.0 ], rotation = 180.0 }
[[joints]]
id = "Left"
target = { translation = [ -50.0, 0.0, 0.0 ], rotation = 270.0 }
-snap = { translation = [ -25.0, 0.0, 0.0 ], rotation = 270.0 }>
\ No newline at end of file
+snap = { translation = [ -25.0, 0.0, 0.0 ], rotation = 270.0 }
M crates/unified/src/client/ui.rs => crates/unified/src/client/ui.rs +26 -4
@@ 1,9 1,11 @@
use bevy::prelude::*;
-use crate::client::colors;
+use crate::{client::colors, ecs::{FuelText, Player, PlayerStorage, PowerText}};
pub fn ui_plugin(app: &mut App) {
- app.add_systems(Startup, setup_ui);
+ app
+ .add_systems(Startup, setup_ui)
+ .add_systems(Update, update_ui);
}
fn setup_ui(mut commands: Commands) {
@@ 25,7 27,18 @@ fn setup_ui(mut commands: Commands) {
},
BorderRadius::all(Val::Px(5.0)),
BackgroundColor(colors::MANTLE),
- children![(
+ children![
+ (
+ TextColor(colors::PEACH),
+ Text::new("Fuel: 25"),
+ FuelText,
+ ),
+ (
+ TextColor(colors::PEACH),
+ Text::new("Power: 25"),
+ PowerText,
+ ),
+ /*(
Node {
width: Val::Percent(100.0),
height: Val::Px(20.0),
@@ 34,7 47,16 @@ fn setup_ui(mut commands: Commands) {
},
BorderRadius::all(Val::Px(5.0)),
BackgroundColor(colors::CRUST),
- )],
+ )*/],
)],
));
}
+
+fn update_ui(
+ mut fuel_text: Single<&mut Text, With<FuelText>>,
+ mut power_text: Single<&mut Text, (With<PowerText>, Without<FuelText>)>,
+ player: Single<(&PlayerStorage), (With<Player>, Without<PowerText>)>,
+) {
+ fuel_text.0 = format!("Fuel: {}/{}", player.fuel, player.fuel_capacity);
+ power_text.0 = format!("Power: {}/{}", player.power, player.power_capacity);
+}
M crates/unified/src/config/part.rs => crates/unified/src/config/part.rs +6 -0
@@ 7,6 7,7 @@ use serde::{Deserialize, Serialize};
pub struct PartConfig {
pub part: PartPartConfig,
pub physics: PartPhysicsConfig,
+ pub thruster: Option<PartThrusterConfig>,
pub joints: Vec<JointConfig>,
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
@@ 22,6 23,11 @@ pub struct PartPhysicsConfig {
pub mass: f32,
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
+pub struct PartThrusterConfig {
+ pub flow_rate: f32, // kg/s
+ pub exhaust_speed: f32, // m/s
+}
+#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
pub struct JointConfig {
pub id: String,
pub target: JointOffset,
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +12 -0
@@ 16,6 16,10 @@ pub struct StarfieldFront;
pub struct StarfieldMid;
#[derive(Component)]
pub struct StarfieldBack;
+#[derive(Component)]
+pub struct FuelText;
+#[derive(Component)]
+pub struct PowerText;
#[derive(Resource, Default)]
pub struct CursorWorldCoordinates(pub Option<Vec2>);
@@ 72,3 76,11 @@ pub struct DragRequestEvent {
#[entities]
pub snap_target: Option<Entity>,
}
+
+#[derive(Component, Serialize, Deserialize, Debug)]
+pub struct PlayerStorage {
+ pub fuel_capacity: f32,
+ pub fuel: f32,
+ pub power_capacity: f32,
+ pub power: f32,
+}
M crates/unified/src/server/player.rs => crates/unified/src/server/player.rs +12 -4
@@ 1,5 1,5 @@
use crate::config::planet::Planet;
-use crate::ecs::{DragRequestEvent, Part, Player, PlayerThrust, ThrustEvent};
+use crate::ecs::{DragRequestEvent, Part, Player, PlayerStorage, PlayerThrust, ThrustEvent};
use crate::server::part::SpawnPartRequest;
use crate::server::system_sets::PlayerInputSet;
use crate::server::world_config::WorldConfigResource;
@@ 66,6 66,12 @@ fn handle_new_players(
asset_server.load("config/parts/hearty.part.toml"),
))
.insert(PlayerThrust::default())
+ .insert(PlayerStorage {
+ fuel_capacity: 25.0,
+ fuel: 25.0,
+ power_capacity: 25.0,
+ power: 25.0,
+ })
.insert(Player {
client: joined_player,
});
@@ 73,7 79,7 @@ fn handle_new_players(
}
fn player_thrust(
- mut players: Query<(&Transform, &mut ExternalForce, &mut PlayerThrust)>,
+ mut players: Query<(&Transform, &Part, &mut ExternalForce, &mut PlayerThrust, &mut PlayerStorage)>,
clients: Query<&ConnectedNetworkEntity>,
mut thrust_event: EventReader<FromClient<ThrustEvent>>,
world_config: Res<WorldConfigResource>,
@@ 85,7 91,7 @@ fn player_thrust(
{
let ConnectedNetworkEntity { game_entity } = clients.get(*client_entity).unwrap();
- let Ok((_, _, mut thrust)) = players.get_mut(*game_entity) else {
+ let Ok((_, _, _, mut thrust, _)) = players.get_mut(*game_entity) else {
continue;
};
@@ 96,7 102,7 @@ fn player_thrust(
ThrustEvent::Right(on) => thrust.right = on,
}
}
- for (transform, mut force, thrust) in &mut players {
+ for (transform, part, mut force, thrust, mut storage) in &mut players {
let Some(world_config) = &world_config.config else {
return;
};
@@ 154,5 160,7 @@ fn player_thrust(
transform.translation.xy(),
);
*force += external_force;
+
+ storage.fuel -= thrusters.iter().sum::<f32>() * part.strong_config.thruster.as_ref().unwrap().flow_rate;
}
}
M crates/unified/src/shared_plugins.rs => crates/unified/src/shared_plugins.rs +3 -2
@@ 1,6 1,6 @@
use crate::attachment::{Joint, JointOf, PartInShip, Peer, Ship, SnapOf, SnapOfJoint};
use crate::config::planet::Planet;
-use crate::ecs::{DragRequestEvent, Part, Particles, Player, ThrustEvent};
+use crate::ecs::{DragRequestEvent, Part, Particles, Player, PlayerStorage, ThrustEvent};
use bevy::app::{App, PluginGroup, PluginGroupBuilder};
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
@@ 35,7 35,8 @@ pub fn register_everything(app: &mut App) {
.replicate::<Peer>()
.replicate::<JointOf>()
.replicate::<SnapOfJoint>()
- .replicate::<SnapOf>();
+ .replicate::<SnapOf>()
+ .replicate::<PlayerStorage>();
}
fn physics_setup_plugin(app: &mut App) {