Skip to content

Commit

Permalink
refactor some modules
Browse files Browse the repository at this point in the history
  • Loading branch information
janhohenheim committed Sep 16, 2024
1 parent 1d30196 commit 33bdcf0
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 156 deletions.
77 changes: 77 additions & 0 deletions src/player/camera/control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::f32::consts::FRAC_PI_2;

use crate::{dialog::conditions::dialog_running, player::Player};
use bevy::{app::RunFixedMainLoop, prelude::*, time::run_fixed_main_schedule};
use leafwing_input_manager::prelude::*;

use super::{PlayerCamera, PlayerCameraConfig};

pub(super) fn plugin(app: &mut App) {
app.add_plugins(InputManagerPlugin::<CameraAction>::default());
app.add_systems(
RunFixedMainLoop,
rotate_camera
.run_if(not(dialog_running))
.before(run_fixed_main_schedule),
);
app.add_systems(Update, follow_player);
}

#[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)]
#[actionlike(DualAxis)]
pub enum CameraAction {
RotateCamera,
}

impl CameraAction {
pub fn default_input_map() -> InputMap<Self> {
let mut input_map = InputMap::default();

// Default gamepad input bindings
input_map.insert_dual_axis(CameraAction::RotateCamera, GamepadStick::LEFT);

// Default kbm input bindings
input_map.insert_dual_axis(CameraAction::RotateCamera, MouseMove::default());

input_map
}
}

fn follow_player(
mut q_camera: Query<&mut Transform, With<PlayerCamera>>,
q_player: Query<&Transform, (With<Player>, Without<PlayerCamera>)>,
) {
// Use `Transform` instead of `Position`` because we want the camera to move
// smoothly, so we use the interpolated transform of the player.
let Ok(player_transform) = q_player.get_single() else {
return;
};
let Ok(mut camera_transform) = q_camera.get_single_mut() else {
return;
};
let height_offset = 0.5;
camera_transform.translation =
player_transform.translation + player_transform.up() * height_offset;
}

fn rotate_camera(
mut character_query: Query<(
&mut Transform,
&ActionState<CameraAction>,
&PlayerCameraConfig,
)>,
) {
for (mut transform, action_state, config) in &mut character_query {
let delta = action_state.axis_pair(&CameraAction::RotateCamera);
let delta_yaw = -delta.x * config.sensitivity.x;
let delta_pitch = -delta.y * config.sensitivity.y;

let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ);
let yaw = yaw + delta_yaw;

const PITCH_LIMIT: f32 = FRAC_PI_2 - 0.01;
let pitch = (pitch + delta_pitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);

transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
}
}
79 changes: 5 additions & 74 deletions src/player/camera/mod.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
use std::f32::consts::FRAC_PI_2;

use crate::{dialog::conditions::dialog_running, ui_camera::UiCamera};
use bevy::{app::RunFixedMainLoop, prelude::*, time::run_fixed_main_schedule};
use crate::ui_camera::UiCamera;
use bevy::prelude::*;
use control::CameraAction;
use leafwing_input_manager::prelude::*;

use super::Player;

mod control;
mod on_dialog;

pub(super) fn plugin(app: &mut App) {
app.register_type::<(PlayerCamera, PlayerCameraConfig)>();
app.add_plugins(InputManagerPlugin::<CameraAction>::default());
app.add_systems(
RunFixedMainLoop,
rotate_camera
.run_if(not(dialog_running))
.before(run_fixed_main_schedule),
);
app.add_systems(Update, follow_player);
app.add_plugins(on_dialog::plugin);
app.add_plugins((on_dialog::plugin, control::plugin));
}

#[derive(Component, Default, Reflect)]
Expand Down Expand Up @@ -48,26 +38,6 @@ impl Default for PlayerCameraConfig {
}
}

#[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)]
#[actionlike(DualAxis)]
pub enum CameraAction {
RotateCamera,
}

impl CameraAction {
pub fn default_input_map() -> InputMap<Self> {
let mut input_map = InputMap::default();

// Default gamepad input bindings
input_map.insert_dual_axis(CameraAction::RotateCamera, GamepadStick::LEFT);

// Default kbm input bindings
input_map.insert_dual_axis(CameraAction::RotateCamera, MouseMove::default());

input_map
}
}

pub fn spawn_player_camera(world: &mut World) {
let ui_cameras: Vec<_> = world
.query_filtered::<Entity, With<UiCamera>>()
Expand All @@ -85,42 +55,3 @@ pub fn spawn_player_camera(world: &mut World) {
InputManagerBundle::with_map(CameraAction::default_input_map()),
));
}

fn follow_player(
mut q_camera: Query<&mut Transform, With<PlayerCamera>>,
q_player: Query<&Transform, (With<Player>, Without<PlayerCamera>)>,
) {
// Use `Transform` instead of `Position`` because we want the camera to move
// smoothly, so we use the interpolated transform of the player.
let Ok(player_transform) = q_player.get_single() else {
return;
};
let Ok(mut camera_transform) = q_camera.get_single_mut() else {
return;
};
let height_offset = 0.5;
camera_transform.translation =
player_transform.translation + player_transform.up() * height_offset;
}

