~starkingdoms/starkingdoms

d18ffeae50e20652e18195ae14a3097653a96124 — core 5 months ago 8ec2ca8
feat: basic part functionality
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