Compare commits
No commits in common. "678979db7e0ae2eebadf0165c4e3657f21b17a83" and "242e06ebf1dba274d11d36f47678818d45da124f" have entirely different histories.
678979db7e
...
242e06ebf1
|
@ -1,7 +1,5 @@
|
||||||
# v0.14.0-dev
|
# v0.14.0-dev
|
||||||
|
|
||||||
- Implement fast travel (must be unlocked by getting phone number of FASTravel)
|
|
||||||
- Implement phone calls
|
|
||||||
- Chats don't automatically advance now, the player has to press "Continue"
|
- Chats don't automatically advance now, the player has to press "Continue"
|
||||||
- Add sparkles to Jupiter's ring ✨😍✨ best visible from Farview Station
|
- Add sparkles to Jupiter's ring ✨😍✨ best visible from Farview Station
|
||||||
- Add setting to change pointer
|
- Add setting to change pointer
|
||||||
|
|
62
src/chat.rs
62
src/chat.rs
|
@ -21,13 +21,10 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
pub const CHATS: &[&str] = &[
|
pub const CHATS: &[&str] = &[
|
||||||
include_str!("chats/fastravel.yaml"),
|
include_str!("chats/fastravel.yaml"),
|
||||||
include_str!("chats/phone.yaml"),
|
|
||||||
include_str!("chats/serenity.yaml"),
|
include_str!("chats/serenity.yaml"),
|
||||||
include_str!("chats/thebe.yaml"),
|
include_str!("chats/thebe.yaml"),
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const CONTACTS: &[&str] = &["icarus", "travel", "luna", "nox"];
|
|
||||||
|
|
||||||
pub const TEXT_CONTINUE: &str = "Continue...";
|
pub const TEXT_CONTINUE: &str = "Continue...";
|
||||||
|
|
||||||
pub const TOKEN_CHAT: &str = "chat";
|
pub const TOKEN_CHAT: &str = "chat";
|
||||||
|
@ -893,13 +890,11 @@ pub fn handle_chat_scripts(
|
||||||
With<actor::Player>,
|
With<actor::Player>,
|
||||||
>,
|
>,
|
||||||
mut q_playercam: Query<(&mut Position, &mut LinearVelocity), With<actor::PlayerCamera>>,
|
mut q_playercam: Query<(&mut Position, &mut LinearVelocity), With<actor::PlayerCamera>>,
|
||||||
mut q_chats: Query<&mut Chat>,
|
|
||||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||||
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
|
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
|
||||||
mut ew_achievement: EventWriter<game::AchievementEvent>,
|
mut ew_achievement: EventWriter<game::AchievementEvent>,
|
||||||
id2pos: Res<game::Id2Pos>,
|
id2pos: Res<game::Id2Pos>,
|
||||||
id2v: Res<game::Id2V>,
|
id2v: Res<game::Id2V>,
|
||||||
mut prefs: ResMut<Preferences>,
|
|
||||||
) {
|
) {
|
||||||
for script in er_chatscript.read() {
|
for script in er_chatscript.read() {
|
||||||
// Parse the script string
|
// Parse the script string
|
||||||
|
@ -1007,33 +1002,6 @@ pub fn handle_chat_scripts(
|
||||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Drink));
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Drink));
|
||||||
ew_achievement.send(game::AchievementEvent::DrinkPizza);
|
ew_achievement.send(game::AchievementEvent::DrinkPizza);
|
||||||
}
|
}
|
||||||
"changename" => {
|
|
||||||
let mut new_name = param1.to_string();
|
|
||||||
if !param2.is_empty() {
|
|
||||||
if !new_name.is_empty() {
|
|
||||||
new_name += " ";
|
|
||||||
}
|
|
||||||
new_name += param2;
|
|
||||||
}
|
|
||||||
for mut chat in &mut q_chats {
|
|
||||||
if new_name.is_empty() {
|
|
||||||
chat.talker.name = None;
|
|
||||||
} else {
|
|
||||||
chat.talker.name = Some(new_name.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"registercontact" => {
|
|
||||||
if CONTACTS.contains(¶m1) {
|
|
||||||
let param1_string = param1.to_string();
|
|
||||||
if !prefs.contacts.contains(¶m1_string) {
|
|
||||||
prefs.contacts.push(param1_string);
|
|
||||||
prefs.save();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error!("Can't register contact `{param1}', it doesn't exist in the chat::CONTACTS constant.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
error!("Error, undefined chat script {name}");
|
error!("Error, undefined chat script {name}");
|
||||||
}
|
}
|
||||||
|
@ -1044,7 +1012,6 @@ pub fn handle_chat_scripts(
|
||||||
pub fn update_chat_variables(
|
pub fn update_chat_variables(
|
||||||
mut vars: ResMut<var::GameVars>,
|
mut vars: ResMut<var::GameVars>,
|
||||||
settings: Res<var::Settings>,
|
settings: Res<var::Settings>,
|
||||||
prefs: Res<var::Preferences>,
|
|
||||||
q_player: Query<&actor::Suit, With<actor::Player>>,
|
q_player: Query<&actor::Suit, With<actor::Player>>,
|
||||||
) {
|
) {
|
||||||
if let Ok(suit) = q_player.get_single() {
|
if let Ok(suit) = q_player.get_single() {
|
||||||
|
@ -1058,7 +1025,15 @@ pub fn update_chat_variables(
|
||||||
"player_suit_health_percent",
|
"player_suit_health_percent",
|
||||||
((suit.integrity * 100.0).round() as u8).to_string(),
|
((suit.integrity * 100.0).round() as u8).to_string(),
|
||||||
);
|
);
|
||||||
vars.set_in_scope("$", "ar", bool2chatvar(settings.hud_active));
|
vars.set_in_scope(
|
||||||
|
"$",
|
||||||
|
"ar",
|
||||||
|
if settings.hud_active {
|
||||||
|
String::from("1")
|
||||||
|
} else {
|
||||||
|
String::from("0")
|
||||||
|
},
|
||||||
|
);
|
||||||
let wears_chefhat = if let Some(ava) = hud::PLAYER_AR_AVATARS.get(settings.ar_avatar) {
|
let wears_chefhat = if let Some(ava) = hud::PLAYER_AR_AVATARS.get(settings.ar_avatar) {
|
||||||
match ava.0 {
|
match ava.0 {
|
||||||
hud::Avatar::ChefHat => 1,
|
hud::Avatar::ChefHat => 1,
|
||||||
|
@ -1068,24 +1043,5 @@ pub fn update_chat_variables(
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
vars.set_in_scope("$", "chefhat", wears_chefhat.to_string());
|
vars.set_in_scope("$", "chefhat", wears_chefhat.to_string());
|
||||||
|
|
||||||
// Set phone variables
|
|
||||||
let mut any = false;
|
|
||||||
for contact in CONTACTS {
|
|
||||||
let value = prefs.contacts.contains(&contact.to_string());
|
|
||||||
if value {
|
|
||||||
any = true;
|
|
||||||
}
|
|
||||||
vars.set_in_scope("phone", contact, bool2chatvar(value));
|
|
||||||
}
|
|
||||||
vars.set_in_scope("phone", "any", bool2chatvar(any));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bool2chatvar(var: bool) -> String {
|
|
||||||
if var {
|
|
||||||
String::from("1")
|
|
||||||
} else {
|
|
||||||
String::from("0")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,10 +96,6 @@
|
||||||
- Can you please fill up my oxygen tank without taking me anywhere?:
|
- Can you please fill up my oxygen tank without taking me anywhere?:
|
||||||
- script: refilloxygen 1000
|
- script: refilloxygen 1000
|
||||||
- Of course, you can count on FASTravel!
|
- Of course, you can count on FASTravel!
|
||||||
- I wish I could use your services from anywhere!:
|
|
||||||
- Actually, you can!
|
|
||||||
- script: registercontact travel
|
|
||||||
- Here's our phone number, call us any time!
|
|
||||||
- Is there anything interesting to do around here?:
|
- Is there anything interesting to do around here?:
|
||||||
- goto: interesting
|
- goto: interesting
|
||||||
- No, thank you.:
|
- No, thank you.:
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
- chat: phone
|
|
||||||
- if ~phone$any:
|
|
||||||
- "Error: Phonebook empty."
|
|
||||||
- goto: EXIT
|
|
||||||
- Select contact to call.
|
|
||||||
- if: phone$travel
|
|
||||||
FASTravel:
|
|
||||||
- goto: travel
|
|
||||||
- "[Cancel]":
|
|
||||||
- goto: EXIT
|
|
||||||
|
|
||||||
- label: travel
|
|
||||||
- script: changename FASTravel
|
|
||||||
- Welcome to FASTravel™, how can I help you today?
|
|
||||||
- label: travel_mainnode
|
|
||||||
- Can you pick me up please?:
|
|
||||||
- Yes! Where should we drop you off?
|
|
||||||
- Serenity Station:
|
|
||||||
- Ok! Activate cryofreeze and we'll be right there.
|
|
||||||
- "[Activate Cryofreeze]":
|
|
||||||
- script: cryofadeout
|
|
||||||
- sleep: 5
|
|
||||||
- script: cryotrip serenity
|
|
||||||
- goto: EXIT
|
|
||||||
- I changed my mind.:
|
|
||||||
- Alright. Anything else I can help you with?
|
|
||||||
- goto: travel_mainnode
|
|
||||||
- Metis Prime Station:
|
|
||||||
- Ok! Activate cryofreeze and we'll be right there.
|
|
||||||
- "[Activate Cryofreeze]":
|
|
||||||
- script: cryofadeout
|
|
||||||
- sleep: 5
|
|
||||||
- script: cryotrip metisprime
|
|
||||||
- goto: EXIT
|
|
||||||
- I changed my mind.:
|
|
||||||
- Alright. Anything else I can help you with?
|
|
||||||
- goto: travel_mainnode
|
|
||||||
- Farview Station:
|
|
||||||
- Ok! Activate cryofreeze and we'll be right there.
|
|
||||||
- "[Activate Cryofreeze]":
|
|
||||||
- script: cryofadeout
|
|
||||||
- sleep: 5
|
|
||||||
- script: cryotrip farview
|
|
||||||
- goto: EXIT
|
|
||||||
- I changed my mind.:
|
|
||||||
- Alright. Anything else I can help you with?
|
|
||||||
- goto: travel_mainnode
|
|
||||||
- I just wanted to say that you're awesome!:
|
|
||||||
- Thank you so much!
|
|
||||||
- Hearing this makes my day!
|
|
||||||
- Satisfying our customers is what I'm programmed to live for.
|
|
||||||
- Good bye!:
|
|
||||||
- goto: EXIT
|
|
||||||
- "[Hang up]":
|
|
||||||
- goto: EXIT
|
|
|
@ -18,7 +18,6 @@ use bevy_xpbd_3d::prelude::*;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA";
|
pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA";
|
||||||
pub const ID_PLAYER: &str = "player";
|
|
||||||
pub const ID_EARTH: &str = "earth";
|
pub const ID_EARTH: &str = "earth";
|
||||||
pub const ID_SOL: &str = "sol";
|
pub const ID_SOL: &str = "sol";
|
||||||
pub const ID_JUPITER: &str = "jupiter";
|
pub const ID_JUPITER: &str = "jupiter";
|
||||||
|
@ -902,9 +901,9 @@ fn spawn_entities(
|
||||||
|
|
||||||
let orbited_mass: Option<f64> = if let Some(id) = &state.orbit_object_id {
|
let orbited_mass: Option<f64> = if let Some(id) = &state.orbit_object_id {
|
||||||
match id.as_str() {
|
match id.as_str() {
|
||||||
ID_JUPITER => Some(nature::JUPITER_MASS),
|
"jupiter" => Some(nature::JUPITER_MASS),
|
||||||
ID_EARTH => Some(nature::EARTH_MASS),
|
"earth" => Some(nature::EARTH_MASS),
|
||||||
ID_SOL => Some(nature::SOL_MASS),
|
"sol" => Some(nature::SOL_MASS),
|
||||||
_ => {
|
_ => {
|
||||||
error!("Found no mass for object `{id}`");
|
error!("Found no mass for object `{id}`");
|
||||||
continue;
|
continue;
|
||||||
|
|
21
src/game.rs
21
src/game.rs
|
@ -98,7 +98,6 @@ pub enum GameEvent {
|
||||||
SetShadows(Turn),
|
SetShadows(Turn),
|
||||||
UpdateFlashlight,
|
UpdateFlashlight,
|
||||||
Achievement(String),
|
Achievement(String),
|
||||||
PhoneCall,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Turn {
|
pub enum Turn {
|
||||||
|
@ -163,7 +162,6 @@ pub fn setup(mut settings: ResMut<Settings>, prefs: ResMut<var::Preferences>) {
|
||||||
pub fn handle_game_event(
|
pub fn handle_game_event(
|
||||||
mut settings: ResMut<Settings>,
|
mut settings: ResMut<Settings>,
|
||||||
mut er_game: EventReader<GameEvent>,
|
mut er_game: EventReader<GameEvent>,
|
||||||
mut ew_conv: EventWriter<chat::StartConversationEvent>,
|
|
||||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||||
mut ew_updateoverlays: EventWriter<hud::UpdateOverlayVisibility>,
|
mut ew_updateoverlays: EventWriter<hud::UpdateOverlayVisibility>,
|
||||||
mut ew_updatemenu: EventWriter<menu::UpdateMenuEvent>,
|
mut ew_updatemenu: EventWriter<menu::UpdateMenuEvent>,
|
||||||
|
@ -272,19 +270,6 @@ pub fn handle_game_event(
|
||||||
spotlight.intensity = actor::FLASHLIGHT_INTENSITY[prefs.flashlight_power];
|
spotlight.intensity = actor::FLASHLIGHT_INTENSITY[prefs.flashlight_power];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GameEvent::PhoneCall => {
|
|
||||||
let talker = chat::Talker {
|
|
||||||
chat_name: "phone".to_string(),
|
|
||||||
actor_id: "".to_string(),
|
|
||||||
name: Some("Phone".to_string()),
|
|
||||||
counts_towards_achievement: false,
|
|
||||||
pronoun: None,
|
|
||||||
talking_speed: 0.0,
|
|
||||||
};
|
|
||||||
ew_conv.send(chat::StartConversationEvent {
|
|
||||||
talker: talker,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,7 +486,7 @@ fn update_id2pos(
|
||||||
id2pos.0.clear();
|
id2pos.0.clear();
|
||||||
for (pos, id) in &q_id {
|
for (pos, id) in &q_id {
|
||||||
id2pos.0.insert(id.0.clone(), pos.0);
|
id2pos.0.insert(id.0.clone(), pos.0);
|
||||||
if id.0 == cmd::ID_JUPITER {
|
if id.0 == "jupiter" {
|
||||||
jupiterpos.0 = pos.0;
|
jupiterpos.0 = pos.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -609,12 +594,12 @@ fn check_achievements(
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let pos_sun = if let Some(pos) = id2pos.0.get(cmd::ID_SOL) {
|
let pos_sun = if let Some(pos) = id2pos.0.get("sol") {
|
||||||
pos
|
pos
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let pos_jupiter = if let Some(pos) = id2pos.0.get(cmd::ID_JUPITER) {
|
let pos_jupiter = if let Some(pos) = id2pos.0.get("jupiter") {
|
||||||
pos
|
pos
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
|
56
src/menu.rs
56
src/menu.rs
|
@ -49,8 +49,6 @@ pub struct MenuElement;
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct MenuTopLevel;
|
pub struct MenuTopLevel;
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct FooterElement;
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct MenuAchievements;
|
pub struct MenuAchievements;
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct DeathScreenElement;
|
pub struct DeathScreenElement;
|
||||||
|
@ -65,7 +63,6 @@ pub enum DeathScreenEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const MENUDEF: &[(&str, MenuAction)] = &[
|
pub const MENUDEF: &[(&str, MenuAction)] = &[
|
||||||
("Phone Call", MenuAction::PhoneCall),
|
|
||||||
("", MenuAction::ToggleAR),
|
("", MenuAction::ToggleAR),
|
||||||
("", MenuAction::ChangeARAvatar),
|
("", MenuAction::ChangeARAvatar),
|
||||||
("", MenuAction::ChangePointer),
|
("", MenuAction::ChangePointer),
|
||||||
|
@ -95,7 +92,6 @@ pub enum MenuAction {
|
||||||
ModReactor,
|
ModReactor,
|
||||||
ToggleSound,
|
ToggleSound,
|
||||||
ToggleMusic,
|
ToggleMusic,
|
||||||
PhoneCall,
|
|
||||||
ToggleCamera,
|
ToggleCamera,
|
||||||
ToggleFullscreen,
|
ToggleFullscreen,
|
||||||
ToggleShadows,
|
ToggleShadows,
|
||||||
|
@ -351,20 +347,17 @@ pub fn setup(
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.with_children(|builder| {
|
.with_children(|builder| {
|
||||||
builder.spawn((
|
builder.spawn((TextBundle {
|
||||||
FooterElement,
|
text: Text {
|
||||||
TextBundle {
|
sections: vec![TextSection::new(
|
||||||
text: Text {
|
format!("{} {}", GAME_NAME, settings.version.as_str()),
|
||||||
sections: vec![TextSection::new(
|
style_version,
|
||||||
format!("{} {}", GAME_NAME, settings.version.as_str()),
|
)],
|
||||||
style_version,
|
justify: JustifyText::Right,
|
||||||
)],
|
|
||||||
justify: JustifyText::Right,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
));
|
..default()
|
||||||
|
},));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,17 +433,8 @@ pub struct MenuState {
|
||||||
|
|
||||||
pub fn update_menu(
|
pub fn update_menu(
|
||||||
mut q_text: Query<&mut Text, With<MenuTopLevel>>,
|
mut q_text: Query<&mut Text, With<MenuTopLevel>>,
|
||||||
mut q_footer: Query<&mut Text, (With<FooterElement>, Without<MenuTopLevel>)>,
|
mut q_achievement_text: Query<&mut Text, (With<MenuAchievements>, Without<MenuTopLevel>)>,
|
||||||
mut q_achievement_text: Query<
|
|
||||||
&mut Text,
|
|
||||||
(
|
|
||||||
With<MenuAchievements>,
|
|
||||||
Without<MenuTopLevel>,
|
|
||||||
Without<FooterElement>,
|
|
||||||
),
|
|
||||||
>,
|
|
||||||
mut q_vis: Query<&mut Visibility, With<menu::MenuElement>>,
|
mut q_vis: Query<&mut Visibility, With<menu::MenuElement>>,
|
||||||
id2pos: Res<game::Id2Pos>,
|
|
||||||
achievement_tracker: Res<var::AchievementTracker>,
|
achievement_tracker: Res<var::AchievementTracker>,
|
||||||
menustate: Res<MenuState>,
|
menustate: Res<MenuState>,
|
||||||
settings: Res<Settings>,
|
settings: Res<Settings>,
|
||||||
|
@ -465,21 +449,6 @@ pub fn update_menu(
|
||||||
|
|
||||||
let bools = achievement_tracker.to_bool_vec();
|
let bools = achievement_tracker.to_bool_vec();
|
||||||
let rendered = achievement_tracker.to_textsections();
|
let rendered = achievement_tracker.to_textsections();
|
||||||
if let (Ok(mut text), Some(player_pos), Some(jupiter_pos)) = (
|
|
||||||
q_footer.get_single_mut(),
|
|
||||||
id2pos.0.get(cmd::ID_PLAYER),
|
|
||||||
id2pos.0.get(cmd::ID_JUPITER),
|
|
||||||
) {
|
|
||||||
let (clock_max, clock_current) =
|
|
||||||
nature::pos_to_orbit_time(*player_pos, *jupiter_pos, nature::JUPITER_MASS);
|
|
||||||
text.sections[0].value = format!(
|
|
||||||
"Orbital Clock:\n{} of {}\n{} {}",
|
|
||||||
nature::format_seconds_to_hour_min(clock_current),
|
|
||||||
nature::format_seconds_to_hour_min(clock_max),
|
|
||||||
GAME_NAME,
|
|
||||||
settings.version.as_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Ok(mut text) = q_achievement_text.get_single_mut() {
|
if let Ok(mut text) = q_achievement_text.get_single_mut() {
|
||||||
for i in 0..text.sections.len() - 1 {
|
for i in 0..text.sections.len() - 1 {
|
||||||
text.sections[i + 1].style.color = if bools[i] {
|
text.sections[i + 1].style.color = if bools[i] {
|
||||||
|
@ -744,11 +713,6 @@ pub fn handle_input(
|
||||||
ew_game.send(GameEvent::SetShadows(Toggle));
|
ew_game.send(GameEvent::SetShadows(Toggle));
|
||||||
ew_updatemenu.send(UpdateMenuEvent);
|
ew_updatemenu.send(UpdateMenuEvent);
|
||||||
}
|
}
|
||||||
MenuAction::PhoneCall => {
|
|
||||||
ew_game.send(GameEvent::PhoneCall);
|
|
||||||
ew_game.send(GameEvent::SetMenu(Turn::Off));
|
|
||||||
ew_updatemenu.send(UpdateMenuEvent);
|
|
||||||
}
|
|
||||||
MenuAction::Restart => {
|
MenuAction::Restart => {
|
||||||
settings.god_mode = false;
|
settings.god_mode = false;
|
||||||
ew_playerdies.send(game::PlayerDiesEvent(actor::DamageType::Depressurization));
|
ew_playerdies.send(game::PlayerDiesEvent(actor::DamageType::Depressurization));
|
||||||
|
|
|
@ -242,26 +242,3 @@ pub fn rotation_for_orbiting_body(orbit_distance: f64, mass: f64) -> f64 {
|
||||||
0.0
|
0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assumes a circular 2D orbit in the invariable plane of the solar system
|
|
||||||
/// Returns (seconds for a single orbit, current seconds of orbit)
|
|
||||||
pub fn pos_to_orbit_time(pos: DVec3, orbited_pos: DVec3, orbited_mass: f64) -> (f64, f64) {
|
|
||||||
let rel_x = pos.x - orbited_pos.x;
|
|
||||||
let rel_z = pos.z - orbited_pos.z;
|
|
||||||
let orbit_distance = (rel_x * rel_x + rel_z * rel_z).sqrt();
|
|
||||||
|
|
||||||
// get total orbit seconds
|
|
||||||
let period = simple_orbital_period(orbited_mass, orbit_distance);
|
|
||||||
|
|
||||||
// get current orbital phase
|
|
||||||
let angle_radians = (rel_z).atan2(-rel_x);
|
|
||||||
let mut fraction = angle_radians / (PI * 2.0);
|
|
||||||
if fraction < 0.0 {
|
|
||||||
fraction += 1.0;
|
|
||||||
}
|
|
||||||
return (period, period * fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn format_seconds_to_hour_min(seconds: f64) -> String {
|
|
||||||
return format!("{:02.0}:{:02.0}", seconds / 3600.0, (seconds % 3600.0) / 60.0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -477,7 +477,6 @@ pub struct Preferences {
|
||||||
#[serde(default = "Preferences::default_flashlight_power")]
|
#[serde(default = "Preferences::default_flashlight_power")]
|
||||||
pub flashlight_power: usize, // 0-2
|
pub flashlight_power: usize, // 0-2
|
||||||
pub thruster_boost: usize, // 0-2
|
pub thruster_boost: usize, // 0-2
|
||||||
pub contacts: Vec<String>,
|
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub source_file: Option<String>,
|
pub source_file: Option<String>,
|
||||||
|
|
Loading…
Reference in a new issue