~starkingdoms/starkingdoms

ref: 69730b33b8aed64f6b26e6cdcb334a7cec4e54f4 starkingdoms/crates/unified/src/server/planets.rs -rw-r--r-- 3.8 KiB
69730b33 — core planets 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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use bevy::asset::Handle;
use bevy::prelude::*;
use bevy_rapier2d::dynamics::AdditionalMassProperties;
use bevy_rapier2d::prelude::Collider;
use bevy_replicon::prelude::Replicated;
use crate::config::planet::{Planet, PlanetBundle, PlanetConfigCollection};

pub fn planets_plugin(app: &mut App) {
    app
        .init_resource::<PlanetConfigResource>()
        .add_systems(Startup, start_loading_planets)
        .add_systems(Update, update_planets);
}

#[derive(Resource, Default)]
pub struct PlanetConfigResource {
    handle: Option<Handle<PlanetConfigCollection>>
}

fn start_loading_planets(assets: Res<AssetServer>, mut planets: ResMut<PlanetConfigResource>) {
    planets.handle = Some(assets.load("config/planets.pc.toml"));
}


pub fn update_planets(
    mut commands: Commands,
    mut ev_config: EventReader<AssetEvent<PlanetConfigCollection>>,
    mut assets: ResMut<Assets<PlanetConfigCollection>>,
    mut planets: ResMut<PlanetConfigResource>,
    mut q_planets: Query<(Entity, &mut Planet, &mut Transform, &mut AdditionalMassProperties)>
) {
    let Some(handle) = planets.handle.as_ref() else { return; };

    let waiting_for_asset_id = handle.id();

    for ev in ev_config.read() {
        match ev {
            AssetEvent::Added { id } => {
                if *id == waiting_for_asset_id {
                    info!("planet config loaded - creating planets");
                    let planet_config = assets.get(*id).unwrap();
                    for planet in &planet_config.planets {
                        commands.spawn(PlanetBundle {
                            planet: planet.clone(),
                            transform: Transform::from_xyz(planet.default_transform[0], planet.default_transform[1], planet.default_transform[2]),
                            collider: Collider::ball(planet.radius),
                            additional_mass_properties: AdditionalMassProperties::Mass(planet.mass),
                        }).insert(Replicated);
                        info!(?planet, "new planet spawned");
                    }
                }
            },
            AssetEvent::Modified { id } => {
                if *id == waiting_for_asset_id {
                    info!("planet config modified - reloading planets");
                    let planet_config = assets.get(*id).unwrap();

                    for planet in &planet_config.planets {
                        let existing_planet = q_planets.iter_mut().find(|(_, p, _, _)| p.name == planet.name);

                        if let Some((existing, mut e_planet, mut e_transform, mut e_mass)) = existing_planet {
                            commands.entity(existing)
                                .remove::<Collider>()
                                .insert(Collider::ball(planet.radius));
                            *e_planet = planet.clone();
                            e_transform.translation = Vec3::new(planet.default_transform[0], planet.default_transform[1], planet.default_transform[2]);
                            *e_mass = AdditionalMassProperties::Mass(planet.mass);
                            info!(?planet, "planet hot-reloaded");
                        } else {
                            commands.spawn(PlanetBundle {
                                planet: planet.clone(),
                                transform: Transform::from_xyz(planet.default_transform[0], planet.default_transform[1], planet.default_transform[2]),
                                collider: Collider::ball(planet.radius),
                                additional_mass_properties: AdditionalMassProperties::Mass(planet.mass),
                            }).insert(Replicated);
                            info!(?planet, "new planet spawned");
                        }


                    }
                }
            },
            _ => {}
        }
    }
}