From c69baa80e911288b5f0b67d0593c1ecf966282b1 Mon Sep 17 00:00:00 2001 From: yuni <hut@hut.pm> Date: Mon, 2 Dec 2024 00:54:02 +0100 Subject: [PATCH] Icarus can now go sky diving with you \o/ --- src/actor.rs | 5 +++-- src/chat.rs | 25 ++++++++++++++++++++++++- src/chats/serenity.yaml | 20 ++++++++++++++++++++ src/cmd.rs | 7 ++++++- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/actor.rs b/src/actor.rs index a6c1692..4e77c85 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -235,6 +235,8 @@ pub struct HasAtmosphere { pub r_inner: f64, pub r_outer: f64, } +#[derive(Component)] +pub struct NPCIcarus; #[derive(Component)] pub struct LifeForm { @@ -822,8 +824,7 @@ fn handle_wants_acceleration( if accel.brake { let stop_direction = (matching.v - v.0).as_vec3(); if stop_direction.length_squared() > 0.003 { - delta_v = - (trans.rotation.inverse() * stop_direction.normalize()).as_dvec3(); + delta_v = (trans.rotation.inverse() * stop_direction.normalize()).as_dvec3(); engine.currently_matching_velocity = true; thruster_on = true; // is this redundant? } diff --git a/src/chat.rs b/src/chat.rs index f805776..ef4f41a 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -907,6 +907,10 @@ pub fn handle_chat_scripts( (&mut Position, &mut Rotation, &mut LinearVelocity), With<actor::PlayerCamera>, >, + mut q_icarus: Query< + (Entity, &mut Position, &mut Rotation, &mut LinearVelocity), + (With<actor::NPCIcarus>, Without<actor::PlayerCamera>), + >, mut q_chats: Query<&mut Chat>, mut ew_sfx: EventWriter<audio::PlaySfxEvent>, mut ew_effect: EventWriter<visual::SpawnEffectEvent>, @@ -1030,6 +1034,7 @@ pub fn handle_chat_scripts( let dest = vars.get("$$dive_destination"); let speed_kmh = vars.getf("$$dive_speed"); let angle = vars.getf("$$dive_angle"); + let icarus_joins = vars.getb("$$dive_with_icarus"); if let (Some(dest), Some(speed_kmh), Some(angle)) = (dest, speed_kmh, angle) { let distance = if angle < 10.0 { @@ -1069,11 +1074,29 @@ pub fn handle_chat_scripts( let towards_jupiter = look_at_quat(target_pos, *jupiter_pos, Dir3::X.as_dvec3()); if let Ok((mut pos, mut rot, mut v)) = q_playercam.get_single_mut() { + let offset = (DQuat::from_rotation_x(20.0f64.to_radians()) + * towards_jupiter) + * DVec3::new(0.0, 0.0, -15.0); v.0 = v_target; - pos.0 = target_pos; + pos.0 = target_pos + offset; rot.0 = towards_jupiter; } + if icarus_joins { + if let Ok((entity, mut pos, mut rot, mut v)) = q_icarus.get_single_mut() { + commands + .entity(entity) + .remove::<actor::WantsMatchVelocityWith>(); + commands.entity(entity).remove::<actor::WantsMaxVelocity>(); + v.0 = v_target; + pos.0 = target_pos; + rot.0 = towards_jupiter; + vars.set_in_scope("$", "dive_in_progress_icarus", "1".to_string()); + } else { + error!("Could not dive with Icarus, failed to find entity with component NPCIcarus"); + } + } + suit.oxygen = suit.oxygen_max; gforce.ignore_gforce_seconds = 1.0; ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::WakeUp)); diff --git a/src/chats/serenity.yaml b/src/chats/serenity.yaml index 45b62d6..6fa30c5 100644 --- a/src/chats/serenity.yaml +++ b/src/chats/serenity.yaml @@ -10,6 +10,8 @@ # Icarus {{{1 - chat: Icarus +- if $$dive_in_progress_icarus: + - WOOOOOOOOOOOOOHOOOOOOOOOOO!!!!!! - if $met: - Oh hey, you're back! - goto: node_main @@ -87,6 +89,24 @@ - I think I need a lowdown on reality...: - Sure, what do you wanna know? - goto: node_lowdown +- Let's do something crazy together!: + - How about some sky diving into the atmosphere of Jupiter? + - I wanted to try it for a while, but it is kind of scary alone. + - Awesome idea, let's do it!: + - Yes!! + - set: $$dive_with_icarus + - Let's ask FASTravel to pick us up and launch us into Jupiter. Would take too long to fly ourselves. + - label: node_fastravel + - What's FASTravel?: + - The main cargo corporation around here, surely you've seen them around? + - Or just give them a phone call. [press ESC] + - goto: node_fastravel + - Ok, let's go!: + - ALRIGHT, LETS DO SOME SKY DIVING! Call up FASTravel, I will join you. + - goto: EXIT + - That sounds like a good way to get killed.: + - Yeah... it does, doesn't it? + - Maybe I'll stick to exploring Jupiter's atmosphere in VR. - Can I ask you some general questions?: - Yeah, anything. - goto: generic_questions diff --git a/src/cmd.rs b/src/cmd.rs index ca433fa..a9e5cb7 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -19,6 +19,7 @@ use regex::Regex; pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA"; pub const ID_PLAYER: &str = "player"; +pub const ID_ICARUS: &str = "Icarus"; pub const ID_EARTH: &str = "earth"; pub const ID_SOL: &str = "sol"; pub const ID_JUPITER: &str = "jupiter"; @@ -1171,7 +1172,7 @@ fn spawn_scenes( state.angular_momentum = DVec3::ZERO; if template == "tutorialnpc" { - state.id = "Icarus".to_string(); + state.id = ID_ICARUS.to_string(); state.name = Some(state.id.clone()); state.chat = state.id.clone(); @@ -1332,6 +1333,7 @@ fn spawn_entities( let mut rotation = state.rotation; let is_jupiter = state.id == ID_JUPITER; + let is_icarus = state.id == ID_ICARUS; // Preprocessing let mut absolute_pos = if let Some(id) = &state.relative_to { @@ -1408,6 +1410,9 @@ fn spawn_entities( actor.insert(world::DespawnOnPlayerDeath); actor.insert(actor::HitPoints::default()); actor.insert(Position::from(absolute_pos)); + if is_icarus { + actor.insert(actor::NPCIcarus); + } if state.is_sphere { let sphere_texture_handle = if let Some(model) = &state.model { Some(asset_server.load(format!("models/textures/{}.jpg", model)))