rewrite handle_wants_acceleration() using MatchVelocityTarget

This commit is contained in:
yuni 2024-11-30 03:23:25 +01:00
parent 4c7d631b93
commit 0ce3d03e1f

View file

@ -791,17 +791,15 @@ fn handle_wants_rotation_change(mut q_actor: Query<(&mut Rotation, &mut WantsRot
fn handle_wants_acceleration(
time: Res<Time>,
settings: Res<var::Settings>,
jupiter_pos: Res<game::JupiterPos>,
q_audiosinks: Query<(&audio::Sfx, &AudioSink)>,
mut q_actor: Query<
(
Entity,
&Transform,
&Position,
&mut LinearVelocity,
&MatchingVelocityTarget,
Option<&mut Engine>,
Option<&WantsAcceleration>,
Option<&hud::IsTargeted>,
Option<&PlayerCamera>,
),
(Without<visual::IsEffect>, Without<HiddenInsideVehicle>),
@ -809,78 +807,25 @@ fn handle_wants_acceleration(
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
) {
let dt = time.delta_seconds();
// Vector elements: (Entity, is_player, pos)
let mut request_closest: Vec<(Entity, bool, DVec3)> = vec![];
let mut closest_map: HashMap<Entity, DVec3> = HashMap::new();
// First, determine whether any actor wants to brake (=match velocity)
for (entity, _, pos, _, _, accel, _, is_player) in &mut q_actor {
if accel.is_some() && accel.unwrap().brake {
request_closest.push((entity, is_player.is_some(), pos.0.clone()));
}
}
// If an actor is braking, find out relative to what it wants to brake
for (entity, is_player, pos) in &request_closest {
let mut target_v: Option<DVec3> = None;
// First, if this is the player, check whether they targeted anything
// so we can match velocity to the target.
if *is_player {
for (_, _, _, v, _, _, is_target, _) in &q_actor {
if is_target.is_some() {
target_v = Some(v.0);
break;
}
}
}
// If not, simply look for the closest object and match velocity to that.
if target_v.is_none() {
let mut closest_distance = camera::MAX_DIST_FOR_MATCH_VELOCITY;
for (testentity, _, testpos, v, _, _, _, _) in &q_actor {
if *entity != testentity {
let distance = (*pos - testpos.0).length();
if distance < closest_distance {
target_v = Some(v.0);
closest_distance = distance;
}
}
}
}
// Last resort: Match velocity to the orbital velocity around Jupiter
if target_v.is_none() {
let relative_pos = *pos - jupiter_pos.0;
target_v = Some(nature::orbital_velocity(relative_pos, nature::JUPITER_MASS));
}
if let Some(target_v) = target_v {
closest_map.insert(*entity, target_v);
}
}
// Finally, apply the requested acceleration to the actor's velocity
let mut play_thruster_sound = false;
let mut players_engine: Option<Engine> = None;
for (entity, trans, pos, mut v, engine, accel, _, is_player) in &mut q_actor {
let mut thruster_on = false;
for (trans, pos, mut v, matching, engine, accel, is_player) in &mut q_actor {
// Apply the requested acceleration to the actor's velocity
if let (Some(mut engine), Some(accel)) = (engine, accel) {
let mut thruster_on = false;
let mut delta_v = DVec3::ZERO;
let mut allow_fullstop = false;
let boost = engine.current_boost_factor;
engine.currently_matching_velocity = false;
if accel.brake {
if let Some(target_v) = closest_map.get(&entity) {
let stop_direction = (*target_v - v.0).as_vec3();
if stop_direction.length_squared() > 0.003 {
delta_v =
(trans.rotation.inverse() * stop_direction.normalize()).as_dvec3();
engine.currently_matching_velocity = true;
thruster_on = true; // is this redundant?
}
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();
engine.currently_matching_velocity = true;
thruster_on = true; // is this redundant?
}
}
@ -922,16 +867,14 @@ fn handle_wants_acceleration(
// Apply acceleration to velocity
if allow_fullstop {
if let Some(target_v) = closest_map.get(&entity) {
// Prevent overshooting when matching velocity, which
// would result in oscillating acceleration back and forth
for axis in 0..3 {
let original = v[axis];
let target = target_v[axis];
v[axis] += final_accel[axis];
if (original - target).signum() != (v[axis] - target).signum() {
v[axis] = target;
}
// Prevent overshooting when matching velocity, which
// would result in oscillating acceleration back and forth
for axis in 0..3 {
let original = v[axis];
let target = matching.v[axis];
v[axis] += final_accel[axis];
if (original - target).signum() != (v[axis] - target).signum() {
v[axis] = target;
}
}
} else {