use crate::shared::config::planet::{Planet, PlanetSpring, PlanetSpringJoint, SpecialSpriteProperties}; use crate::prelude::*; use crate::shared::ecs::{MAIN_STAR_LAYERS}; const PLANET_SPRING_COMPLIANCE: f64 = 0.01; const PLANET_SPRING_DAMPING: f64 = 0.1; pub fn incoming_planets_plugin(app: &mut App) { app.add_systems(Update, (handle_incoming_planets, handle_updated_planets, setup_planet_spring_joints)); } fn build_planet_sprite(planet: &Planet, asset_server: &AssetServer) -> Sprite { let mut sprite = Sprite::from_image(asset_server.load(&planet.sprite)); sprite.custom_size = Some(Vec2::splat(planet.radius as f32 * 2.0)); if let Some(SpecialSpriteProperties::ForceColor(c)) = planet.special_sprite_properties { sprite.color = c; } sprite } fn handle_incoming_planets( mut commands: Commands, new_planets: Query<(Entity, &Planet), Added>, asset_server: Res, ) { for (new_entity, new_planet) in new_planets.iter() { commands.entity(new_entity) .insert(MAIN_STAR_LAYERS.clone()) .insert(build_planet_sprite(new_planet, &asset_server)); trace!(?new_planet, "prepared new planet"); } } fn handle_updated_planets( mut commands: Commands, updated_planets: Query<(Entity, &Planet), Changed>, asset_server: Res, ) { for (updated_entity, updated_planet) in updated_planets.iter() { commands.entity(updated_entity) .remove::() .insert(build_planet_sprite(updated_planet, &asset_server)); trace!(?updated_planet, "updated planet"); } } #[derive(Component)] struct SpringJointReady; fn setup_planet_spring_joints( unmatched_springs: Query<(Entity, &PlanetSpring), Without>, planets: Query<(Entity, &Planet)>, mut commands: Commands, ) { for (spring_entity, spring) in unmatched_springs.iter() { let Some((planet_entity, _)) = planets.iter().find(|(_, p)| p.name == spring.name) else { continue; }; commands.entity(spring_entity).insert(( RigidBody::Kinematic, LinearVelocity::default(), SpringJointReady, )); commands.spawn(( PlanetSpringJoint { name: spring.name.clone() }, FixedJoint::new(planet_entity, spring_entity) .with_point_compliance(PLANET_SPRING_COMPLIANCE), JointDamping { linear: PLANET_SPRING_DAMPING, angular: 1.0 }, )); } }