This commit is contained in:
parent
cadaeceba9
commit
4357a5838a
|
@ -1,4 +1,7 @@
|
||||||
use std::{collections::HashMap, error::Error, fmt::Debug, hash::Hash, marker::PhantomData};
|
use std::{
|
||||||
|
collections::HashMap, error::Error, f32::consts::PI, fmt::Debug, hash::Hash,
|
||||||
|
marker::PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_input_actionmap::InputMap;
|
use bevy_input_actionmap::InputMap;
|
||||||
|
@ -41,11 +44,15 @@ pub struct Speed(pub f32);
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct Sprinting;
|
pub struct Sprinting;
|
||||||
|
|
||||||
|
#[derive(Default, Deref, DerefMut)]
|
||||||
|
struct Snapping(bool);
|
||||||
|
|
||||||
fn movement_controls<S, A: 'static>(
|
fn movement_controls<S, A: 'static>(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
config: Res<NavigationConfig<S, A>>,
|
config: Res<NavigationConfig<S, A>>,
|
||||||
input: Res<InputMap<A>>,
|
input: Res<InputMap<A>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
|
mut snapping: ResMut<Snapping>,
|
||||||
mut query: Query<
|
mut query: Query<
|
||||||
(
|
(
|
||||||
Entity,
|
Entity,
|
||||||
|
@ -66,6 +73,41 @@ fn movement_controls<S, A: 'static>(
|
||||||
for (entity, mut velocity, mut speed, max_speed, rotation_speed, mut position, destination) in
|
for (entity, mut velocity, mut speed, max_speed, rotation_speed, mut position, destination) in
|
||||||
query.iter_mut()
|
query.iter_mut()
|
||||||
{
|
{
|
||||||
|
if **snapping {
|
||||||
|
if let Some(action) = config.action_forward.clone() {
|
||||||
|
if input.active(action) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(action) = config.action_backward.clone() {
|
||||||
|
if input.active(action) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(action) = config.action_left.clone() {
|
||||||
|
if input.active(action) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(action) = config.action_right.clone() {
|
||||||
|
if input.active(action) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let (Some(_), Some(rotate_left), Some(rotate_right)) = (
|
||||||
|
rotation_speed,
|
||||||
|
config.action_rotate_left.clone(),
|
||||||
|
config.action_rotate_right.clone(),
|
||||||
|
) {
|
||||||
|
if input.active(rotate_left) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if input.active(rotate_right) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
**snapping = false;
|
||||||
|
} else {
|
||||||
let sprinting = if let Some(action) = config.action_sprint.clone() {
|
let sprinting = if let Some(action) = config.action_sprint.clone() {
|
||||||
input.active(action)
|
input.active(action)
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,6 +214,66 @@ fn movement_controls<S, A: 'static>(
|
||||||
**speed = **max_speed / 3.;
|
**speed = **max_speed / 3.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn snap<S, A: 'static>(
|
||||||
|
mut tts: ResMut<Tts>,
|
||||||
|
input: Res<InputMap<A>>,
|
||||||
|
config: Res<NavigationConfig<S, A>>,
|
||||||
|
mut snapping: ResMut<Snapping>,
|
||||||
|
mut position: Query<(&mut RigidBodyPositionComponent, &CardinalDirection), With<Player>>,
|
||||||
|
) -> Result<(), Box<dyn Error>>
|
||||||
|
where
|
||||||
|
S: bevy::ecs::component::Component + Clone + Debug + Eq + Hash,
|
||||||
|
A: Hash + Eq + Clone + Send + Sync,
|
||||||
|
{
|
||||||
|
if let Some(action) = config.action_snap_left.clone() {
|
||||||
|
if input.just_active(action) {
|
||||||
|
for (mut position, direction) in position.iter_mut() {
|
||||||
|
**snapping = true;
|
||||||
|
position.position.rotation = UnitComplex::new(match direction {
|
||||||
|
CardinalDirection::North => PI,
|
||||||
|
CardinalDirection::East => PI / 2.,
|
||||||
|
CardinalDirection::South => 0.,
|
||||||
|
CardinalDirection::West => PI * 1.5,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(action) = config.action_snap_right.clone() {
|
||||||
|
if input.just_active(action) {
|
||||||
|
for (mut position, direction) in position.iter_mut() {
|
||||||
|
**snapping = true;
|
||||||
|
position.position.rotation = UnitComplex::new(match direction {
|
||||||
|
CardinalDirection::North => 0.,
|
||||||
|
CardinalDirection::East => PI * 1.5,
|
||||||
|
CardinalDirection::South => PI,
|
||||||
|
CardinalDirection::West => PI / 2.,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(action) = config.action_snap_cardinal.clone() {
|
||||||
|
if input.just_active(action) {
|
||||||
|
for (mut position, direction) in position.iter_mut() {
|
||||||
|
**snapping = true;
|
||||||
|
let yaw: Angle = direction.into();
|
||||||
|
let yaw = yaw.radians();
|
||||||
|
position.position.rotation = UnitComplex::new(yaw);
|
||||||
|
tts.speak(direction.to_string(), true)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(action) = config.action_snap_reverse.clone() {
|
||||||
|
if input.just_active(action) {
|
||||||
|
for (mut position, _) in position.iter_mut() {
|
||||||
|
**snapping = true;
|
||||||
|
position.position.rotation *= UnitComplex::new(PI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_direction(
|
fn update_direction(
|
||||||
|
@ -230,6 +332,10 @@ pub struct NavigationConfig<S, A> {
|
||||||
pub action_right: Option<A>,
|
pub action_right: Option<A>,
|
||||||
pub action_rotate_left: Option<A>,
|
pub action_rotate_left: Option<A>,
|
||||||
pub action_rotate_right: Option<A>,
|
pub action_rotate_right: Option<A>,
|
||||||
|
pub action_snap_left: Option<A>,
|
||||||
|
pub action_snap_right: Option<A>,
|
||||||
|
pub action_snap_reverse: Option<A>,
|
||||||
|
pub action_snap_cardinal: Option<A>,
|
||||||
pub action_sprint: Option<A>,
|
pub action_sprint: Option<A>,
|
||||||
pub forward_movement_factor: f32,
|
pub forward_movement_factor: f32,
|
||||||
pub backward_movement_factor: f32,
|
pub backward_movement_factor: f32,
|
||||||
|
@ -247,6 +353,10 @@ impl<S, A> Default for NavigationConfig<S, A> {
|
||||||
action_right: None,
|
action_right: None,
|
||||||
action_rotate_left: None,
|
action_rotate_left: None,
|
||||||
action_rotate_right: None,
|
action_rotate_right: None,
|
||||||
|
action_snap_left: None,
|
||||||
|
action_snap_right: None,
|
||||||
|
action_snap_reverse: None,
|
||||||
|
action_snap_cardinal: None,
|
||||||
action_sprint: None,
|
action_sprint: None,
|
||||||
forward_movement_factor: 1.,
|
forward_movement_factor: 1.,
|
||||||
backward_movement_factor: 1.,
|
backward_movement_factor: 1.,
|
||||||
|
@ -280,19 +390,23 @@ where
|
||||||
.get_resource::<NavigationConfig<S, A>>()
|
.get_resource::<NavigationConfig<S, A>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
app.register_type::<MaxSpeed>()
|
app.init_resource::<Snapping>()
|
||||||
|
.register_type::<MaxSpeed>()
|
||||||
.register_type::<RotationSpeed>()
|
.register_type::<RotationSpeed>()
|
||||||
.register_type::<Sprinting>()
|
.register_type::<Sprinting>()
|
||||||
.add_system(update_direction)
|
.add_system(update_direction)
|
||||||
.add_system(speak_direction.chain(error_handler))
|
.add_system(speak_direction.chain(error_handler))
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, remove_speed);
|
.add_system_to_stage(CoreStage::PostUpdate, remove_speed);
|
||||||
if config.movement_control_states.is_empty() {
|
if config.movement_control_states.is_empty() {
|
||||||
app.add_system(movement_controls::<S, A>);
|
app.add_system(movement_controls::<S, A>)
|
||||||
|
.add_system(snap::<S, A>.chain(error_handler));
|
||||||
} else {
|
} else {
|
||||||
let states = config.movement_control_states;
|
let states = config.movement_control_states;
|
||||||
for state in states {
|
for state in states {
|
||||||
app.add_system_set(
|
app.add_system_set(
|
||||||
SystemSet::on_update(state).with_system(movement_controls::<S, A>),
|
SystemSet::on_update(state)
|
||||||
|
.with_system(movement_controls::<S, A>)
|
||||||
|
.with_system(snap::<S, A>.chain(error_handler)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user