~starkingdoms/starkingdoms

ref: 400713570607b91c1041d6684c337df8f6586d1b starkingdoms/crates/unified/src/server/part.rs -rw-r--r-- 2.2 KiB
40071357 — core fix: part hot reloading 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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) {
    app.add_systems(PreUpdate, (handle_ready_parts, handle_part_reloading));
}

#[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
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 handle_part_reloading(existing_parts: Query<(Entity, &PartHandle)>, assets: Res<Assets<PartConfig>>, mut asset_events: EventReader<AssetEvent<PartConfig>>, mut commands: Commands) {
    for event in asset_events.read() {
        match event {
            AssetEvent::Modified { id } => {
                let config = assets.get(*id).unwrap();
                for existing_part in existing_parts.iter() {
                    if existing_part.1.0.id() == *id {
                        commands.entity(existing_part.0)
                            .insert(calculate_bundle(config, &existing_part.1.0));
                    }
                }
            },
            _ => {}
        }
    }
}

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,
    )
}