implement update_matching_velocity_target()
This commit is contained in:
parent
cde59dcdd0
commit
67703072d7
4 changed files with 92 additions and 6 deletions
86
src/actor.rs
86
src/actor.rs
|
@ -79,6 +79,7 @@ impl Plugin for ActorPlugin {
|
|||
handle_input.run_if(in_control).run_if(game_running),
|
||||
handle_collisions.run_if(game_running),
|
||||
handle_damage.run_if(game_running),
|
||||
update_matching_velocity_target.run_if(game_running),
|
||||
),
|
||||
);
|
||||
app.add_systems(
|
||||
|
@ -86,6 +87,10 @@ impl Plugin for ActorPlugin {
|
|||
(handle_vehicle_enter_exit.run_if(game_running),),
|
||||
);
|
||||
app.add_event::<VehicleEnterExitEvent>();
|
||||
app.insert_resource(MatchingVelocityTargetUpdateTimer(Timer::from_seconds(
|
||||
0.25,
|
||||
TimerMode::Repeating,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,11 +178,13 @@ impl Default for ExperiencesGForce {
|
|||
}
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct MatchingVelocity {
|
||||
pub struct MatchingVelocityTarget {
|
||||
pub entity: Option<Entity>,
|
||||
pub pos: Option<DVec3>,
|
||||
pub v: DVec3,
|
||||
}
|
||||
#[derive(Resource)]
|
||||
pub struct MatchingVelocityTargetUpdateTimer(Timer);
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct WantsAcceleration {
|
||||
|
@ -1221,3 +1228,80 @@ fn handle_atmosphere(
|
|||
settings.atmo_drag = None;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_matching_velocity_target(
|
||||
time: Res<Time>,
|
||||
mut timer: ResMut<MatchingVelocityTargetUpdateTimer>,
|
||||
jupiter_pos: Res<game::JupiterPos>,
|
||||
mut q_actor: Query<
|
||||
(
|
||||
Entity,
|
||||
&Transform,
|
||||
&Position,
|
||||
&mut LinearVelocity,
|
||||
Option<&mut MatchingVelocityTarget>,
|
||||
Option<&WantsAcceleration>,
|
||||
Option<&hud::IsTargeted>,
|
||||
Option<&PlayerCamera>,
|
||||
),
|
||||
(Without<visual::IsEffect>, Without<HiddenInsideVehicle>),
|
||||
>,
|
||||
) {
|
||||
if timer.0.tick(time.delta()).just_finished() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut closest_map: HashMap<Entity, DVec3> = HashMap::new();
|
||||
|
||||
for (entity, _, pos, _, matching, _, _, is_player) in &q_actor {
|
||||
// We only care about entities that ever need to match their velocity
|
||||
if matching.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
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.is_some() {
|
||||
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.0 - 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.0 - 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);
|
||||
}
|
||||
}
|
||||
|
||||
for (entity, _, _, _, matching, _, _, _) in &mut q_actor {
|
||||
if let Some(mut matching) = matching {
|
||||
if let Some(target_v) = closest_map.get(&entity) {
|
||||
matching.v = *target_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1513,7 +1513,7 @@ fn spawn_entities(
|
|||
actor.insert(actor::ExperiencesAtmosphere);
|
||||
}
|
||||
if state.is_player || state.is_vehicle {
|
||||
actor.insert(MatchingVelocity::default());
|
||||
actor.insert(MatchingVelocityTarget::default());
|
||||
// previously used to apply mouse movement to actor rotation, but currently unused
|
||||
actor.insert(ExternalTorque::ZERO.with_persistence(false));
|
||||
}
|
||||
|
|
|
@ -1338,7 +1338,10 @@ fn update_target_selectagon(
|
|||
|
||||
fn update_motion_marker(
|
||||
settings: Res<Settings>,
|
||||
q_player: Query<(&Transform, &LinearVelocity, &MatchingVelocity), With<actor::PlayerCamera>>,
|
||||
q_player: Query<
|
||||
(&Transform, &LinearVelocity, &MatchingVelocityTarget),
|
||||
With<actor::PlayerCamera>,
|
||||
>,
|
||||
mut q_retrograde: Query<
|
||||
(&mut Transform, &mut Visibility),
|
||||
(With<MarkerMotionRetrograde>, Without<actor::PlayerCamera>),
|
||||
|
@ -1350,8 +1353,7 @@ fn update_motion_marker(
|
|||
let dv = player_v.0 - player_mv.v;
|
||||
if dv.length() > 1.0 {
|
||||
*vis = Visibility::Inherited;
|
||||
trans.translation =
|
||||
player_trans.translation - (dv.as_vec3().normalize() * 2.0);
|
||||
trans.translation = player_trans.translation - (dv.as_vec3().normalize() * 2.0);
|
||||
trans.look_at(player_trans.translation, player_trans.up());
|
||||
} else {
|
||||
*vis = Visibility::Hidden;
|
||||
|
|
|
@ -34,7 +34,7 @@ pub mod prelude {
|
|||
pub use crate::{
|
||||
actor, audio, camera, chat, cmd, common, game, hud, load, menu, nature, var, visual, world,
|
||||
};
|
||||
pub use actor::MatchingVelocity;
|
||||
pub use actor::MatchingVelocityTarget;
|
||||
pub use game::Cycle::Next;
|
||||
pub use game::Turn::Toggle;
|
||||
pub use game::{GameEvent, Turn};
|
||||
|
|
Loading…
Add table
Reference in a new issue