Compare commits

..

2 commits

2 changed files with 5 additions and 320 deletions

View file

@ -475,6 +475,8 @@ pub fn handle_input(
let player_entity = player.get_single().unwrap();
if keyboard_input.just_pressed(settings.key_interact) {
let mut done = false;
// Talking to people
let objects: Vec<(chat::Talker, &Transform)> = q_talker
.iter()
@ -487,10 +489,12 @@ pub fn handle_input(
ew_conv.send(chat::StartConversationEvent {
talker: talker.clone(),
});
done = true;
}
}
// Entering Vehicles
if q_player_drives.is_empty() {
if !done && q_player_drives.is_empty() {
// Sort vehicles by their distance to the player
let objects: Vec<((Entity, &Actor, Option<&MessageOnVehicleEntry>), &Transform)> =
q_vehicles

View file

@ -22,7 +22,6 @@ use bevy::transform::TransformSystem;
use bevy::window::PrimaryWindow;
use bevy_xpbd_3d::plugins::sync;
use bevy_xpbd_3d::prelude::*;
use std::collections::HashMap;
pub const INITIAL_ZOOM_LEVEL: f64 = 10.0;
pub const MAX_DIST_FOR_MATCH_VELOCITY: f64 = 10000.0;
@ -541,324 +540,6 @@ pub fn apply_input_to_player(
accel.brake = key_input.pressed(settings.key_stop);
}
#[allow(clippy::too_many_arguments)]
pub fn apply_input_to_player_old(
time: Res<Time>,
mut commands: Commands,
settings: Res<var::Settings>,
jupiter_pos: Res<game::JupiterPos>,
windows: Query<&Window, With<PrimaryWindow>>,
mut mouse_events: EventReader<MouseMotion>,
key_input: Res<ButtonInput<KeyCode>>,
q_audiosinks: Query<(&audio::Sfx, &AudioSink)>,
q_target: Query<&LinearVelocity, (With<hud::IsTargeted>, Without<actor::PlayerCamera>)>,
q_closest: Query<
(&Position, &LinearVelocity),
(
Without<hud::IsTargeted>,
Without<visual::IsEffect>,
Without<actor::PlayerCamera>,
Without<actor::Player>,
Without<actor::PlayerDrivesThis>,
),
>,
mut q_playercam: Query<
(
Entity,
&Transform,
&mut actor::Engine,
&Position,
&mut LinearVelocity,
&mut ExternalTorque,
Option<&actor::PlayerDrivesThis>,
),
(With<actor::PlayerCamera>, Without<Camera>),
>,
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
) {
if settings.map_active || !settings.in_control() {
return;
}
let dt = time.delta_seconds();
let mut play_thruster_sound = false;
let mut axis_input: DVec3 = DVec3::ZERO;
let (win_res_x, win_res_y): (f32, f32);
let mut focused = true;
if let Ok(window) = &windows.get_single() {
focused = window.focused;
win_res_x = window.resolution.width();
win_res_y = window.resolution.height();
} else {
win_res_x = 1920.0;
win_res_y = 1050.0;
}
if let Ok((player_entity, player_transform, mut engine, pos, mut v, mut torque, bike)) =
q_playercam.get_single_mut()
{
let target_v: DVec3 = if let Ok(target) = q_target.get_single() {
target.0
} else {
let mut closest_distance = MAX_DIST_FOR_MATCH_VELOCITY;
let mut closest_velocity = None;
for (testpos, v) in q_closest.iter() {
let distance = (pos.0 - testpos.0).length();
if distance < closest_distance {
closest_velocity = Some(v);
closest_distance = distance;
}
}
if closest_velocity.is_some() {
closest_velocity.unwrap().0
} else {
let relative_pos = pos.0 - jupiter_pos.0;
nature::orbital_velocity(relative_pos, nature::JUPITER_MASS)
}
};
// Handle key input
if focused {
if key_input.pressed(settings.key_forward) || settings.cruise_control_active {
axis_input.z += 1.2;
}
if key_input.pressed(settings.key_back) {
axis_input.z -= 1.2;
}
if key_input.pressed(settings.key_right) {
axis_input.x -= 1.2;
}
if key_input.pressed(settings.key_left) {
axis_input.x += 1.2;
}
if key_input.pressed(settings.key_up) {
axis_input.y += 1.2;
}
if key_input.pressed(settings.key_down) {
axis_input.y -= 1.2;
}
if key_input.pressed(settings.key_stop) {
let stop_direction = (target_v - v.0).normalize();
if stop_direction.length_squared() > 0.3 {
axis_input += 1.0
* DVec3::from(
player_transform.rotation.inverse() * stop_direction.as_vec3(),
);
}
}
} else {
if settings.cruise_control_active {
axis_input.z += 1.2;
}
}
// In typical games we would normalize the input vector so that diagonal movement is as
// fast as forward or sideways movement. But here, we merely clamp each direction to an
// absolute maximum of 1, since every thruster can be used separately. If the forward
// thrusters and the leftward thrusters are active at the same time, then of course the
// total diagonal acceleration is faster than the forward acceleration alone.
axis_input = axis_input.clamp(DVec3::splat(-1.0), DVec3::splat(1.0));
// Apply movement update
let forward_factor = engine.current_warmup
* (if axis_input.z > 0.0 {
engine.thrust_forward
} else {
engine.thrust_back
});
let right_factor = engine.thrust_sideways * engine.current_warmup;
let up_factor = engine.thrust_sideways * engine.current_warmup;
let factor = DVec3::new(right_factor as f64, up_factor as f64, forward_factor as f64);
let boost = if bike.is_none() {
engine.current_boost_factor
} else {
1.0
};
if axis_input.length_squared() > 0.003 {
engine.currently_firing = true;
let acceleration_global: DVec3 =
DVec3::from(player_transform.rotation * (axis_input * factor).as_vec3());
let mut acceleration_total: DVec3 =
(actor::ENGINE_SPEED_FACTOR * dt) as f64 * boost * acceleration_global;
let threshold = 1e-5;
if key_input.pressed(settings.key_stop) {
// Decelerate (or match velocity to target_v)
engine.currently_matching_velocity = true;
let dv = v.0 - target_v;
for i in 0..3 {
if dv[i].abs() < threshold {
v[i] = target_v[i];
} else if dv[i].signum() != (dv[i] + acceleration_total[i]).signum() {
// Almost stopped, but we overshot v=0
v[i] = target_v[i];
acceleration_total[i] = 0.0;
}
}
} else {
engine.currently_matching_velocity = false;
}
// TODO: handle mass
v.0 += acceleration_total;
engine.current_warmup =
(engine.current_warmup + dt / engine.warmup_seconds).clamp(0.0, 1.0);
play_thruster_sound = true;
// Visual effect
if bike.is_none() && acceleration_total.length_squared() > 1e-4 {
let thruster_direction = acceleration_total.normalize();
let thruster_pos = pos.0 - 0.3 * thruster_direction;
let thruster_v = v.0 - boost * 5.0 * thruster_direction;
ew_effect.send(visual::SpawnEffectEvent {
duration: 2.0,
class: visual::Effects::ThrusterParticle(
Position::from(thruster_pos),
LinearVelocity::from(thruster_v),
),
});
}
} else {
engine.currently_firing = false;
engine.currently_matching_velocity = false;
engine.current_warmup =
(engine.current_warmup - dt / engine.warmup_seconds).clamp(0.0, 1.0);
}
// Handle mouse input and mouse-like key bindings
let mut play_reactionwheel_sound = false;
let mut mouse_delta = Vec2::ZERO;
let mut pitch_yaw_rot = Vec3::ZERO;
let sensitivity_factor = if settings.is_zooming {
settings.zoom_sensitivity_factor
} else {
1.0
};
let mouseless_sensitivity = 8.0 * sensitivity_factor;
let mouseless_rotation_sensitivity = 40.0 * sensitivity_factor;
if key_input.pressed(settings.key_mouseup) {
pitch_yaw_rot[0] -= mouseless_sensitivity;
}
if key_input.pressed(settings.key_mousedown) {
pitch_yaw_rot[0] += mouseless_sensitivity;
}
if key_input.pressed(settings.key_mouseleft) {
pitch_yaw_rot[1] += mouseless_sensitivity;
}
if key_input.pressed(settings.key_mouseright) {
pitch_yaw_rot[1] -= mouseless_sensitivity;
}
if key_input.pressed(settings.key_rotateleft) {
pitch_yaw_rot[2] -= mouseless_rotation_sensitivity;
}
if key_input.pressed(settings.key_rotateright) {
pitch_yaw_rot[2] += mouseless_rotation_sensitivity;
}
for mouse_event in mouse_events.read() {
mouse_delta += mouse_event.delta;
}
if mouse_delta != Vec2::ZERO {
if key_input.pressed(settings.key_rotate) {
pitch_yaw_rot[2] += 1000.0 * mouse_delta.x / win_res_x;
} else {
pitch_yaw_rot[0] += 1000.0 * mouse_delta.y / win_res_y;
pitch_yaw_rot[1] -= 1000.0 * mouse_delta.x / win_res_x;
}
}
let mouse_speed = pitch_yaw_rot.length();
let mouse_moving = mouse_speed > EPSILON32;
if mouse_moving {
play_reactionwheel_sound = true;
pitch_yaw_rot *=
settings.mouse_sensitivity * sensitivity_factor * engine.reaction_wheels;
torque.apply_torque(DVec3::from(
player_transform.rotation
* Vec3::new(pitch_yaw_rot[0], pitch_yaw_rot[1], pitch_yaw_rot[2]),
));
}
if settings.rotation_stabilizer_active || key_input.pressed(settings.key_stop) {
commands
.entity(player_entity)
.try_insert(actor::WantsMaxRotation(mouse_speed as f64 * 0.1));
} else {
commands
.entity(player_entity)
.remove::<actor::WantsMaxRotation>();
}
let mut sinks: HashMap<audio::Sfx, &AudioSink> = HashMap::new();
for (sfx, sink) in &q_audiosinks {
sinks.insert(*sfx, sink);
}
// Play sound effects
if let Some(sink) = sinks.get(&audio::Sfx::ElectricMotor) {
let reactionwheel_volume = 1.5;
let volume = sink.volume();
let speed = sink.speed();
let action = pitch_yaw_rot.length_squared().powf(0.2) * 0.0005;
if play_reactionwheel_sound && !settings.mute_sfx && bike.is_some() {
sink.set_volume(
settings.volume_sfx * reactionwheel_volume * (volume + action).clamp(0.0, 1.0),
);
sink.set_speed((speed + action * 0.2).clamp(0.2, 0.5));
sink.play()
} else {
if volume <= 0.01 {
sink.pause()
} else {
sink.set_volume((volume - 0.01).clamp(0.0, 1.0));
sink.set_speed((speed - 0.03).clamp(0.2, 0.5));
}
}
}
let sinks = vec![
(
1.0,
boost as f32,
actor::EngineType::Monopropellant,
sinks.get(&audio::Sfx::Thruster),
),
(
1.0,
1.0,
actor::EngineType::Ion,
sinks.get(&audio::Sfx::Ion),
),
];
let seconds_to_max_vol = 0.05;
let seconds_to_min_vol = 0.05;
for sink_data in sinks {
if let (vol_boost, speed, engine_type, Some(sink)) = sink_data {
if settings.mute_sfx {
sink.pause();
} else {
let volume = sink.volume();
let maxvol = settings.volume_sfx * vol_boost;
if engine.engine_type == engine_type {
if play_thruster_sound {
sink.set_speed(speed);
sink.play();
if volume < maxvol {
sink.set_volume(
(volume + dt / seconds_to_max_vol).clamp(0.0, maxvol),
);
}
} else {
sink.set_volume((volume - dt / seconds_to_min_vol).clamp(0.0, maxvol));
}
} else if volume > 0.0 {
sink.set_volume((volume - dt / seconds_to_min_vol).clamp(0.0, maxvol));
}
if volume < 0.0001 {
sink.pause();
}
}
}
}
}
}
pub fn update_map_only_object_visibility(
settings: Res<var::Settings>,
q_camera: Query<&Transform, With<Camera>>,