use nightshade::prelude::*;
#[inline]
pub fn key_down(world: &World, key: KeyCode) -> bool {
world.resources.input.keyboard.is_key_pressed(key)
}
#[inline]
pub fn key_pressed(world: &World, key: KeyCode) -> bool {
world.resources.input.keyboard.just_pressed(key)
}
#[inline]
pub fn mouse_down(world: &World, button: MouseButton) -> bool {
let state = world.resources.input.mouse.state;
match button {
MouseButton::Left => state.contains(MouseState::LEFT_CLICKED),
MouseButton::Right => state.contains(MouseState::RIGHT_CLICKED),
MouseButton::Middle => state.contains(MouseState::MIDDLE_CLICKED),
_ => false,
}
}
#[inline]
pub fn mouse_clicked(world: &World, button: MouseButton) -> bool {
let state = world.resources.input.mouse.state;
match button {
MouseButton::Left => state.contains(MouseState::LEFT_JUST_PRESSED),
MouseButton::Right => state.contains(MouseState::RIGHT_JUST_PRESSED),
MouseButton::Middle => state.contains(MouseState::MIDDLE_JUST_PRESSED),
_ => false,
}
}
#[inline]
pub fn mouse_position(world: &World) -> Vec2 {
world.resources.input.mouse.position
}
#[inline]
pub fn mouse_delta(world: &World) -> Vec2 {
world.resources.input.mouse.position_delta
}
#[inline]
pub fn mouse_scroll(world: &World) -> f32 {
world.resources.input.mouse.wheel_delta.y
}
#[inline]
pub fn pointer_over_ui(world: &World) -> bool {
world
.resources
.retained_ui
.interaction
.hovered_entity
.is_some()
}
#[inline]
pub fn axis(world: &World, negative: KeyCode, positive: KeyCode) -> f32 {
let mut value = 0.0;
if key_down(world, negative) {
value -= 1.0;
}
if key_down(world, positive) {
value += 1.0;
}
value
}
pub fn wasd(world: &World) -> Vec3 {
let forward_input = axis(world, KeyCode::KeyS, KeyCode::KeyW);
let strafe_input = axis(world, KeyCode::KeyA, KeyCode::KeyD);
if forward_input == 0.0 && strafe_input == 0.0 {
return Vec3::zeros();
}
let camera_forward = crate::camera::camera_forward(world);
let mut planar_forward = Vec3::new(camera_forward.x, 0.0, camera_forward.z);
if planar_forward.magnitude_squared() < f32::EPSILON {
planar_forward = Vec3::new(0.0, 0.0, -1.0);
}
let planar_forward = planar_forward.normalize();
let right = nalgebra_glm::cross(&planar_forward, &Vec3::y());
(planar_forward * forward_input + right * strafe_input).normalize()
}
#[inline]
pub fn delta_time(world: &World) -> f32 {
world.resources.window.timing.delta_time
}
#[inline]
pub fn real_delta_time(world: &World) -> f32 {
world.resources.window.timing.raw_delta_time
}
#[inline]
pub fn elapsed_seconds(world: &World) -> f32 {
world.resources.window.timing.uptime_milliseconds as f32 / 1000.0
}
#[cfg(feature = "gamepad")]
pub use nightshade::prelude::gilrs::Button as GamepadButton;
#[cfg(feature = "gamepad")]
pub use nightshade::prelude::gilrs::Axis as GamepadAxis;
#[cfg(feature = "gamepad")]
pub fn gamepad_button_down(world: &mut World, button: GamepadButton) -> bool {
query_active_gamepad(world).is_some_and(|gamepad| gamepad.is_pressed(button))
}
#[cfg(feature = "gamepad")]
pub fn gamepad_button_pressed(world: &World, button: GamepadButton) -> bool {
world.resources.input.gamepad.just_pressed(button)
}
#[cfg(feature = "gamepad")]
pub fn gamepad_axis(world: &mut World, axis: GamepadAxis) -> f32 {
query_active_gamepad(world)
.map(|gamepad| gamepad.value(axis))
.unwrap_or(0.0)
}
#[cfg(feature = "gamepad")]
pub fn gamepad_left_stick(world: &mut World) -> Vec2 {
Vec2::new(
gamepad_axis(world, GamepadAxis::LeftStickX),
gamepad_axis(world, GamepadAxis::LeftStickY),
)
}
#[cfg(feature = "gamepad")]
pub fn gamepad_right_stick(world: &mut World) -> Vec2 {
Vec2::new(
gamepad_axis(world, GamepadAxis::RightStickX),
gamepad_axis(world, GamepadAxis::RightStickY),
)
}
#[cfg(feature = "gamepad")]
pub fn gamepad_connected(world: &mut World) -> bool {
query_active_gamepad(world).is_some()
}
#[cfg(feature = "gamepad")]
pub(crate) fn gamepad_button_from_name(name: &str) -> Option<GamepadButton> {
Some(match name.to_ascii_lowercase().as_str() {
"south" | "a" | "cross" => GamepadButton::South,
"east" | "b" | "circle" => GamepadButton::East,
"west" | "x" | "square" => GamepadButton::West,
"north" | "y" | "triangle" => GamepadButton::North,
"left_shoulder" | "lb" => GamepadButton::LeftTrigger,
"right_shoulder" | "rb" => GamepadButton::RightTrigger,
"left_trigger" | "lt" => GamepadButton::LeftTrigger2,
"right_trigger" | "rt" => GamepadButton::RightTrigger2,
"select" | "back" => GamepadButton::Select,
"start" => GamepadButton::Start,
"mode" | "guide" => GamepadButton::Mode,
"left_thumb" | "l3" => GamepadButton::LeftThumb,
"right_thumb" | "r3" => GamepadButton::RightThumb,
"dpad_up" => GamepadButton::DPadUp,
"dpad_down" => GamepadButton::DPadDown,
"dpad_left" => GamepadButton::DPadLeft,
"dpad_right" => GamepadButton::DPadRight,
_ => return None,
})
}
#[cfg(feature = "gamepad")]
pub(crate) fn gamepad_axis_from_name(name: &str) -> Option<GamepadAxis> {
Some(match name.to_ascii_lowercase().as_str() {
"left_x" => GamepadAxis::LeftStickX,
"left_y" => GamepadAxis::LeftStickY,
"right_x" => GamepadAxis::RightStickX,
"right_y" => GamepadAxis::RightStickY,
"left_z" => GamepadAxis::LeftZ,
"right_z" => GamepadAxis::RightZ,
_ => return None,
})
}