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