From dfb83f6835de486e4c2b621cd9bcccefdf0e7436 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 10 Aug 2025 22:55:34 +0300 Subject: [PATCH] add core:mob component & move player movement to scripting --- res/content/base/entities/player.json | 6 ++ res/scripts/components/mob.lua | 116 ++++++++++++++++++++++++++ src/logic/PlayerController.cpp | 5 -- src/logic/PlayerController.hpp | 1 - src/objects/Entities.cpp | 4 +- src/objects/Player.cpp | 82 ------------------ src/objects/Player.hpp | 4 - src/physics/Hitbox.cpp | 3 +- src/physics/Hitbox.hpp | 3 +- src/physics/PhysicsSolver.cpp | 8 +- 10 files changed, 132 insertions(+), 100 deletions(-) create mode 100644 res/scripts/components/mob.lua diff --git a/res/content/base/entities/player.json b/res/content/base/entities/player.json index b20a7aed..d3d5712c 100644 --- a/res/content/base/entities/player.json +++ b/res/content/base/entities/player.json @@ -1,5 +1,11 @@ { "components": [ + { + "name": "core:mob", + "args": { + "jump_force": 8.0 + } + }, "base:player_animator" ], "hitbox": [0.6, 1.8, 0.6] diff --git a/res/scripts/components/mob.lua b/res/scripts/components/mob.lua new file mode 100644 index 00000000..e3909da1 --- /dev/null +++ b/res/scripts/components/mob.lua @@ -0,0 +1,116 @@ +local body = entity.rigidbody + +local jump_force = SAVED_DATA.jump_force or ARGS.jump_force or 0.0 +local air_damping = SAVED_DATA.air_damping or ARGS.air_damping or 1.0 +local ground_damping = SAVED_DATA.ground_damping or ARGS.ground_damping or 1.0 +local movement_speed = SAVED_DATA.movement_speed or ARGS.movement_speed or 4.0 +local run_speed_mul = SAVED_DATA.run_speed_mul or ARGS.run_speed_mul or 1.5 +local crouch_speed_mul = SAVED_DATA.crouch_speed_mul or ARGS.crouch_speed_mul or 0.35 +local flight_speed_mul = SAVED_DATA.flight_speed_mul or ARGS.flight_speed_mul or 4.0 +local cheat_speed_mul = SAVED_DATA.cheat_speed_mul or ARGS.cheat_speed_mul or 5.0 + +function jump(multiplier) + if body:is_grounded() then + local vel = body:get_vel() + body:set_vel( + vec3.add(vel, {0, jump_force * (multiplier or 1.0), 0}, vel)) + end +end + +function elevate(speed, delta, vel) + vel = vel or body:get_vel() + body:set_vel( + vec3.add(vel, {0, speed * delta, 0}, vel)) +end + +function lower(speed, delta, vel) + vel = vel or body:get_vel() + body:set_vel( + vec3.add(vel, {0, -speed * delta, 0}, vel)) +end + +function move_horizontal(speed, dir, vel) + vel = vel or body:get_vel() + if vec3.length(dir) > 0.0 then + vec3.normalize(dir, dir) + + vel[1] = dir[1] * speed + vel[3] = dir[3] * speed + end + body:set_vel(vel) +end + +function on_update(tps) + local delta = (1.0 / tps) + local pid = entity:get_player() + if pid then + -- todo: replace with entity direction + local cam = cameras.get("core:first-person") + local front = cam:get_front() + local right = cam:get_right() + front[2] = 0.0 + vec3.normalize(front, front) + + local grounded = body:is_grounded() + + local isjump = input.is_active('movement.jump') + local issprint = input.is_active('movement.sprint') + local iscrouch = input.is_active('movement.crouch') + local isforward = input.is_active('movement.forward') + local ischeat = input.is_active('movement.cheat') + local isback = input.is_active('movement.back') + local isleft = input.is_active('movement.left') + local isright = input.is_active('movement.right') + local flight = player.is_flight(pid) + local noclip = player.is_noclip(pid) + + local vel = body:get_vel() + + local speed = movement_speed + + if flight then + speed = speed * flight_speed_mul + elseif issprint then + speed = speed * run_speed_mul + elseif iscrouch and grounded then + speed = speed * crouch_speed_mul + end + body:set_crouching(iscrouch) + + if ischeat then + speed = speed * cheat_speed_mul + end + + local dir = {0, 0, 0} + if isforward then + vec3.add(dir, front, dir) + end + if isback then + vec3.sub(dir, front, dir) + end + if isright then + vec3.add(dir, right, dir) + end + if isleft then + vec3.sub(dir, right, dir) + end + + if vec3.length(dir) > 0.0 then + move_horizontal(speed, dir, vel) + end + + if flight then + if isjump then + elevate(speed * 8.0, delta) + elseif iscrouch then + lower(speed * 8.0, delta) + end + elseif isjump then + jump() + end + body:set_vdamping(flight) + body:set_gravity_scale(flight and 0.0 or 1.0) + body:set_linear_damping((flight or not grounded) and air_damping or ground_damping) + body:set_body_type(noclip and "kinematic" or "dynamic") + end +end diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index f5fdea1b..8021db51 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -271,7 +271,6 @@ void PlayerController::update(float delta, const Input* inputEvents) { } else { resetKeyboard(); } - updatePlayer(delta); } void PlayerController::postUpdate( @@ -313,10 +312,6 @@ void PlayerController::resetKeyboard() { input = {}; } -void PlayerController::updatePlayer(float delta) { - player.updateInput(input, delta); -} - static int determine_rotation( const Block* def, const glm::ivec3& norm, const glm::vec3& camDir ) { diff --git a/src/logic/PlayerController.hpp b/src/logic/PlayerController.hpp index cd49642c..7f895ee3 100644 --- a/src/logic/PlayerController.hpp +++ b/src/logic/PlayerController.hpp @@ -60,7 +60,6 @@ class PlayerController { void updateKeyboard(const Input& inputEvents); void resetKeyboard(); - void updatePlayer(float delta); void updateEntityInteraction(entityid_t eid, bool lclick, bool rclick); void updateInteraction(const Input& inputEvents, float delta); diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 8dcdecd4..2353dc1b 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -297,7 +297,9 @@ void Entities::updatePhysics(float delta) { int substeps = static_cast(delta * vel * 20); substeps = std::min(100, std::max(2, substeps)); physics->step(*level.chunks, hitbox, delta, substeps, eid.uid); - hitbox.linearDamping = hitbox.grounded * 24; + hitbox.friction = glm::abs(hitbox.gravityScale <= 1e-7f) + ? 8.0f + : (!grounded ? 2.0f : 10.0f); transform.setPos(hitbox.position); if (hitbox.grounded && !grounded) { scripting::on_entity_grounded( diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index befdd0b3..2c2fbe24 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -21,13 +21,6 @@ static debug::Logger logger("player"); -constexpr float CROUCH_SPEED_MUL = 0.35f; -constexpr float RUN_SPEED_MUL = 1.5f; -constexpr float PLAYER_GROUND_DAMPING = 10.0f; -constexpr float PLAYER_AIR_DAMPING = 8.0f; -constexpr float FLIGHT_SPEED_MUL = 4.0f; -constexpr float CHEAT_SPEED_MUL = 5.0f; -constexpr float JUMP_FORCE = 8.0f; constexpr int SPAWN_ATTEMPTS_PER_UPDATE = 64; Player::Player( @@ -82,17 +75,6 @@ void Player::updateEntity() { "will be respawned"; eid = ENTITY_AUTO; } - auto hitbox = getHitbox(); - if (hitbox == nullptr) { - return; - } - hitbox->linearDamping = PLAYER_GROUND_DAMPING; - hitbox->verticalDamping = flight; - hitbox->gravityScale = flight ? 0.0f : 1.0f; - if (flight || !hitbox->grounded) { - hitbox->linearDamping = PLAYER_AIR_DAMPING; - } - hitbox->type = noclip ? BodyType::KINEMATIC : BodyType::DYNAMIC; } Hitbox* Player::getHitbox() { @@ -102,70 +84,6 @@ Hitbox* Player::getHitbox() { return nullptr; } -void Player::updateInput(PlayerInput& input, float delta) { - auto hitbox = getHitbox(); - if (hitbox == nullptr) { - return; - } - bool crouch = input.shift && hitbox->grounded && !input.sprint; - float speed = this->speed; - if (flight) { - speed *= FLIGHT_SPEED_MUL; - } - if (input.cheat) { - speed *= CHEAT_SPEED_MUL; - } - - hitbox->crouching = crouch; - if (crouch) { - speed *= CROUCH_SPEED_MUL; - } else if (input.sprint) { - speed *= RUN_SPEED_MUL; - } - - glm::vec3 dir(0, 0, 0); - if (input.moveForward) { - dir += fpCamera->dir; - } - if (input.moveBack) { - dir -= fpCamera->dir; - } - if (input.moveRight) { - dir += fpCamera->right; - } - if (input.moveLeft) { - dir -= fpCamera->right; - } - if (glm::length(dir) > 0.0f) { - dir = glm::normalize(dir); - doMove(dir, speed, delta); - } - if (flight) { - if (input.jump) { - hitbox->velocity.y += speed * delta * 9; - } - if (input.shift) { - hitbox->velocity.y -= speed * delta * 9; - } - } else if (input.jump) { - doJump(); - } -} - -void Player::doMove(const glm::vec3& dir, float speed, float delta) { - if (auto hitbox = getHitbox()) { - hitbox->velocity += dir * speed * delta * 9.0f; - } -} - -void Player::doJump() { - if (auto hitbox = getHitbox()) { - if (hitbox->grounded) { - hitbox->velocity.y = JUMP_FORCE; - } - } -} - void Player::updateSelectedEntity() { selectedEid = selection.entity; } diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index 2da8ee1d..b9999c78 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -59,9 +59,6 @@ class Player : public Serializable { entityid_t eid = ENTITY_AUTO; entityid_t selectedEid = 0; - void doMove(const glm::vec3& dir, float speed, float delta); - void doJump(); - glm::vec3 rotation {}; public: util::VecInterpolation<3, float, true> rotationInterpolation {true}; @@ -85,7 +82,6 @@ public: void teleport(glm::vec3 position); void updateEntity(); - void updateInput(PlayerInput& input, float delta); void updateSelectedEntity(); void postUpdate(); diff --git a/src/physics/Hitbox.cpp b/src/physics/Hitbox.cpp index 83ad823c..adf07841 100644 --- a/src/physics/Hitbox.cpp +++ b/src/physics/Hitbox.cpp @@ -6,6 +6,5 @@ Hitbox::Hitbox(BodyType type, glm::vec3 position, glm::vec3 halfsize) : type(type), position(position), halfsize(halfsize), - velocity(0.0f,0.0f,0.0f), - linearDamping(0.1f) + velocity(0.0f,0.0f,0.0f) {} diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index e825cefe..2285a632 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -52,7 +52,8 @@ struct Hitbox { glm::vec3 position; glm::vec3 halfsize; glm::vec3 velocity; - float linearDamping; + float linearDamping = 0.5; + float friction = 1.0f; bool verticalDamping = false; bool grounded = false; float gravityScale = 1.0f; diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 62a6abd6..0d1cb4a0 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -25,7 +25,7 @@ void PhysicsSolver::step( entityid_t entity ) { float dt = delta / static_cast(substeps); - float linearDamping = hitbox.linearDamping; + float linearDamping = hitbox.linearDamping * hitbox.friction; float s = 2.0f/BLOCK_AABB_GRID; const glm::vec3& half = hitbox.halfsize; @@ -45,11 +45,11 @@ void PhysicsSolver::step( colisionCalc(chunks, hitbox, vel, pos, half, (prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f); } - vel.x *= glm::max(0.0f, 1.0f - dt * linearDamping); + vel.x /= 1.0f + dt * linearDamping; + vel.z /= 1.0f + dt * linearDamping; if (hitbox.verticalDamping) { - vel.y *= glm::max(0.0f, 1.0f - dt * linearDamping); + vel.y /= 1.0f + dt * linearDamping; } - vel.z *= glm::max(0.0f, 1.0f - dt * linearDamping); pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f; if (hitbox.grounded && pos.y < py) {