2022-12-20 15:15:09 +00:00
|
|
|
use std::{collections::HashMap, error::Error, f32::consts::PI, fmt::Debug, hash::Hash};
|
2021-05-13 17:25:45 +00:00
|
|
|
|
2024-10-06 22:17:48 +00:00
|
|
|
use bevy::{math::CompassQuadrant, prelude::*};
|
2022-05-06 16:07:59 +00:00
|
|
|
use bevy_rapier2d::prelude::*;
|
2021-05-13 17:25:45 +00:00
|
|
|
use bevy_tts::Tts;
|
2024-08-25 22:57:52 +00:00
|
|
|
use leafwing_input_manager::prelude::*;
|
2021-05-13 17:25:45 +00:00
|
|
|
|
|
|
|
use crate::{
|
2024-10-06 22:17:48 +00:00
|
|
|
core::{Area, CardinalDirection, GlobalTransformExt, Player, TransformExt},
|
2021-05-13 17:25:45 +00:00
|
|
|
error::error_handler,
|
2022-07-19 16:56:41 +00:00
|
|
|
log::Log,
|
|
|
|
utils::target_and_other,
|
2021-05-13 17:25:45 +00:00
|
|
|
};
|
|
|
|
|
2024-08-25 22:57:52 +00:00
|
|
|
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)]
|
2022-08-02 22:15:22 +00:00
|
|
|
pub enum NavigationAction {
|
|
|
|
Move,
|
2023-01-31 22:48:26 +00:00
|
|
|
Translate,
|
2022-08-02 22:15:22 +00:00
|
|
|
Rotate,
|
2022-09-28 14:32:33 +00:00
|
|
|
SetLinearVelocity,
|
|
|
|
SetAngularVelocity,
|
2022-08-02 22:15:22 +00:00
|
|
|
SnapLeft,
|
|
|
|
SnapRight,
|
|
|
|
SnapCardinal,
|
|
|
|
SnapReverse,
|
|
|
|
}
|
|
|
|
|
2024-08-25 22:57:52 +00:00
|
|
|
impl Actionlike for NavigationAction {
|
|
|
|
fn input_control_kind(&self) -> InputControlKind {
|
|
|
|
match &self {
|
|
|
|
NavigationAction::Move
|
|
|
|
| NavigationAction::Translate
|
|
|
|
| NavigationAction::SetLinearVelocity => InputControlKind::DualAxis,
|
|
|
|
NavigationAction::Rotate | NavigationAction::SetAngularVelocity => {
|
|
|
|
InputControlKind::Axis
|
|
|
|
}
|
|
|
|
NavigationAction::SnapLeft
|
|
|
|
| NavigationAction::SnapRight
|
|
|
|
| NavigationAction::SnapCardinal
|
|
|
|
| NavigationAction::SnapReverse => InputControlKind::Button,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-10 19:50:52 +00:00
|
|
|
#[derive(Component, Clone, Copy, Debug, Deref, DerefMut, Reflect)]
|
2021-05-13 17:25:45 +00:00
|
|
|
#[reflect(Component)]
|
2023-01-31 22:48:26 +00:00
|
|
|
pub struct BackwardMovementFactor(pub f32);
|
2021-05-13 17:25:45 +00:00
|
|
|
|
2023-01-31 22:48:26 +00:00
|
|
|
impl Default for BackwardMovementFactor {
|
2021-05-13 17:25:45 +00:00
|
|
|
fn default() -> Self {
|
2023-01-31 22:48:26 +00:00
|
|
|
Self(1.)
|
2021-05-13 17:25:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-31 22:48:26 +00:00
|
|
|
#[derive(Component, Clone, Copy, Debug, Deref, DerefMut, Reflect)]
|
2021-05-13 17:25:45 +00:00
|
|
|
#[reflect(Component)]
|
2023-01-31 22:48:26 +00:00
|
|
|
pub struct ForwardMovementFactor(pub f32);
|
2021-05-13 17:25:45 +00:00
|
|
|
|
2023-01-31 22:48:26 +00:00
|
|
|
impl Default for ForwardMovementFactor {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self(1.)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Component, Clone, Copy, Debug, Deref, DerefMut, Reflect)]
|
2021-05-13 17:25:45 +00:00
|
|
|
#[reflect(Component)]
|
2023-01-31 22:48:26 +00:00
|
|
|
pub struct StrafeMovementFactor(pub f32);
|
|
|
|
|
|
|
|
impl Default for StrafeMovementFactor {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self(1.)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Component, Clone, Copy, Default, Debug, Deref, DerefMut, Reflect)]
|
|
|
|
#[reflect(Component)]
|
2024-10-06 22:17:48 +00:00
|
|
|
pub struct RotationSpeed(pub Rot2);
|
2021-05-13 17:25:45 +00:00
|
|
|
|
2022-12-19 20:08:31 +00:00
|
|
|
#[derive(Deref, DerefMut)]
|
2022-08-04 16:25:09 +00:00
|
|
|
struct SnapTimer(Timer);
|
2021-05-13 17:25:45 +00:00
|
|
|
|
2022-08-04 16:25:09 +00:00
|
|
|
impl Default for SnapTimer {
|
|
|
|
fn default() -> Self {
|
2022-12-19 20:08:31 +00:00
|
|
|
Self(Timer::from_seconds(0.2, TimerMode::Once))
|
2022-08-04 16:25:09 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-22 02:58:34 +00:00
|
|
|
|
2022-12-19 20:08:31 +00:00
|
|
|
#[derive(Resource, Default, Deref, DerefMut)]
|
|
|
|
struct SnapTimers(HashMap<Entity, SnapTimer>);
|
|
|
|
|
2023-01-31 22:48:26 +00:00
|
|
|
#[derive(Component, Clone, Copy, Debug, Deref, DerefMut, Reflect)]
|
|
|
|
#[reflect(Component)]
|
|
|
|
pub struct Speed(pub f32);
|
|
|
|
|
|
|
|
impl Default for Speed {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self(1.)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-03 14:08:23 +00:00
|
|
|
fn snap(
|
|
|
|
mut tts: ResMut<Tts>,
|
|
|
|
mut snap_timers: ResMut<SnapTimers>,
|
|
|
|
mut query: Query<
|
|
|
|
(
|
|
|
|
Entity,
|
|
|
|
&ActionState<NavigationAction>,
|
|
|
|
&mut Transform,
|
|
|
|
&CardinalDirection,
|
|
|
|
),
|
|
|
|
With<Player>,
|
|
|
|
>,
|
|
|
|
) -> Result<(), Box<dyn Error>> {
|
|
|
|
for (entity, actions, mut transform, direction) in &mut query {
|
|
|
|
if snap_timers.contains_key(&entity) {
|
|
|
|
continue;
|
2024-03-14 18:37:46 +00:00
|
|
|
} else if actions.just_pressed(&NavigationAction::SnapLeft) {
|
2023-04-03 14:08:23 +00:00
|
|
|
snap_timers.insert(entity, SnapTimer::default());
|
2024-10-06 22:17:48 +00:00
|
|
|
transform.rotation = Quat::from_rotation_z(match direction.0 {
|
|
|
|
CompassQuadrant::North => PI,
|
|
|
|
CompassQuadrant::East => PI / 2.,
|
|
|
|
CompassQuadrant::South => 0.,
|
|
|
|
CompassQuadrant::West => -PI / 2.,
|
2023-04-03 14:08:23 +00:00
|
|
|
});
|
2024-03-14 18:37:46 +00:00
|
|
|
} else if actions.just_pressed(&NavigationAction::SnapRight) {
|
2023-04-03 14:08:23 +00:00
|
|
|
snap_timers.insert(entity, SnapTimer::default());
|
2024-10-06 22:17:48 +00:00
|
|
|
transform.rotation = Quat::from_rotation_z(match direction.0 {
|
|
|
|
CompassQuadrant::North => 0.,
|
|
|
|
CompassQuadrant::East => -PI / 2.,
|
|
|
|
CompassQuadrant::South => PI,
|
|
|
|
CompassQuadrant::West => PI / 2.,
|
2023-04-03 14:08:23 +00:00
|
|
|
});
|
2024-03-14 18:37:46 +00:00
|
|
|
} else if actions.just_pressed(&NavigationAction::SnapReverse) {
|
2023-04-03 14:08:23 +00:00
|
|
|
snap_timers.insert(entity, SnapTimer::default());
|
|
|
|
transform.rotate(Quat::from_rotation_z(PI));
|
2024-03-14 18:37:46 +00:00
|
|
|
} else if actions.just_pressed(&NavigationAction::SnapCardinal) {
|
2024-10-06 22:17:48 +00:00
|
|
|
println!("Direction: {direction:?}");
|
|
|
|
let yaw: Rot2 = direction.into();
|
|
|
|
let yaw = yaw.as_radians();
|
|
|
|
println!("Yaw: {yaw}");
|
2023-04-03 14:08:23 +00:00
|
|
|
transform.rotation = Quat::from_rotation_z(yaw);
|
|
|
|
tts.speak(direction.to_string(), true)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tick_snap_timers(time: Res<Time>, mut snap_timers: ResMut<SnapTimers>) {
|
|
|
|
for timer in snap_timers.values_mut() {
|
|
|
|
timer.tick(time.delta());
|
|
|
|
}
|
|
|
|
snap_timers.retain(|_, v| !v.finished());
|
|
|
|
}
|
|
|
|
|
2023-01-31 22:48:26 +00:00
|
|
|
fn controls(
|
2024-08-11 14:08:20 +00:00
|
|
|
rapier_context: Res<RapierContext>,
|
2023-01-31 22:48:26 +00:00
|
|
|
time: Res<Time>,
|
2022-12-19 20:08:31 +00:00
|
|
|
snap_timers: Res<SnapTimers>,
|
2022-08-04 16:25:09 +00:00
|
|
|
mut query: Query<(
|
|
|
|
Entity,
|
2022-09-28 14:32:33 +00:00
|
|
|
&mut ActionState<NavigationAction>,
|
2022-08-04 16:25:09 +00:00
|
|
|
&mut Velocity,
|
2023-01-31 22:48:26 +00:00
|
|
|
&Speed,
|
2022-08-04 16:25:09 +00:00
|
|
|
Option<&RotationSpeed>,
|
2023-01-31 22:48:26 +00:00
|
|
|
Option<&BackwardMovementFactor>,
|
|
|
|
Option<&ForwardMovementFactor>,
|
|
|
|
Option<&StrafeMovementFactor>,
|
2024-03-24 21:12:11 +00:00
|
|
|
&mut Transform,
|
2024-08-11 14:08:20 +00:00
|
|
|
&Collider,
|
2022-08-04 16:25:09 +00:00
|
|
|
)>,
|
2023-01-31 22:48:26 +00:00
|
|
|
) {
|
|
|
|
for (
|
|
|
|
entity,
|
|
|
|
mut actions,
|
|
|
|
mut velocity,
|
|
|
|
speed,
|
|
|
|
rotation_speed,
|
|
|
|
backward_movement_factor,
|
|
|
|
forward_movement_factor,
|
|
|
|
strafe_movement_factor,
|
2024-03-24 21:12:11 +00:00
|
|
|
mut transform,
|
2024-08-11 14:08:20 +00:00
|
|
|
collider,
|
2023-01-31 22:48:26 +00:00
|
|
|
) in &mut query
|
2021-05-13 17:25:45 +00:00
|
|
|
{
|
2024-08-25 22:57:52 +00:00
|
|
|
if !actions.action_disabled(&NavigationAction::Move) {
|
|
|
|
let mut direction = actions.clamped_axis_pair(&NavigationAction::Move);
|
|
|
|
let forward_movement_factor =
|
|
|
|
forward_movement_factor.map(|v| v.0).unwrap_or_else(|| 1.);
|
|
|
|
let backward_movement_factor =
|
|
|
|
backward_movement_factor.map(|v| v.0).unwrap_or_else(|| 1.);
|
|
|
|
let strafe_movement_factor = strafe_movement_factor.map(|v| v.0).unwrap_or_else(|| 1.);
|
|
|
|
let forward_backward_movement_factor = if direction.x > 0. {
|
|
|
|
forward_movement_factor
|
|
|
|
} else if direction.x < 0. {
|
|
|
|
backward_movement_factor
|
2022-09-28 14:32:33 +00:00
|
|
|
} else {
|
2024-08-25 22:57:52 +00:00
|
|
|
1.
|
|
|
|
};
|
|
|
|
let movement_factor = if direction.x != 0. && direction.y != 0. {
|
|
|
|
strafe_movement_factor.min(forward_backward_movement_factor)
|
|
|
|
} else if direction.y != 0. {
|
|
|
|
strafe_movement_factor
|
|
|
|
} else {
|
|
|
|
forward_backward_movement_factor
|
|
|
|
};
|
|
|
|
trace!("{entity:?}: move: {direction:?}");
|
|
|
|
direction = transform
|
|
|
|
.compute_matrix()
|
|
|
|
.transform_vector3(direction.extend(0.))
|
|
|
|
.truncate();
|
|
|
|
let mut speed = **speed;
|
|
|
|
speed *= movement_factor;
|
|
|
|
let move_velocity = direction * speed;
|
|
|
|
// println!("{entity:?}: SetLinearVelocity: {velocity:?}");
|
|
|
|
actions.set_axis_pair(&NavigationAction::SetLinearVelocity, move_velocity);
|
2023-01-31 22:48:26 +00:00
|
|
|
}
|
2024-08-25 22:57:52 +00:00
|
|
|
if velocity.linvel != actions.axis_pair(&NavigationAction::SetLinearVelocity) {
|
|
|
|
velocity.linvel = actions.axis_pair(&NavigationAction::SetLinearVelocity);
|
|
|
|
}
|
|
|
|
if actions.axis_pair(&NavigationAction::Translate) != Vec2::ZERO {
|
|
|
|
let pair = actions.axis_pair(&NavigationAction::Translate);
|
|
|
|
if rapier_context
|
|
|
|
.cast_shape(
|
|
|
|
transform.translation.truncate(),
|
2024-10-06 22:17:48 +00:00
|
|
|
transform.yaw().as_radians(),
|
2024-08-25 22:57:52 +00:00
|
|
|
pair,
|
|
|
|
collider,
|
|
|
|
ShapeCastOptions {
|
|
|
|
max_time_of_impact: 1.,
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
QueryFilter::new()
|
|
|
|
.exclude_sensors()
|
|
|
|
.exclude_collider(entity),
|
|
|
|
)
|
|
|
|
.is_none()
|
|
|
|
{
|
|
|
|
transform.translation += pair.extend(0.);
|
2023-01-31 22:48:26 +00:00
|
|
|
}
|
2024-08-25 22:57:52 +00:00
|
|
|
actions.set_axis_pair(&NavigationAction::Translate, Vec2::ZERO);
|
2022-08-04 16:25:09 +00:00
|
|
|
}
|
|
|
|
if !snap_timers.contains_key(&entity) {
|
2022-08-02 22:15:22 +00:00
|
|
|
if let Some(rotation_speed) = rotation_speed {
|
2024-08-25 22:57:52 +00:00
|
|
|
let delta =
|
2024-10-06 22:17:48 +00:00
|
|
|
rotation_speed.as_radians() * actions.clamped_value(&NavigationAction::Rotate);
|
2024-08-25 22:57:52 +00:00
|
|
|
actions.set_value(&NavigationAction::SetAngularVelocity, delta);
|
2022-03-22 02:58:34 +00:00
|
|
|
}
|
2022-09-28 14:32:33 +00:00
|
|
|
}
|
2024-08-25 22:57:52 +00:00
|
|
|
if actions.value(&NavigationAction::SetAngularVelocity) != 0. {
|
2024-03-24 21:12:11 +00:00
|
|
|
// velocity.angvel =
|
|
|
|
// actions.value(&NavigationAction::SetAngularVelocity);
|
|
|
|
transform.rotation *= Quat::from_rotation_z(
|
|
|
|
actions.value(&NavigationAction::SetAngularVelocity) * time.delta_seconds(),
|
|
|
|
);
|
2021-05-13 17:25:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-08-04 16:25:09 +00:00
|
|
|
|
2021-07-26 20:50:25 +00:00
|
|
|
fn update_direction(
|
|
|
|
mut commands: Commands,
|
2022-02-14 12:56:45 +00:00
|
|
|
mut query: Query<
|
2022-07-19 16:24:45 +00:00
|
|
|
(Entity, &GlobalTransform, Option<&mut CardinalDirection>),
|
2021-07-26 20:50:25 +00:00
|
|
|
(With<Player>, Changed<Transform>),
|
|
|
|
>,
|
|
|
|
) {
|
2023-03-28 17:13:23 +00:00
|
|
|
for (entity, transform, direction) in &mut query {
|
2022-07-19 16:24:45 +00:00
|
|
|
let yaw = transform.yaw();
|
2021-07-26 20:50:25 +00:00
|
|
|
let new_direction: CardinalDirection = yaw.into();
|
2022-02-14 12:56:45 +00:00
|
|
|
if let Some(mut direction) = direction {
|
|
|
|
if *direction != new_direction {
|
|
|
|
*direction = new_direction;
|
|
|
|
}
|
|
|
|
} else {
|
2021-07-26 20:50:25 +00:00
|
|
|
commands.entity(entity).insert(new_direction);
|
2021-05-13 17:25:45 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-26 20:50:25 +00:00
|
|
|
}
|
|
|
|
|
2022-09-21 18:56:57 +00:00
|
|
|
fn remove_direction(
|
|
|
|
mut commands: Commands,
|
2023-03-28 16:57:37 +00:00
|
|
|
mut removed: RemovedComponents<Transform>,
|
2022-09-21 18:56:57 +00:00
|
|
|
directions: Query<&CardinalDirection>,
|
|
|
|
) {
|
2024-02-09 20:59:16 +00:00
|
|
|
for entity in removed.read() {
|
2022-09-21 18:56:57 +00:00
|
|
|
if directions.contains(entity) {
|
2023-04-01 12:20:59 +00:00
|
|
|
commands.entity(entity).remove::<CardinalDirection>();
|
2022-09-21 18:56:57 +00:00
|
|
|
}
|
2022-07-11 22:03:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-26 20:50:25 +00:00
|
|
|
fn speak_direction(
|
|
|
|
mut tts: ResMut<Tts>,
|
2024-10-06 22:17:48 +00:00
|
|
|
player: Query<&CardinalDirection, (With<Player>, Changed<CardinalDirection>)>,
|
2021-07-26 20:50:25 +00:00
|
|
|
) -> Result<(), Box<dyn Error>> {
|
2024-10-06 22:17:48 +00:00
|
|
|
if let Ok(direction) = player.get_single() {
|
|
|
|
let direction: String = (*direction).into();
|
|
|
|
tts.speak(direction, true)?;
|
2022-01-13 20:43:02 +00:00
|
|
|
}
|
2021-05-13 17:25:45 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2022-05-12 15:07:38 +00:00
|
|
|
fn add_speed(mut commands: Commands, query: Query<Entity, (Added<Speed>, Without<Velocity>)>) {
|
2023-03-28 17:13:23 +00:00
|
|
|
for entity in &query {
|
2022-05-12 15:07:38 +00:00
|
|
|
commands.entity(entity).insert(Velocity {
|
|
|
|
linvel: Vec2::ZERO,
|
|
|
|
..default()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-06 15:42:25 +00:00
|
|
|
fn log_area_descriptions(
|
2022-07-19 16:56:41 +00:00
|
|
|
mut events: EventReader<CollisionEvent>,
|
|
|
|
areas: Query<(&Area, Option<&Name>)>,
|
|
|
|
players: Query<&Player>,
|
2024-10-06 15:42:25 +00:00
|
|
|
config: Res<NavigationPlugin>,
|
2022-07-19 16:56:41 +00:00
|
|
|
mut log: Query<&mut Log>,
|
2024-10-06 15:42:25 +00:00
|
|
|
) {
|
2022-07-19 16:56:41 +00:00
|
|
|
if !config.log_area_descriptions {
|
|
|
|
return;
|
|
|
|
}
|
2024-02-09 20:59:16 +00:00
|
|
|
for event in events.read() {
|
2022-07-19 16:56:41 +00:00
|
|
|
let (entity1, entity2, started) = match event {
|
|
|
|
CollisionEvent::Started(collider1, collider2, _) => (collider1, collider2, true),
|
|
|
|
CollisionEvent::Stopped(collider1, collider2, _) => (collider1, collider2, false),
|
|
|
|
};
|
|
|
|
if let Some((area, other)) = target_and_other(*entity1, *entity2, &|v| areas.get(v).is_ok())
|
|
|
|
{
|
|
|
|
if players.get(other).is_ok() {
|
|
|
|
if let Ok((aabb, area_name)) = areas.get(area) {
|
|
|
|
let name = if let Some(name) = area_name {
|
|
|
|
Some(name.to_string())
|
|
|
|
} else if config.describe_undescribed_areas {
|
|
|
|
Some(format!("{}-by-{} area", aabb.extents().x, aabb.extents().y))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
if let Some(name) = name {
|
|
|
|
if let Ok(mut log) = log.get_single_mut() {
|
|
|
|
if started {
|
|
|
|
log.push(format!("Entering {name}."));
|
|
|
|
} else {
|
|
|
|
log.push(format!("Leaving {name}."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-28 16:57:37 +00:00
|
|
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
2023-04-03 14:08:23 +00:00
|
|
|
pub struct Movement;
|
2023-01-31 22:48:26 +00:00
|
|
|
|
2022-12-19 20:08:31 +00:00
|
|
|
#[derive(Resource, Clone, Debug)]
|
2024-10-06 15:42:25 +00:00
|
|
|
pub struct NavigationPlugin {
|
2022-07-19 16:56:41 +00:00
|
|
|
pub describe_undescribed_areas: bool,
|
|
|
|
pub log_area_descriptions: bool,
|
2021-05-13 17:25:45 +00:00
|
|
|
}
|
|
|
|
|
2024-10-06 15:42:25 +00:00
|
|
|
impl Default for NavigationPlugin {
|
2021-05-13 17:25:45 +00:00
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
2022-07-19 16:56:41 +00:00
|
|
|
describe_undescribed_areas: false,
|
|
|
|
log_area_descriptions: true,
|
2021-05-13 17:25:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-06 15:42:25 +00:00
|
|
|
impl Plugin for NavigationPlugin {
|
2022-01-10 19:50:52 +00:00
|
|
|
fn build(&self, app: &mut App) {
|
2024-10-06 15:42:25 +00:00
|
|
|
app.insert_resource(self.clone())
|
|
|
|
.init_resource::<SnapTimers>()
|
2023-01-31 22:48:26 +00:00
|
|
|
.register_type::<BackwardMovementFactor>()
|
|
|
|
.register_type::<ForwardMovementFactor>()
|
|
|
|
.register_type::<StrafeMovementFactor>()
|
2021-05-13 17:25:45 +00:00
|
|
|
.register_type::<RotationSpeed>()
|
2022-12-19 20:08:31 +00:00
|
|
|
.register_type::<Speed>()
|
2023-09-08 21:12:35 +00:00
|
|
|
.add_plugins(InputManagerPlugin::<NavigationAction>::default())
|
|
|
|
.add_systems(PreUpdate, (update_direction, add_speed))
|
2023-03-28 16:57:37 +00:00
|
|
|
.add_systems(
|
2023-09-08 21:12:35 +00:00
|
|
|
Update,
|
2023-04-03 14:08:23 +00:00
|
|
|
(snap.pipe(error_handler), controls)
|
|
|
|
.chain()
|
|
|
|
.in_set(Movement),
|
2023-03-28 16:57:37 +00:00
|
|
|
)
|
2023-04-03 14:08:23 +00:00
|
|
|
.add_systems(
|
2024-08-25 22:57:52 +00:00
|
|
|
FixedUpdate,
|
2023-09-08 21:12:35 +00:00
|
|
|
(tick_snap_timers, speak_direction.pipe(error_handler)),
|
|
|
|
)
|
2024-10-06 15:42:25 +00:00
|
|
|
.add_systems(PostUpdate, (remove_direction, log_area_descriptions));
|
2021-05-13 17:25:45 +00:00
|
|
|
}
|
|
|
|
}
|