use bevy::prelude::*; use bevy_rapier2d::prelude::*; use serde::{Deserialize, Serialize}; use crate::{config::StkConfig, module::component::PartType, planet}; use starkingdoms_common::PlanetType as c_PlanetType; #[derive(Component, Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] pub struct PlanetType(pub c_PlanetType); #[derive(Bundle)] pub struct PlanetBundle { pub planet_type: PlanetType, pub transform: TransformBundle, } pub fn spawn_planets(mut commands: Commands) { info!("Spawning planets"); let sun_pos = Transform::from_xyz(0.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Sun), transform: TransformBundle::from(sun_pos), }) .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Sun)).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Sun)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Sun)).size + 0.3, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let mercury_pos = Transform::from_xyz(2322.588, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Mercury), transform: TransformBundle::from(mercury_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Mercury)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Mercury)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Mercury)).size + 0.3, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let venus_pos = Transform::from_xyz(4339.992, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Venus), transform: TransformBundle::from(venus_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Venus)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Venus)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Venus)).size + 0.3, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let earth_pos = Transform::from_xyz(6000.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Earth), transform: TransformBundle::from(earth_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Earth)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Earth)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Earth)).size + 0.3, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let moon_pos = Transform::from_xyz(6030.828, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Moon), transform: TransformBundle::from(moon_pos), }) .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Moon)).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Moon)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Moon)).size + 0.1, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let mars_pos = Transform::from_xyz(9_142.083, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Mars), transform: TransformBundle::from(mars_pos), }) .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Mars)).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Mars)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Mars)).size + 0.1, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let jupiter_pos = Transform::from_xyz(31222.8, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Jupiter), transform: TransformBundle::from(jupiter_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Jupiter)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Jupiter)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Jupiter)).size + 0.1, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let saturn_pos = Transform::from_xyz(57495.6, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Saturn), transform: TransformBundle::from(saturn_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Saturn)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Saturn)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Saturn)).size + 0.1, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let uranus_pos = Transform::from_xyz(115147.56, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Uranus), transform: TransformBundle::from(uranus_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Uranus)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Uranus)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Uranus)).size + 0.1, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let neptune_pos = Transform::from_xyz(180420.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Neptune), transform: TransformBundle::from(neptune_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Neptune)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Neptune)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Neptune)).size + 0.1, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let pluto_pos = Transform::from_xyz(236892.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType(c_PlanetType::Pluto), transform: TransformBundle::from(pluto_pos), }) .insert(Collider::ball( planet!(PlanetType(c_PlanetType::Pluto)).size, )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Pluto)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball( planet!(PlanetType(c_PlanetType::Pluto)).size + 0.1, )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); } pub fn gravity_update( mut part_query: Query< ( &Transform, &ReadMassProperties, &mut ExternalForce, &mut ExternalImpulse, ), With, >, planet_query: Query<(&Transform, &ReadMassProperties), With>, server_config: Res, ) { for (part_transform, part_mp, mut forces, mut impulses) in &mut part_query { forces.force = Vec2::ZERO; impulses.impulse = Vec2::ZERO; forces.torque = 0.; let part_mp = part_mp.get(); let part_mass = part_mp.mass; let part_translate = part_transform.translation; for (planet_transform, planet_mp) in &planet_query { let planet_mp = planet_mp.get(); let planet_mass = planet_mp.mass; let planet_translate = planet_transform.translation; let distance = planet_translate.distance(part_translate); // gravity equation let force = server_config.world.gravity * ((part_mass * planet_mass) / (distance * distance)); // gravity vector let direction = (planet_translate - part_translate).normalize() * force; // apply gravity vector as impulse to body forces.force += direction.xy(); //impulses.impulse += direction.xy(); } } }