aboutsummaryrefslogtreecommitdiff
path: root/plugins/movement/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/movement/src')
-rw-r--r--plugins/movement/src/lib.rs52
-rw-r--r--plugins/movement/src/movement.rs5
-rw-r--r--plugins/movement/src/position.rs12
-rw-r--r--plugins/movement/src/reducer.rs62
-rw-r--r--plugins/movement/src/velocity.rs12
5 files changed, 143 insertions, 0 deletions
diff --git a/plugins/movement/src/lib.rs b/plugins/movement/src/lib.rs
new file mode 100644
index 0000000..f7f6ba5
--- /dev/null
+++ b/plugins/movement/src/lib.rs
@@ -0,0 +1,52 @@
+//! CH Modules - Movement
+//!
+//! CH Movement provides a set of systems for driving Entity movement.
+//!
+//! # Included
+//!
+//! - **Velocity**: Represents the entity's current momentum, used by systems to calculate the next frame's position
+//! - **Position**: Represents the entity's current location
+//! - **Movement**: A pure marker, used to flag this entity as movable
+//! - **VelocityReducer**: Controls how Velocity is reduced
+
+#![deny(missing_docs)]
+
+use bevy::{
+ app::{FixedUpdate, Plugin},
+ ecs::{query::With, system::Query},
+};
+use ch_macro_rules::import;
+
+// Basic data
+import!(position, velocity, movement);
+
+// Modifiers
+import!(reducer);
+
+/// Cigarette Hacker movement plugin
+///
+/// Used to describe the movement of characters in the game
+pub struct CHMovementPlugins;
+
+impl Plugin for CHMovementPlugins {
+ fn build(&self, app: &mut bevy::app::App) {
+ app.add_systems(FixedUpdate, update_movement);
+ }
+}
+
+fn update_movement(
+ query: Query<(&mut Position, &mut Velocity, Option<&VelocityReducer>), With<Movement>>,
+) {
+ for (mut pos, mut velo, reducer) in query {
+ // Add Velocity to Position
+ pos.x += velo.x;
+ pos.y += velo.y;
+ pos.z += velo.z;
+
+ // Apply velocity reduction (default to Lerp(0.25) if no reducer present)
+ match reducer {
+ Some(reducer) => reducer.calculate(&mut velo),
+ None => VelocityReducer::Lerp(0.25).calculate(&mut velo),
+ }
+ }
+}
diff --git a/plugins/movement/src/movement.rs b/plugins/movement/src/movement.rs
new file mode 100644
index 0000000..4c13908
--- /dev/null
+++ b/plugins/movement/src/movement.rs
@@ -0,0 +1,5 @@
+use bevy::ecs::component::Component;
+
+/// Indicates that an entity is **movable**, used for CHMovementPlugins systems to recognize it
+#[derive(Component)]
+pub struct Movement;
diff --git a/plugins/movement/src/position.rs b/plugins/movement/src/position.rs
new file mode 100644
index 0000000..c6dc598
--- /dev/null
+++ b/plugins/movement/src/position.rs
@@ -0,0 +1,12 @@
+use bevy::{
+ ecs::component::Component,
+ math::Vec3,
+ prelude::{Deref, DerefMut},
+};
+
+/// Used to represent the actual position of the current entity
+#[derive(Component, Deref, DerefMut, PartialEq, Default, Clone)]
+pub struct Position {
+ #[deref]
+ pos: Vec3,
+}
diff --git a/plugins/movement/src/reducer.rs b/plugins/movement/src/reducer.rs
new file mode 100644
index 0000000..334d37e
--- /dev/null
+++ b/plugins/movement/src/reducer.rs
@@ -0,0 +1,62 @@
+use bevy::{ecs::component::Component, math::Vec3};
+
+use crate::Velocity;
+
+/// Controls how Velocity is reduced
+#[derive(Component)]
+pub enum VelocityReducer {
+ /// Sync mode, only applies the current Velocity to Position each time, does not reduce itself
+ Sync,
+
+ /// Move mode, directly zeroes out the velocity (momentum is transferred to Position)
+ Move,
+
+ /// Constant reduction mode, reduces by a fixed amount each time until it becomes Vec3::ZERO
+ Reduce(Vec3),
+
+ /// Lerp, reduces velocity using linear interpolation each time until it becomes Vec3::ZERO
+ Lerp(f32),
+
+ /// Function, calls a custom function to process velocity
+ Func(Box<dyn Fn(Vec3) -> Vec3 + Send + Sync + 'static>),
+}
+
+impl VelocityReducer {
+ /// Calculates velocity reduction, writing the result back to the Velocity component
+ pub fn calculate(&self, origin: &mut Velocity) {
+ self.calculate_vec(&mut *origin);
+ }
+
+ /// Calculates velocity reduction, writing the result back to Vec3
+ pub fn calculate_vec(&self, origin_vec: &mut Vec3) {
+ match self {
+ VelocityReducer::Sync => {
+ // DO NOTHING
+ }
+ VelocityReducer::Move => {
+ *origin_vec = Vec3::ZERO;
+ }
+ VelocityReducer::Reduce(vec3) => {
+ let mut vec = *origin_vec - *vec3;
+ // Handle direction: if sign flips, clamp to zero
+ if (origin_vec.x > 0.0 && vec.x < 0.0) || (origin_vec.x < 0.0 && vec.x > 0.0) {
+ vec.x = 0.0;
+ }
+ if (origin_vec.y > 0.0 && vec.y < 0.0) || (origin_vec.y < 0.0 && vec.y > 0.0) {
+ vec.y = 0.0;
+ }
+ if (origin_vec.z > 0.0 && vec.z < 0.0) || (origin_vec.z < 0.0 && vec.z > 0.0) {
+ vec.z = 0.0;
+ }
+ *origin_vec = vec;
+ }
+ VelocityReducer::Lerp(lerp) => {
+ let lerp = lerp.clamp(0., 1.);
+ *origin_vec = origin_vec.lerp(Vec3::ZERO, lerp);
+ }
+ VelocityReducer::Func(fn_mut) => {
+ *origin_vec = fn_mut(*origin_vec);
+ }
+ }
+ }
+}
diff --git a/plugins/movement/src/velocity.rs b/plugins/movement/src/velocity.rs
new file mode 100644
index 0000000..c445e64
--- /dev/null
+++ b/plugins/movement/src/velocity.rs
@@ -0,0 +1,12 @@
+use bevy::{
+ ecs::component::Component,
+ math::Vec3,
+ prelude::{Deref, DerefMut},
+};
+
+/// Used to record the amount of movement an object is currently undergoing
+#[derive(Component, Deref, DerefMut, PartialEq, Default, Clone)]
+pub struct Velocity {
+ #[deref]
+ velocity: Vec3,
+}