implement entering vehicles, variable engine parameters
This commit is contained in:
parent
ec7fcc0ef4
commit
61324ffe7a
52
src/actor.rs
52
src/actor.rs
|
@ -2,6 +2,7 @@ use bevy::prelude::*;
|
|||
use crate::{nature, settings, actor, audio, hud};
|
||||
|
||||
const MIN_INTERACT_DISTANCE: f32 = 30.0;
|
||||
const NO_RIDE: u32 = 0;
|
||||
|
||||
pub struct ActorPlugin;
|
||||
impl Plugin for ActorPlugin {
|
||||
|
@ -40,6 +41,7 @@ pub struct Actor {
|
|||
pub m: f32, // mass
|
||||
pub v: Vec3, // velocity
|
||||
pub angular_momentum: Quat,
|
||||
pub inside_entity: u32,
|
||||
}
|
||||
|
||||
impl Default for Actor {
|
||||
|
@ -48,12 +50,14 @@ impl Default for Actor {
|
|||
hp: 100.0,
|
||||
m: 100.0,
|
||||
v: Vec3::ZERO,
|
||||
inside_entity: NO_RIDE,
|
||||
angular_momentum: Quat::from_euler(EulerRot::XYZ, 0.001, 0.01, 0.003),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)] pub struct Player;
|
||||
#[derive(Component)] pub struct PlayerDrivesThis;
|
||||
#[derive(Component)] pub struct PlayerInConversation;
|
||||
#[derive(Component)] pub struct InConversationWithPlayer;
|
||||
|
||||
|
@ -104,6 +108,27 @@ impl Default for LifeForm { fn default() -> Self { Self {
|
|||
adrenaline_jolt: 0.0,
|
||||
}}}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Vehicle;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Engine {
|
||||
pub thrust_forward: f32,
|
||||
pub thrust_back: f32,
|
||||
pub thrust_sideways: f32,
|
||||
pub reaction_wheels: f32,
|
||||
}
|
||||
impl Default for Engine {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
thrust_forward: 1.0,
|
||||
thrust_back: 1.0,
|
||||
thrust_sideways: 1.0,
|
||||
reaction_wheels: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Suit {
|
||||
pub oxygen: f32,
|
||||
|
@ -173,17 +198,20 @@ pub fn update_physics_lifeforms(
|
|||
}
|
||||
|
||||
pub fn handle_input(
|
||||
mut commands: Commands,
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
settings: ResMut<settings::Settings>,
|
||||
query: Query<(&Talker, &Transform)>,
|
||||
player: Query<&Transform, With<actor::Player>>,
|
||||
q_talker: Query<(&Talker, &Transform), Without<actor::Player>>,
|
||||
mut player: Query<(&mut Actor, &mut Transform), With<actor::Player>>,
|
||||
mut q_vehicles: Query<(Entity, &mut Visibility, &Transform), (With<actor::Vehicle>, Without<actor::Player>)>,
|
||||
mut ew_conv: EventWriter<StartConversationEvent>,
|
||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
)
|
||||
{
|
||||
let mindist = MIN_INTERACT_DISTANCE * MIN_INTERACT_DISTANCE;
|
||||
if keyboard_input.just_pressed(settings.key_interact) {
|
||||
let mindist = MIN_INTERACT_DISTANCE * MIN_INTERACT_DISTANCE;
|
||||
if let Ok(player) = player.get_single() {
|
||||
for (talker, transform) in &query {
|
||||
if let Ok((_player_actor, player)) = player.get_single() {
|
||||
for (talker, transform) in &q_talker {
|
||||
if transform.translation.distance_squared(player.translation) <= mindist {
|
||||
ew_conv.send(StartConversationEvent{talker: talker.clone()});
|
||||
break;
|
||||
|
@ -191,6 +219,20 @@ pub fn handle_input(
|
|||
}
|
||||
}
|
||||
}
|
||||
else if keyboard_input.just_pressed(settings.key_vehicle) {
|
||||
if let Ok((mut player_actor, mut player)) = player.get_single_mut() {
|
||||
for (entity, mut visibility, vehicle_transform) in q_vehicles.iter_mut() {
|
||||
if vehicle_transform.translation.distance_squared(player.translation) <= mindist {
|
||||
player_actor.inside_entity = entity.index();
|
||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::EnterVehicle));
|
||||
*player = *vehicle_transform;
|
||||
*visibility = Visibility::Hidden;
|
||||
commands.entity(entity).insert(PlayerDrivesThis);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_new_conversations(
|
||||
|
|
|
@ -30,6 +30,7 @@ pub enum Sfx {
|
|||
Switch,
|
||||
Ping,
|
||||
Connect,
|
||||
EnterVehicle,
|
||||
None,
|
||||
}
|
||||
|
||||
|
@ -142,6 +143,7 @@ pub fn play_sfx(
|
|||
Sfx::IncomingChatMessage => sound_incoming_message.0.clone(),
|
||||
Sfx::Ping => sound_ping.0.clone(),
|
||||
Sfx::Connect => sound_connect.0.clone(),
|
||||
Sfx::EnterVehicle => sound_switch.0.clone(),
|
||||
Sfx::None => sound_ping.0.clone(),
|
||||
},
|
||||
settings: PlaybackSettings::DESPAWN,
|
||||
|
@ -156,6 +158,7 @@ pub fn str2sfx(sfx_label: &str) -> Sfx {
|
|||
"chat" => Sfx::IncomingChatMessage,
|
||||
"ping" => Sfx::Ping,
|
||||
"connect" => Sfx::Connect,
|
||||
"entervehicle" => Sfx::EnterVehicle,
|
||||
_ => Sfx::None,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -52,7 +52,8 @@ fn run_camera_controller(
|
|||
mut mouse_events: EventReader<MouseMotion>,
|
||||
key_input: Res<ButtonInput<KeyCode>>,
|
||||
thruster_sound_controller: Query<&AudioSink, With<audio::ComponentThrusterSound>>,
|
||||
mut query: Query<(&mut Transform, &mut CameraController, &mut actor::Actor), With<Camera>>,
|
||||
q_engine: Query<&actor::Engine, With<actor::PlayerDrivesThis>>,
|
||||
mut query: Query<(&mut Transform, &mut CameraController, &mut actor::Actor, &actor::Engine), With<Camera>>,
|
||||
) {
|
||||
let dt = time.delta_seconds();
|
||||
let mut play_thruster_sound = false;
|
||||
|
@ -63,7 +64,7 @@ fn run_camera_controller(
|
|||
focused = window_result.unwrap().focused;
|
||||
}
|
||||
|
||||
if let Ok((mut transform, mut controller, mut actor)) = query.get_single_mut() {
|
||||
if let Ok((mut transform, mut controller, mut actor, player_engine)) = query.get_single_mut() {
|
||||
if !controller.initialized {
|
||||
controller.initialized = true;
|
||||
transform.rotation =
|
||||
|
@ -120,8 +121,14 @@ fn run_camera_controller(
|
|||
controller.velocity = Vec3::ZERO;
|
||||
}
|
||||
}
|
||||
let forward = *transform.forward();
|
||||
let right = *transform.right();
|
||||
|
||||
let engine = if let Ok(engine) = q_engine.get_single() { engine } else { player_engine };
|
||||
let forward = *transform.forward() * (if axis_input.z > 0.0 {
|
||||
engine.thrust_forward
|
||||
} else {
|
||||
engine.thrust_back
|
||||
});
|
||||
let right = *transform.right() * engine.thrust_sideways;
|
||||
actor.v += controller.velocity.x * dt * right
|
||||
+ controller.velocity.y * dt * Vec3::Y
|
||||
+ controller.velocity.z * dt * forward;
|
||||
|
|
|
@ -79,6 +79,8 @@ actor 3650 230 5000 asteroid1
|
|||
|
||||
actor 10 -30 20 bike
|
||||
scale 5
|
||||
vehicle yes
|
||||
thrust 50 0 10 0.5
|
||||
|
||||
actor 10 0 70 suit
|
||||
name Icarus
|
||||
|
|
|
@ -23,6 +23,7 @@ pub struct Settings {
|
|||
pub key_run: KeyCode,
|
||||
pub key_stop: KeyCode,
|
||||
pub key_interact: KeyCode,
|
||||
pub key_vehicle: KeyCode,
|
||||
pub key_reply1: KeyCode,
|
||||
pub key_reply2: KeyCode,
|
||||
pub key_reply3: KeyCode,
|
||||
|
@ -70,6 +71,7 @@ impl Default for Settings {
|
|||
key_run: KeyCode::KeyR,
|
||||
key_stop: KeyCode::Space,
|
||||
key_interact: KeyCode::KeyE,
|
||||
key_vehicle: KeyCode::KeyV,
|
||||
key_reply1: KeyCode::Digit1,
|
||||
key_reply2: KeyCode::Digit2,
|
||||
key_reply3: KeyCode::Digit3,
|
||||
|
|
51
src/world.rs
51
src/world.rs
|
@ -90,6 +90,10 @@ pub fn setup(
|
|||
integrity: 0.3,
|
||||
..default()
|
||||
},
|
||||
actor::Engine {
|
||||
thrust_forward: 1.2,
|
||||
..default()
|
||||
},
|
||||
Camera3dBundle {
|
||||
camera: Camera {
|
||||
hdr: true, // HDR is required for bloom
|
||||
|
@ -236,6 +240,11 @@ struct ParserState {
|
|||
is_lifeform: bool,
|
||||
is_alive: bool,
|
||||
is_suited: bool,
|
||||
is_vehicle: bool,
|
||||
thrust_forward: f32,
|
||||
thrust_sideways: f32,
|
||||
thrust_back: f32,
|
||||
reaction_wheels: f32,
|
||||
|
||||
// Chat fields
|
||||
delay: f64,
|
||||
|
@ -249,6 +258,7 @@ struct ParserState {
|
|||
impl Default for ParserState {
|
||||
fn default() -> Self {
|
||||
let default_actor = actor::Actor::default();
|
||||
let default_engine = actor::Engine::default();
|
||||
Self {
|
||||
class: DefClass::None,
|
||||
name: "NONAME".to_string(),
|
||||
|
@ -263,6 +273,11 @@ impl Default for ParserState {
|
|||
is_lifeform: false,
|
||||
is_alive: false,
|
||||
is_suited: false,
|
||||
is_vehicle: false,
|
||||
thrust_forward: default_engine.thrust_forward,
|
||||
thrust_sideways: default_engine.thrust_forward,
|
||||
thrust_back: default_engine.thrust_back,
|
||||
reaction_wheels: default_engine.reaction_wheels,
|
||||
|
||||
delay: 0.0,
|
||||
text: "".to_string(),
|
||||
|
@ -322,6 +337,13 @@ impl ParserState {
|
|||
conv_id: self.chat.clone(),
|
||||
..default()
|
||||
};
|
||||
let component_vehicle = actor::Vehicle;
|
||||
let component_engine = actor::Engine {
|
||||
thrust_forward: self.thrust_forward,
|
||||
thrust_back: self.thrust_back,
|
||||
thrust_sideways: self.thrust_sideways,
|
||||
reaction_wheels: self.reaction_wheels,
|
||||
};
|
||||
let component_suit = actor::Suit::default();
|
||||
let component_model = SceneBundle {
|
||||
transform: Transform {
|
||||
|
@ -364,10 +386,20 @@ impl ParserState {
|
|||
));
|
||||
}
|
||||
else {
|
||||
commands.spawn((
|
||||
component_actor,
|
||||
component_model,
|
||||
));
|
||||
if self.is_vehicle {
|
||||
commands.spawn((
|
||||
component_actor,
|
||||
component_model,
|
||||
component_vehicle,
|
||||
component_engine,
|
||||
));
|
||||
}
|
||||
else {
|
||||
commands.spawn((
|
||||
component_actor,
|
||||
component_model,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.reset();
|
||||
|
@ -448,6 +480,9 @@ pub fn load_defs(
|
|||
state.is_lifeform = true;
|
||||
state.is_suited = true;
|
||||
}
|
||||
["vehicle", "yes"] => {
|
||||
state.is_vehicle = true;
|
||||
}
|
||||
["pronoun", pronoun] => {
|
||||
state.pronoun = pronoun.to_string();
|
||||
}
|
||||
|
@ -482,6 +517,14 @@ pub fn load_defs(
|
|||
continue;
|
||||
}
|
||||
}
|
||||
["thrust", forward, back, sideways, reaction_wheels] => {
|
||||
if let (Ok(forward_float), Ok(back_float), Ok(sideways_float), Ok(reaction_wheels_float)) = (forward.parse::<f32>(), back.parse::<f32>(), sideways.parse::<f32>(), reaction_wheels.parse::<f32>()) {
|
||||
state.thrust_forward = forward_float;
|
||||
state.thrust_back = back_float;
|
||||
state.thrust_sideways = sideways_float;
|
||||
state.reaction_wheels = reaction_wheels_float;
|
||||
}
|
||||
}
|
||||
|
||||
// Parsing chats
|
||||
["chat", chat_name] => {
|
||||
|
|
Loading…
Reference in a new issue