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(9142.0833, 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<PartType>,
>,
planet_query: Query<(&Transform, &ReadMassProperties), With<PlanetType>>,
server_config: Res<StkConfig>,
) {
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();
}
}
}