M crates/unified/assets/config/planets.pc.toml => crates/unified/assets/config/planets.pc.toml +11 -11
@@ 1,5 1,5 @@
[orbit]
-planet_spring_compliance = 0
+planet_spring_compliance = 0.0
[[planets]]
name = "Sun"
@@ 17,7 17,7 @@ radius = 666.66 # m
mass = 205_000_000.0 # kg
default_transform = [116_129.4, 0.0, 0.0]
planet_resource = { name = "Composite", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.2056, period = 299.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.2056 }
[[planets]]
name = "Venus"
@@ 26,7 26,7 @@ radius = 1899.8 # m
mass = 806_166_000.0 # kg
default_transform = [216_999.6, 0.0, 0.0]
planet_resource = { name = "Sulfur", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.0068, period = 546.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.0068 }
[[planets]]
name = "Earth"
@@ 36,7 36,7 @@ radius = 2000.0 # m
mass = 16_900_000_000.0 # kg
planet_resource = { name = "Carbon", color = { LinearRgba = { red = 1.0, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 2.0 }
default_transform = [300_000.0, 0.0, 0.0]
-orbit = { orbiting = "Sun", eccentricity = 0.0167, period = 900.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.0167 }
[[planets]]
name = "Moon"
@@ 46,7 46,7 @@ radius = 545.4 # m
mass = 360_236_000.0 # kg
default_transform = [312_700.0, 0.0, 0.0]
planet_resource = { name = "Silicon", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Earth", eccentricity = 0.0549, period = 256.0 }
+orbit = { orbiting = "Earth", eccentricity = 0.0549 }
[[planets]]
name = "Mars"
@@ 56,7 56,7 @@ radius = 1062.0 # m
mass = 525_857_000.0 # kg
default_transform = [430_000.0, 0.0, 0.0]
planet_resource = { name = "Iron", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.0934, period = 1745.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.0934 }
[[planets]]
name = "Jupiter"
@@ 65,7 65,7 @@ radius = 21946.0 # m
mass = 1_131_221_218_000.0 # kg
default_transform = [1_561_140.0, 0.0, 0.0]
planet_resource = { name = "Hydrogen", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.0484, period = 11218.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.0484 }
[[planets]]
name = "Saturn"
@@ 74,7 74,7 @@ radius = 18_280.4 # m
mass = 561_386_112_000.0 # kg
default_transform = [2_874_780.0, 0.0, 0.0]
planet_resource = { name = "Helium", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.0541, period = 28297.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.0541 }
[[planets]]
name = "Uranus"
@@ 83,7 83,7 @@ radius = 8014.0 # m
mass = 69_763_532_000.0 # kg
default_transform = [4_050_000.0, 0.0, 0.0]
planet_resource = { name = "Rubber", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.0472, period = 46791.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.0472 }
[[planets]]
name = "Neptune"
@@ 92,7 92,7 @@ radius = 7_766.0 # m
mass = 106_674_649_000.0 # kg
default_transform = [5_000_000.0, 0.0, 0.0]
planet_resource = { name = "Methane", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.0086, period = 60454.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.0086 }
[[planets]]
name = "Pluto"
@@ 101,4 101,4 @@ radius = 373.6 # m
mass = 10_817_000.0 # kg
default_transform = [5_922_300.0, 0.0, 0.0]
planet_resource = { name = "Ice", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
-orbit = { orbiting = "Sun", eccentricity = 0.2488, period = 118234.0 }
+orbit = { orbiting = "Sun", eccentricity = 0.2488 }
M crates/unified/src/client/starguide/orbit.rs => crates/unified/src/client/starguide/orbit.rs +13 -8
@@ 13,7 13,7 @@ fn update_orbits(
me: Single<(&Transform, &LinearVelocity), (With<Me>, Without<StarguideCamera>)>,
mut gizmos: Gizmos<StarguideGizmos>,
world_config: Res<WorldConfigResource>,
- planets: Query<(&Mass, &Planet, &Transform)>,
+ planets: Query<(&Mass, &Planet, &Transform, &LinearVelocity)>,
) {
let Some(world_config) = &world_config.config else {
return;
@@ 22,12 22,13 @@ fn update_orbits(
let mut p_mass = None;
let mut p_transform = None;
- let (sun_mass, _, sun_transform) = planets.iter().find(|planet| planet.1.name == "Sun").unwrap();
+ let mut p_velocity = None;
+ let (sun_mass, _, sun_transform, sun_velocity) = planets.iter().find(|planet| planet.1.name == "Sun").unwrap();
let mut closest = f32::INFINITY;
- for (mass, planet, transform) in planets {
+ for (mass, planet, transform, velocity) in planets {
if planet.name == "Sun" { continue }
- let (other_mass, _, other_transform) = planets.iter().find(|f_planet| f_planet.1.name == planet.orbit.clone().unwrap().orbiting).unwrap();
+ let (other_mass, _, other_transform, other_velocity) = planets.iter().find(|f_planet| f_planet.1.name == planet.orbit.clone().unwrap().orbiting).unwrap();
let a = other_transform.translation - transform.translation;
let hill_sphere = a.length()*(mass.0/(3.0*(other_mass.0+mass.0))).powf(1.0/3.0);
@@ 37,24 38,28 @@ fn update_orbits(
if rel_dist < closest && hill_sphere > rel_dist {
p_mass = Some(mass.0);
p_transform = Some(*transform);
+ p_velocity = Some(*velocity);
closest = rel_dist;
}
}
if p_mass.is_none() {
p_mass = Some(sun_mass.0);
p_transform = Some(*sun_transform);
+ p_velocity = Some(*sun_velocity);
}
let p_mass = p_mass.unwrap();
let p_transform = p_transform.unwrap();
+ let p_velocity = p_velocity.unwrap();
// orbit magic
let rel_pos = me.0.translation - p_transform.translation;
+ let rel_vel = me.1.0 - p_velocity.0;
let u = world_config.world.gravity*p_mass;
- let h = rel_pos.x*me.1.y - rel_pos.y*me.1.x;
+ let h = rel_pos.x*rel_vel.y - rel_pos.y*rel_vel.x;
let r = rel_pos.length();
- let a = (u*r) / (2.0*u - r*(me.1.x*me.1.x + me.1.y*me.1.y));
- let e_x = rel_pos.x/r - (h*me.1.y)/u;
- let e_y = rel_pos.y/r + (h*me.1.x)/u;
+ let a = (u*r) / (2.0*u - r*(rel_vel.x*rel_vel.x + rel_vel.y*rel_vel.y));
+ let e_x = rel_pos.x/r - (h*rel_vel.y)/u;
+ let e_y = rel_pos.y/r + (h*rel_vel.x)/u;
let f_x = -2.0*a*e_x;
let f_y = -2.0*a*e_y;
M crates/unified/src/config/planet.rs => crates/unified/src/config/planet.rs +0 -1
@@ 49,7 49,6 @@ pub struct PlanetResource {
pub struct OrbitData {
pub orbiting: String,
pub eccentricity: f32,
- pub period: f32
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug)]
M crates/unified/src/server/craft.rs => crates/unified/src/server/craft.rs +7 -6
@@ 8,8 8,8 @@ pub fn craft_plugin(app: &mut App) {
fn receive_crafting_request(
mut craft_part_request: MessageReader<FromClient<CraftPartRequest>>,
- part_query: Query<(&Transform, &Part, &PartInShip)>,
- player_query: Query<(Entity, &Transform, &Part), With<Player>>,
+ part_query: Query<(&Transform, &LinearVelocity, &Part, &PartInShip)>,
+ player_query: Query<(Entity, &Transform, &LinearVelocity, &Part), With<Player>>,
parts_query: Query<&Parts>,
mut single_storage_query: Query<(&mut SingleStorage)>,
mut variable_storage_query: Query<(&mut VariableStorage)>,
@@ 18,15 18,15 @@ fn receive_crafting_request(
) {
'request: for request in craft_part_request.read() {
// TODO: make crafting take time
- let (transform, part, parts_list) = if let Ok((transform, part, part_in_ship)) = part_query.get(request.crafting_part) {
+ let (transform, vel, part, parts_list) = if let Ok((transform, vel, part, part_in_ship)) = part_query.get(request.crafting_part) {
// this is a normal part
let Ok(parts_list) = parts_query.get(part_in_ship.0) else {
warn!("Couldn't find parts list in part in ship");
continue;
};
let parts_list = parts_list.iter().collect::<Vec<_>>();
- (transform, part, parts_list)
- } else if let Ok((entity, transform, part)) = player_query.get(request.crafting_part) {
+ (transform, vel, part, parts_list)
+ } else if let Ok((entity, transform, vel, part)) = player_query.get(request.crafting_part) {
// this is a player
let parts_list = if let Ok(parts_list) = parts_query.get(entity) {
let mut parts_list = parts_list.iter().collect::<Vec<_>>();
@@ 35,7 35,7 @@ fn receive_crafting_request(
} else {
vec![entity]
};
- (transform, part, parts_list)
+ (transform, vel, part, parts_list)
} else {
warn!("When receiving a crafting request, the crafting part didn't exist.");
continue;
@@ 113,6 113,7 @@ fn receive_crafting_request(
req: SpawnPartRequest(asset_server.load(
format!("config/parts/{}.part.toml", request.crafted_part.to_lowercase()))),
transform: transform.with_translation(transform.translation + vec3(50.0, 0.0, 0.0)),
+ vel: *vel,
});
}
}
M crates/unified/src/server/earth_parts.rs => crates/unified/src/server/earth_parts.rs +5 -4
@@ 18,7 18,7 @@ pub fn spawn_parts_plugin(app: &mut App) {
fn spawn_parts_on_earth(
mut commands: Commands,
world_config: Res<WorldConfigResource>,
- planets: Query<(&Transform, &Planet)>,
+ planets: Query<(&Transform, &LinearVelocity, &Planet)>,
mut timer: ResMut<PartTimerRes>,
asset_server: Res<AssetServer>,
time: Res<Time>,
@@ 34,8 34,8 @@ fn spawn_parts_on_earth(
timer.timer = Timer::from_seconds(wc.world.spawn_parts_interval_secs, TimerMode::Once);
// find earth
- let Some((spawn_planet_pos, spawn_planet)) =
- planets.iter().find(|p| p.1.name == wc.hearty.spawn_at)
+ let Some((spawn_planet_pos, spawn_planet_vel, spawn_planet)) =
+ planets.iter().find(|p| p.2.name == wc.hearty.spawn_at)
else {
return;
};
@@ 48,6 48,7 @@ fn spawn_parts_on_earth(
commands
.spawn(SpawnPartBundle {
req: SpawnPartRequest(asset_server.load("config/parts/housing.part.toml")),
- transform: new_transform
+ transform: new_transform,
+ vel: *spawn_planet_vel,
});
}
M crates/unified/src/server/orbit/mod.rs => crates/unified/src/server/orbit/mod.rs +10 -4
@@ 1,6 1,7 @@
use std::collections::HashMap;
+use std::f32::consts::PI;
use avian2d::math::TAU;
-use avian2d::prelude::LinearVelocity;
+use avian2d::prelude::{LinearVelocity, Mass};
use bevy::log::debug;
use bevy::math::ops::atan2;
use bevy::prelude::{Component, Plugin, Transform};
@@ 8,6 9,7 @@ use bevy::time::Time;
use serde::{Deserialize, Serialize};
use crate::config::planet::{Planet, PlanetSpring, PlanetSpringJoint};
use crate::prelude::{App, Query, Res, Update, Without};
+use crate::world_config::WorldConfigResource;
pub struct OrbitPlugin;
impl Plugin for OrbitPlugin {
@@ 18,10 20,14 @@ impl Plugin for OrbitPlugin {
fn update_orbits(
mut planets: Query<(&Planet, &Transform, &mut LinearVelocity), Without<PlanetSpring>>,
- planets_2: Query<(&Planet, &Transform), Without<PlanetSpring>>,
+ planets_2: Query<(&Planet, &Transform, &Mass), Without<PlanetSpring>>,
mut planet_springs: Query<(&PlanetSpring, &mut Transform), Without<Planet>>,
+ world_config: Res<WorldConfigResource>,
time: Res<Time>
) {
+ let Some(ref world_config) = world_config.config else {
+ return;
+ };
let parent_velocities = planets.iter().map(|u| (u.0.name.clone(), u.2.clone())).collect::<HashMap<String, LinearVelocity>>();
for (planet, _, mut vel) in planets.iter_mut() {
let Some(orbit_data) = &planet.orbit else { continue; };
@@ 30,7 36,7 @@ fn update_orbits(
let a = (planet.default_transform[0] - parent.0.default_transform[0]) / (1.0 - orbit_data.eccentricity);
let e = orbit_data.eccentricity;
- let t = orbit_data.period;
+ let t = 2.0*PI*((a*a*a)/(world_config.world.gravity*(**parent.2))).sqrt();
let time = time.elapsed_secs();
@@ 71,4 77,4 @@ fn iterative_kepler(m: f32, e: f32) -> f32 {
}
}
output
-}>
\ No newline at end of file
+}
M crates/unified/src/server/part.rs => crates/unified/src/server/part.rs +1 -0
@@ 15,6 15,7 @@ pub fn part_management_plugin(app: &mut App) {
pub struct SpawnPartBundle {
pub req: SpawnPartRequest,
pub transform: Transform,
+ pub vel: LinearVelocity,
}
#[derive(Component)]
M crates/unified/src/server/planets.rs => crates/unified/src/server/planets.rs +5 -3
@@ 46,7 46,7 @@ pub fn update_planets(
let planet_config = assets.get(*id).unwrap();
for planet in &planet_config.planets {
let mut planet_entity = commands
- .spawn(PlanetBundle {
+ .spawn((PlanetBundle {
planet: planet.clone(),
transform: Transform::from_xyz(
planet.default_transform[0],
@@ 55,7 55,9 @@ pub fn update_planets(
),
collider: Collider::circle(planet.radius),
mass: Mass(planet.mass)
- }).with_child((
+ },
+ SleepingDisabled
+ )).with_child((
Collider::circle(planet.radius+2.0),
Sensor,
PlanetSensor(planet.name.clone()),
@@ 76,7 78,7 @@ pub fn update_planets(
PlanetSpringJoint {
name: planet.name.clone()
},
- FixedJoint::new(planet_entity, spring).with_point_compliance(planet_config.orbit.planet_spring_compliance)
+ FixedJoint::new(planet_entity, spring).with_point_compliance(planet_config.orbit.planet_spring_compliance),
));
}
M crates/unified/src/server/player/join.rs => crates/unified/src/server/player/join.rs +8 -5
@@ 7,7 7,9 @@ use crate::server::ConnectedGameEntity;
use crate::server::part::SpawnPartRequest;
use crate::world_config::WorldConfigResource;
-fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldConfig, planets: Query<(&Transform, &Planet)>, asset_server: &AssetServer) {
+fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldConfig,
+ planets: Query<(&Transform, &LinearVelocity, &Planet)>, asset_server: &AssetServer
+) {
trace!(?joined_player, "detected joined player!");
// find earth
if planets.is_empty() {
@@ 15,9 17,9 @@ fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldCo
commands.entity(joined_player).insert(PendingPlayer);
return;
}
- let (spawn_planet_pos, spawn_planet) = planets
+ let (spawn_planet_pos, spawn_planet_vel, spawn_planet) = planets
.iter()
- .find(|p| p.1.name == wc.hearty.spawn_at)
+ .find(|p| p.2.name == wc.hearty.spawn_at)
.unwrap_or_else(|| {
panic!(
"spawn planet {} is missing? (check that the planet is named exactly '{}')",
@@ 48,6 50,7 @@ fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldCo
.insert(Player {
client: joined_player,
})
+ .insert(*spawn_planet_vel)
.remove::<PendingPlayer>();
}
@@ 59,7 62,7 @@ pub fn handle_new_players(
mut commands: Commands,
q_new_clients: Query<(Entity, &ConnectedGameEntity), Added<ConnectedGameEntity>>,
world_config: Res<WorldConfigResource>,
- planets: Query<(&Transform, &Planet)>,
+ planets: Query<(&Transform, &LinearVelocity, &Planet)>,
mut hi_writer: MessageWriter<ToClients<Hi>>,
asset_server: Res<AssetServer>,
) {
@@ 87,7 90,7 @@ pub fn handle_pending_players(
mut commands: Commands,
pending_players: Query<Entity, With<PendingPlayer>>,
world_config: Res<WorldConfigResource>,
- planets: Query<(&Transform, &Planet)>,
+ planets: Query<(&Transform, &LinearVelocity, &Planet)>,
asset_server: Res<AssetServer>,
) {
let Some(wc) = &world_config.config else {