rewrite handle_wants_acceleration() using MatchVelocityTarget
This commit is contained in:
parent
4c7d631b93
commit
0ce3d03e1f
1 changed files with 19 additions and 76 deletions
95
src/actor.rs
95
src/actor.rs
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue