~starkingdoms/starkingdoms

bfce7aada3774a92f1b304dd3f9cd5524f22fcef — core 5 months ago b072b09
fix: parts
A crates/unified/assets/config/parts/chassis.part.toml => crates/unified/assets/config/parts/chassis.part.toml +14 -0
@@ 0,0 1,14 @@
[part]
name = "Chassis"
sprite_connected = "textures/chassis.png"
sprite_disconnected = "textures/chassis.png"

[physics]
width = 50
height = 50
mass = 100

# North
[[joints]]
translation = [ 0.0, 50.0, 0.0 ]
rotation = 0.0
\ No newline at end of file

M crates/unified/src/client/parts.rs => crates/unified/src/client/parts.rs +1 -0
@@ 18,6 18,7 @@ fn handle_incoming_parts(
    asset_server: Res<AssetServer>,
) {
    for (new_entity, new_part) in new_parts.iter() {
        info!(?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));


M crates/unified/src/server/earth_parts.rs => crates/unified/src/server/earth_parts.rs +3 -21
@@ 9,6 9,7 @@ use crate::config::planet::Planet;
use crate::ecs::{Part, PartBundle};
use crate::server::world_config::WorldConfigResource;
use bevy::prelude::*;
use crate::server::part::SpawnPart;

#[derive(Resource, Default)]
struct PartTimerRes {


@@ 51,25 52,6 @@ pub fn spawn_parts_on_earth(
    new_transform.translation += spawn_planet_pos.translation;

    commands
        .spawn(PartBundle {
            part: Part {
                sprite: "textures/chassis.png".to_string(),
                width: wc.part.default_width,
                height: wc.part.default_height,
                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,
                },
            ),
        })
        .insert(Replicated);
        .spawn(SpawnPart("config/parts/chassis.part.toml".to_string()))
        .insert(new_transform);
}
\ No newline at end of file

M crates/unified/src/server/part.rs => crates/unified/src/server/part.rs +28 -26
@@ 1,12 1,13 @@
use bevy::asset::Handle;
use bevy::prelude::*;
use bevy_rapier2d::prelude::{AdditionalMassProperties, Collider};
use bevy_replicon::prelude::Replicated;
use crate::config::part::PartConfig;
use crate::ecs::Part;

pub fn part_config_plugin(app: &mut App) {
    app.add_systems(PreUpdate, handle_spawn_part_requests)
        .add_systems(Update, (update_part_requests, hotreload));
        .add_systems(Update, update_part_requests);
}

#[derive(Component, Debug)]


@@ 15,20 16,34 @@ pub struct SpawnPart(pub String);
struct LoadingPart(Handle<PartConfig>);
#[derive(Component, Debug)]
struct PartType(AssetId<PartConfig>);
#[derive(Component)]
/// STOP DELETING MY ASSET BEVY
struct LiveConfigHandle(Handle<PartConfig>);

// watch for new SpawnPart components and start loading their config files
fn handle_spawn_part_requests(new_parts: Query<(Entity, &SpawnPart), Added<SpawnPart>>, mut commands: Commands, asset_server: Res<AssetServer>) {
fn handle_spawn_part_requests(new_parts: Query<(Entity, &SpawnPart), Added<SpawnPart>>, mut commands: Commands, asset_server: Res<AssetServer>, assets: Res<Assets<PartConfig>>) {
    for (new_part, request) in &new_parts {
        info!(?new_part, ?request, "answering part request");

        let hdl: Handle<PartConfig> = asset_server.load(request.0.clone());

        commands.entity(new_part)
            .remove::<SpawnPart>()
            .insert(LoadingPart(asset_server.load(request.0.clone())));
            .insert(LiveConfigHandle(hdl.clone()));

        if let Some(cfg) = assets.get(&hdl) {
            spawn_part(commands.reborrow(), new_part, cfg, &hdl.id(), hdl.clone());
        } else {
            commands.entity(new_part)
                .insert(LoadingPart(hdl.clone()));
        }
    }
}
fn update_part_requests(
    mut ev_config: EventReader<AssetEvent<PartConfig>>,
    loading_parts: Query<(Entity, &LoadingPart)>,
    assets: ResMut<Assets<PartConfig>>,
    existing_parts: Query<(Entity, &PartType)>,
    mut assets: ResMut<Assets<PartConfig>>,
    mut commands: Commands
) {
    for ev in ev_config.read() {


@@ 37,44 52,30 @@ fn update_part_requests(
                info!(?id, "asset added");
                for (loading_part, req) in &loading_parts {
                    if req.0.id() == *id {
                        let strong_handle = assets.get_strong_handle(*id).unwrap();
                        let Some(asset) = assets.get(*id) else { continue; };
                        spawn_part(commands.reborrow(), loading_part, asset, id);

                        spawn_part(commands.reborrow(), loading_part, asset, id, strong_handle);
                    }
                }
            },
            AssetEvent::Modified { id } => {
                warn!("asset modification missed!");
            }
            _ => {}
        }
    }
}
fn hotreload(
    mut ev_config: EventReader<AssetEvent<PartConfig>>,
    existing_parts: Query<(Entity, &PartType)>,
    assets: ResMut<Assets<PartConfig>>,
    mut commands: Commands
) {
    for ev in ev_config.read() {
        match ev {
            AssetEvent::Modified { id } => {
                info!(?id, "updating part");
                for (existing_part, ptype) in &existing_parts {
                    if ptype.0 == *id {
                        let strong_handle = assets.get_strong_handle(*id).unwrap();
                        let Some(asset) = assets.get(ptype.0) else { continue; };
                        spawn_part(commands.reborrow(), existing_part, asset, id);

                        spawn_part(commands.reborrow(), existing_part, asset, id, strong_handle);
                    }
                }
            }
            AssetEvent::Added { id } => {
                warn!("asset addition missed!");
            }
            _ => {}
        }
    }
}

fn spawn_part(mut commands: Commands, entity: Entity, part: &PartConfig, id: &AssetId<PartConfig>) {
fn spawn_part(mut commands: Commands, entity: Entity, part: &PartConfig, id: &AssetId<PartConfig>, strong_handle: Handle<PartConfig>) {
    commands.entity(entity)
        .remove::<LoadingPart>()
        .insert(Part {


@@ 85,5 86,6 @@ fn spawn_part(mut commands: Commands, entity: Entity, part: &PartConfig, id: &As
        })
        .insert(Collider::cuboid(part.physics.width / 2.0, part.physics.height / 2.0))
        .insert(AdditionalMassProperties::Mass(part.physics.mass))
        .insert(PartType(*id));
        .insert(PartType(*id))
        .insert(Replicated);
}
\ No newline at end of file