M crates/unified/src/client/mod.rs => crates/unified/src/client/mod.rs +1 -1
@@ 70,7 70,7 @@ fn find_me(
commands.entity(entity).insert(Me);
let mut heart_sprite =
Sprite::from_image(asset_server.load("sprites/hearty_heart.png"));
- heart_sprite.custom_size = Some(Vec2::new(part.width, part.height));
+ heart_sprite.custom_size = Some(Vec2::new(part.strong_config.physics.width, part.strong_config.physics.height));
heart_sprite.color = Color::srgb(20.0, 0.0, 0.0);
commands.spawn((
M crates/unified/src/client/parts.rs => crates/unified/src/client/parts.rs +6 -11
@@ 17,23 17,19 @@ fn handle_incoming_parts(
) {
for (new_entity, new_part) in new_parts.iter() {
trace!(?new_entity, ?new_part, "new part");
- let mut sprite = Sprite::from_image(asset_server.load(&new_part.sprite));
- sprite.custom_size = Some(Vec2::new(new_part.width, new_part.height));
+ let mut sprite = Sprite::from_image(asset_server.load(&new_part.strong_config.part.sprite_disconnected));
+ sprite.custom_size = Some(Vec2::new(new_part.strong_config.physics.width, new_part.strong_config.physics.height));
commands
.entity(new_entity)
.insert(sprite)
.insert(AdditionalMassProperties::MassProperties(MassProperties {
local_center_of_mass: Vec2::ZERO,
- mass: new_part.mass,
+ mass: new_part.strong_config.physics.mass,
principal_inertia: 7.5,
}))
- .insert(ReadMassProperties::default())
- .insert(RigidBody::Dynamic)
.insert(Pickable::default())
.observe(on_part_click);
-
- trace!(?new_part, ?new_entity, "prepared new part");
}
}
fn handle_updated_parts(
@@ 42,8 38,8 @@ fn handle_updated_parts(
asset_server: Res<AssetServer>,
) {
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));
+ let mut sprite = Sprite::from_image(asset_server.load(&updated_part.strong_config.part.sprite_disconnected));
+ sprite.custom_size = Some(Vec2::new(updated_part.strong_config.physics.width, updated_part.strong_config.physics.height));
commands
.entity(updated_entity)
@@ 52,10 48,9 @@ fn handle_updated_parts(
.insert(sprite)
.insert(AdditionalMassProperties::MassProperties(MassProperties {
local_center_of_mass: Vec2::ZERO,
- mass: updated_part.mass,
+ mass: updated_part.strong_config.physics.mass,
principal_inertia: 7.5,
}));
- trace!(?updated_part, ?updated_entity, "updated part");
}
}
M crates/unified/src/config/world.rs => crates/unified/src/config/world.rs +3 -3
@@ 5,7 5,7 @@ use serde::Deserialize;
#[derive(Deserialize, Asset, TypePath, Clone)]
pub struct GlobalWorldConfig {
pub world: WorldConfig,
- pub part: PartConfig,
+ pub part: WPartConfig,
pub hearty: HeartyConfig,
}
@@ 16,8 16,8 @@ pub struct WorldConfig {
pub spawn_parts_interval_secs: f32,
}
-#[derive(Deserialize, Asset, TypePath, Clone)]
-pub struct PartConfig {
+#[derive(Deserialize, Asset, TypePath, Clone, Debug)]
+pub struct WPartConfig {
pub default_width: f32,
pub default_height: f32,
pub default_mass: f32,
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +5 -14
@@ 1,12 1,11 @@
use bevy::ecs::entity::MapEntities;
use bevy::math::Vec2;
-use bevy::prelude::{Bundle, Component, Entity, Event, Resource, Transform};
-use bevy_rapier2d::dynamics::AdditionalMassProperties;
+use bevy::prelude::{Component, Entity, Event, Handle, Resource};
use bevy_rapier2d::dynamics::RigidBody;
-use bevy_rapier2d::geometry::Collider;
use bevy_rapier2d::prelude::*;
use bevy_replicon::prelude::Replicated;
use serde::{Deserialize, Serialize};
+use crate::config::part::PartConfig;
#[derive(Component)]
pub struct MainCamera;
@@ 38,18 37,10 @@ pub enum ThrustEvent {
Replicated
)]
pub struct Part {
- pub sprite: String,
- pub width: f32,
- pub height: f32,
- pub mass: f32,
-}
-#[derive(Bundle)]
-pub struct PartBundle {
- pub part: Part,
- pub transform: Transform,
- pub collider: Collider,
- pub additional_mass_properties: AdditionalMassProperties,
+ pub strong_config: PartConfig
}
+#[derive(Component, Debug)]
+pub struct PartHandle(pub Handle<PartConfig>);
#[derive(Component, Serialize, Deserialize, Debug)]
pub struct Player {
M crates/unified/src/server/part.rs => crates/unified/src/server/part.rs +41 -2
@@ 1,8 1,47 @@
-use crate::config::world::PartConfig;
+use bevy::ecs::system::entity_command::remove;
use bevy::prelude::Component;
use bevy::prelude::*;
+use bevy_rapier2d::prelude::{AdditionalMassProperties, Collider};
+use crate::config::part::PartConfig;
+use crate::ecs::{Part, PartHandle};
-pub fn part_management_plugin(_app: &mut App) {}
+pub fn part_management_plugin(app: &mut App) {
+ app.add_systems(PreUpdate, handle_ready_parts);
+}
+
+#[derive(Bundle)]
+pub struct SpawnPartBundle {
+ pub req: SpawnPartRequest,
+ pub transform: Transform,
+}
#[derive(Component)]
pub struct SpawnPartRequest(pub Handle<PartConfig>);
+
+// wait for parts assets to be ready, then spawn the full part
+pub fn handle_ready_parts(loading_parts: Query<(Entity, &SpawnPartRequest)>, mut commands: Commands, assets: Res<Assets<PartConfig>>) {
+ for (entity, loading_part) in &loading_parts {
+ if let Some(strong_config) = assets.get(&loading_part.0) {
+ // config is strong; spawn 'er in!
+ commands.entity(entity)
+ .insert(calculate_bundle(strong_config, &loading_part.0))
+ .remove::<SpawnPartRequest>();
+ }
+ }
+}
+
+fn calculate_bundle(config: &PartConfig, handle: &Handle<PartConfig>) -> impl Bundle {
+ let part = Part {
+ strong_config: config.clone(),
+ };
+ let part_handle = PartHandle(handle.clone());
+ let collider = Collider::cuboid(config.physics.width / 2.0, config.physics.height / 2.0);
+ let additional_mass_properties = AdditionalMassProperties::Mass(config.physics.mass);
+
+ (
+ part,
+ part_handle,
+ collider,
+ additional_mass_properties,
+ )
+}<
\ No newline at end of file