Compare commits
No commits in common. "26729c6f612fd162ab26bf272bc4f71552be0dec" and "008e2d55bcf7017f0b19e369874dec0236384ed9" have entirely different histories.
26729c6f61
...
008e2d55bc
|
@ -475,8 +475,6 @@ 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()
|
||||
|
@ -489,12 +487,10 @@ pub fn handle_input(
|
|||
ew_conv.send(chat::StartConversationEvent {
|
||||
talker: talker.clone(),
|
||||
});
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Entering Vehicles
|
||||
if !done && q_player_drives.is_empty() {
|
||||
if q_player_drives.is_empty() {
|
||||
// Sort vehicles by their distance to the player
|
||||
let objects: Vec<((Entity, &Actor, Option<&MessageOnVehicleEntry>), &Transform)> =
|
||||
q_vehicles
|
||||
|
|
319
src/camera.rs
319
src/camera.rs
|
@ -22,6 +22,7 @@ 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;
|
||||
|
@ -540,6 +541,324 @@ 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>>,
|
||||
|
|
Loading…
Reference in a new issue