summary refs log tree commit diff
path: root/src/Entities
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2024-02-15 11:33:11 +0100
committerMel <einebeere@gmail.com>2024-02-15 11:34:28 +0100
commit92f63bbdbfc214849c203511bbcb1be0a4865588 (patch)
treed82e1b31e583b5cc9538f61cad696dab5dbd84dc /src/Entities
parent87ef308220addbe4406006ceb802a7364e6f1a05 (diff)
downloadmeowcraft-92f63bbdbfc214849c203511bbcb1be0a4865588.tar.zst
meowcraft-92f63bbdbfc214849c203511bbcb1be0a4865588.zip
Proper input system
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/Player.cpp64
-rw-r--r--src/Entities/Player.hpp27
2 files changed, 46 insertions, 45 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 7a1c1af..83c3f5e 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1,13 +1,13 @@
 #include "Player.hpp"
-#include "../Common/Casts.hpp"
+#include "../Input.hpp"
 #include <unordered_set>
 
 namespace MC::Entities {
 
-void Player::update(const Time& time, GFX::Window& window, GFX::Camera& camera, World::World& world) {
-    auto const input_direction = directional_input(window);
+void Player::update(Time const& time, Input const& input, GFX::Camera& camera, World::World& world) {
+    auto const input_direction = directional_input(input);
 
-    auto destination = movement(window, time, input_direction);
+    auto destination = movement(time, input_direction);
 
     if (can_collide()) {
         if (m_velocity.y() < 0.0)
@@ -25,12 +25,12 @@ void Player::update(const Time& time, GFX::Window& window, GFX::Camera& camera,
     }
 
     move_to(destination);
-    rotate(rotational_input(window));
+    rotate(rotational_input(input));
 
     update_camera_position(camera);
 
     update_targeted_block(world);
-    actions(window, world);
+    actions(input, world);
 }
 
 void Player::render(GFX::Actions& actions) {
@@ -72,17 +72,17 @@ Bool Player::can_collide() const {
     return m_movement != MovementMode::NoClip;
 }
 
-Position::World Player::movement(GFX::Window& window, const Time& time, Vec3 input_direction) {
+Position::World Player::movement(Time const& time, Vec3 input_direction) {
     switch (m_movement) {
-        case MovementMode::Walking: m_velocity = walking_velocity(window, time, input_direction); break;
-        case MovementMode::Flying: m_velocity = flying_velocity(window, time, input_direction); break;
-        case MovementMode::NoClip: m_velocity = noclip_velocity(window, time, input_direction); break;
+        case MovementMode::Walking: m_velocity = walking_velocity(time, input_direction); break;
+        case MovementMode::Flying: m_velocity = flying_velocity(time, input_direction); break;
+        case MovementMode::NoClip: m_velocity = noclip_velocity(time, input_direction); break;
     }
 
     return m_transform.position() + m_velocity;
 }
 
-Vec3 Player::walking_velocity(GFX::Window& window, const Time& time, Vec3 input_direction) {
+Vec3 Player::walking_velocity(Time const& time, Vec3 input_direction) {
     constexpr auto base_move_speed = 8.0;
     constexpr auto initial_jump_velocity = 0.16;
     constexpr auto gravity = 0.6;
@@ -109,7 +109,7 @@ Vec3 Player::walking_velocity(GFX::Window& window, const Time& time, Vec3 input_
     };
 }
 
-Vec3 Player::flying_velocity(GFX::Window& window, const Time& time, Vec3 input_direction) {
+Vec3 Player::flying_velocity(Time const& time, Vec3 input_direction) const {
     constexpr auto base_move_speed = 10.0;
 
     auto flying_direction = m_transform.right() * input_direction.x() + m_transform.forward() * input_direction.z();
@@ -126,15 +126,13 @@ Vec3 Player::flying_velocity(GFX::Window& window, const Time& time, Vec3 input_d
     };
 }
 
-Vec3 Player::noclip_velocity(GFX::Window& window, const Time& time, Vec3 input_direction) {
+Vec3 Player::noclip_velocity(Time const& time, Vec3 input_direction) const {
     constexpr auto base_move_speed = 10.0;
 
-    Real const boost = TO(Real, window.key(GLFW_KEY_LEFT_CONTROL, GLFW_PRESS)) * 75.0;
-
     auto const [x, y, z] = input_direction.elements;
     auto const direction = m_transform.right() * x + Vec3(0, y, 0) + m_transform.forward() * z;
 
-    return direction * (base_move_speed + boost) * time.delta();
+    return direction * base_move_speed * time.delta();
 }
 
 void Player::update_targeted_block(World::World& world) {
@@ -152,10 +150,10 @@ void Player::update_targeted_block(World::World& world) {
     else m_targeted_block = {};
 }
 
-void Player::actions(GFX::Window& window, World::World& world) {
+void Player::actions(Input const& input, World::World& world) {
     // Breaking and placing blocks.
-    auto left_click = window.mouse(GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
-    auto right_click = window.mouse(GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS);
+    auto left_click = input.pressed(Mouse::Left);
+    auto right_click = input.pressed(Mouse::Right);
     if (left_click || right_click) {
         if (m_targeted_block.has_value()) {
             auto targeted_block = m_targeted_block.value();
@@ -173,11 +171,15 @@ void Player::actions(GFX::Window& window, World::World& world) {
     }
 
     // Toggle movement modes.
-    // TODO: Need an input system for this, can't get an event only at
-    // the moment the key is pressed, so can't toggle between modes on single press.
-    if (window.key(GLFW_KEY_1, GLFW_PRESS)) m_movement = MovementMode::Walking;
-    else if (window.key(GLFW_KEY_2, GLFW_PRESS)) m_movement = MovementMode::Flying;
-    else if (window.key(GLFW_KEY_3, GLFW_PRESS)) m_movement = MovementMode::NoClip;
+    if (input.double_pressed(Key::Space)) {
+        if (m_movement == MovementMode::Walking) m_movement = MovementMode::Flying;
+        else if (m_movement == MovementMode::Flying) m_movement = MovementMode::Walking;
+    }
+
+    if (input.pressed(Key::N)) {
+        if (m_movement == MovementMode::NoClip) m_movement = MovementMode::Walking;
+        else m_movement = MovementMode::NoClip;
+    }
 }
 
 #define STUCK_THRESHOLD 100
@@ -319,20 +321,18 @@ void Player::update_camera_position(GFX::Camera& camera) const {
     camera.set_angles(cam_transform.rotation());
 }
 
-Vec3 Player::directional_input(GFX::Window& window) {
-    auto key = [&](Int k) -> Real { return window.key(k, GLFW_PRESS); };
-
-    Real x = key(GLFW_KEY_D) - key(GLFW_KEY_A);
-    Real y = key(GLFW_KEY_SPACE) - key(GLFW_KEY_LEFT_SHIFT);
-    Real z = key(GLFW_KEY_S) - key(GLFW_KEY_W);
+Vec3 Player::directional_input(Input const& input) {
+    Real x = input.held(Key::D) - input.held(Key::A);
+    Real y = input.held(Key::Space) - input.held(Key::LeftShift);
+    Real z = input.held(Key::S) - input.held(Key::W);
 
     return {x, y, z};
 }
 
-Rotation Player::rotational_input(GFX::Window& window) {
+Rotation Player::rotational_input(Input const& input) {
     constexpr auto base_rotation_speed = 0.1f;
 
-    auto r = window.mouse_delta();
+    auto r = input.mouse_movement();
     return {r.y() * base_rotation_speed, r.x() * base_rotation_speed, 0.0f};
 }
 
diff --git a/src/Entities/Player.hpp b/src/Entities/Player.hpp
index 2b69d57..342d965 100644
--- a/src/Entities/Player.hpp
+++ b/src/Entities/Player.hpp
@@ -1,14 +1,15 @@
 #pragma once
 
+#include "../Common/Pure.hpp"
 #include "../Time.hpp"
 #include "../Transform.hpp"
 #include "../GFX/Actions.hpp"
 #include "../GFX/Camera.hpp"
 #include "../World/World.hpp"
-#include "../GFX/Window.hpp"
 #include "../Math/AABB.hpp"
 #include "../Math/Rotation.hpp"
 #include "../World/Position.hpp"
+#include "../Input.hpp"
 
 namespace MC::Entities {
 class Player {
@@ -16,9 +17,9 @@ public:
     explicit Player(Position::World position)
         : m_transform(position), m_outline_mesh(create_outline_cube_mesh()) {}
 
-    Position::World position() const { return m_transform.position(); }
+    PURE Position::World position() const { return m_transform.position(); }
 
-    void update(const Time& time, GFX::Window& window, GFX::Camera& camera, World::World& world);
+    void update(Time const& time, Input const& input, GFX::Camera& camera, World::World& world);
     void render(GFX::Actions& actions);
 
     void move(Position::WorldOffset by);
@@ -27,14 +28,14 @@ public:
     void rotate(Rotation by);
     void rotate_to(Rotation to);
 
-    AABB bounds() const;
+    PURE AABB bounds() const;
 
 private:
     struct BlockedAxis {
         Bool positive, negative;
     };
 
-    Bool can_collide() const;
+    PURE Bool can_collide() const;
 
     struct ProcessCollisionsResult {
         Position::World position;
@@ -45,19 +46,19 @@ private:
 
     Position::World rescue_from_void_on_new_chunk(Time const& time, World::World& world, Position::World position);
 
-    Position::World movement(GFX::Window& window, const Time& time, Vec3 input_direction);
-    Vec3 walking_velocity(GFX::Window& window, const Time& time, Vec3 input_direction);
-    Vec3 flying_velocity(GFX::Window& window, const Time& time, Vec3 input_direction);
-    Vec3 noclip_velocity(GFX::Window& window, const Time& time, Vec3 input_direction);
+    Position::World movement(Time const& time, Vec3 input_direction);
+    Vec3 walking_velocity(Time const& time, Vec3 input_direction);
+    PURE Vec3 flying_velocity(Time const& time, Vec3 input_direction) const;
+    PURE Vec3 noclip_velocity(Time const& time, Vec3 input_direction) const;
 
     void update_targeted_block(World::World& world);
-    void actions(GFX::Window& window, World::World& world);
+    void actions(Input const& input, World::World& world);
 
-    Transform camera_transform() const;
+    PURE Transform camera_transform() const;
     void update_camera_position(GFX::Camera& camera) const;
 
-    static Vec3 directional_input(GFX::Window& window);
-    static Rotation rotational_input(GFX::Window& window);
+    static Vec3 directional_input(Input const& input);
+    static Rotation rotational_input(Input const& input);
 
     // Creates a bounding box where `position` is at the center of the bottom face.
     static AABB bounding_box_for_position(Position::World position);