fn rotate_camera(
mut character_query: Query<(
&mut Transform,
&ActionState<CameraAction>,
&PlayerCameraConfig,
)>,
) {
for (mut transform, action_state, config) in &mut character_query {
let delta = action_state.axis_pair(&CameraAction::RotateCamera);
let delta_yaw = -delta.x * config.sensitivity.x;
let delta_pitch = -delta.y * config.sensitivity.y;

let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ);
let yaw = yaw + delta_yaw;

const PITCH_LIMIT: f32 = FRAC_PI_2 - 0.01;
let pitch = (pitch + delta_pitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);

transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
}
}
2 changes: 1 addition & 1 deletion src/player/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
character::{action::CharacterAction, controller::OverrideForwardDirection},
};

use super::{camera::PlayerCamera, interactions::components::AvailablePlayerInteraction, Player};
use super::{camera::PlayerCamera, interactions::AvailablePlayerInteraction, Player};

pub(super) fn plugin(app: &mut App) {
app.load_resource::<PlayerAssets>();
Expand Down
63 changes: 0 additions & 63 deletions src/player/interactions/components.rs

This file was deleted.

5 changes: 1 addition & 4 deletions src/player/interactions/interact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ use leafwing_input_manager::prelude::*;
use crate::{character::action::CharacterAction, dialog::StartDialog, player::Player};

use super::{
components::{
AvailablePlayerInteraction, PlayerInteraction,
},
OpportunitySystem,
OpportunitySystem, {AvailablePlayerInteraction, PlayerInteraction},
};

pub(super) fn plugin(app: &mut App) {
Expand Down
69 changes: 61 additions & 8 deletions src/player/interactions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
use crate::system_set::VariableGameSystem;
use bevy::prelude::*;
use bevy::{
ecs::component::{ComponentHooks, StorageType},
prelude::*,
};

pub mod components;
mod interact;
mod prompt;
mod update_available;

pub(super) fn plugin(app: &mut App) {
app.add_plugins((
components::plugin,
prompt::plugin,
interact::plugin,
update_available::plugin,
));
app.register_type::<(
PlayerInteractionParameters,
AvailablePlayerInteraction,
PlayerInteraction,
)>();
app.add_plugins((prompt::plugin, interact::plugin, update_available::plugin));
app.configure_sets(
Update,
(
Expand All @@ -37,3 +39,54 @@ enum OpportunitySystem {
/// Handles the player interacting with the best available opportunity.
Interact,
}

#[derive(Debug, Component, PartialEq, Eq, Clone, Default, Deref, DerefMut, Reflect)]
#[reflect(Component, PartialEq, Default)]
pub struct AvailablePlayerInteraction(pub Option<Entity>);

/// The general idea is as follows:
/// This component sits on a collider for an interactable object, e.g. a door or a character.
/// Every update, we send a raycast from the camera's forward direction to see if it hits a
/// [`PotentialOpportunity`] collider.
/// If so, we have an interaction opportunity.
#[derive(Debug, Component, PartialEq, Clone, Reflect)]
#[reflect(Component, PartialEq)]
pub struct PlayerInteractionParameters {
/// The prompt to display when the opportunity is available.
pub prompt: String,
/// The maximum distance from the camera at which the opportunity can be interacted with.
pub max_distance: f32,
}

impl PlayerInteractionParameters {
pub fn default(player_interaction: &PlayerInteraction) -> Self {
match player_interaction {
PlayerInteraction::Dialog(..) => Self {
prompt: "Talk".to_string(),
max_distance: 2.5,
},
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, Reflect)]
#[reflect(PartialEq, Component)]
pub enum PlayerInteraction {
/// A dialog opportunity with a Yarn Spinner dialogue node.
Dialog(String),
}

impl Component for PlayerInteraction {
const STORAGE_TYPE: StorageType = StorageType::Table;

fn register_component_hooks(hooks: &mut ComponentHooks) {
hooks.on_add(|mut world, entity, _component_id| {
if world.get::<PlayerInteractionParameters>(entity).is_some() {
return;
}
let interaction = world.get::<PlayerInteraction>(entity).unwrap();
let parameters = PlayerInteractionParameters::default(interaction);
world.commands().entity(entity).insert(parameters);
});
}
}
3 changes: 1 addition & 2 deletions src/player/interactions/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use bevy::ui::Val::*;
use sickle_ui::{prelude::*, ui_commands::SetTextExt as _};

use super::{
components::{AvailablePlayerInteraction, PlayerInteractionParameters},
OpportunitySystem,
OpportunitySystem, {AvailablePlayerInteraction, PlayerInteractionParameters},
};

pub(super) fn plugin(app: &mut App) {
Expand Down
5 changes: 1 addition & 4 deletions src/player/interactions/update_available.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ use avian3d::prelude::*;
use bevy::prelude::*;

use super::{
components::{
AvailablePlayerInteraction, PlayerInteraction, PlayerInteractionParameters,
},
OpportunitySystem,
OpportunitySystem, {AvailablePlayerInteraction, PlayerInteraction, PlayerInteractionParameters},
};

pub(super) fn plugin(app: &mut App) {
Expand Down

0 comments on commit 33bdcf0

Please sign in to comment.