diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index 47a6384d..422807c6 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -66,6 +66,9 @@ LevelController::LevelController( void LevelController::update(float delta, bool pause) { for (const auto& [_, player] : *level->players) { + if (player->isSuspended()) { + continue; + } glm::vec3 position = player->getPosition(); player->chunks->configure( position.x, @@ -85,6 +88,9 @@ void LevelController::update(float delta, bool pause) { level->entities->updatePhysics(delta); level->entities->update(delta); for (const auto& [_, player] : *level->players) { + if (player->isSuspended()) { + continue; + } if (playerTickClock.update(delta)) { if (player->getId() % playerTickClock.getParts() == playerTickClock.getPart()) { diff --git a/src/logic/scripting/lua/libs/libplayer.cpp b/src/logic/scripting/lua/libs/libplayer.cpp index af908aea..5979d0f6 100644 --- a/src/logic/scripting/lua/libs/libplayer.cpp +++ b/src/logic/scripting/lua/libs/libplayer.cpp @@ -284,6 +284,20 @@ static int l_delete(lua::State* L) { return 0; } +static int l_is_suspended(lua::State* L) { + if (auto player = get_player(L, 1)) { + return lua::pushboolean(L, player->isSuspended()); + } + return 0; +} + +static int l_set_suspended(lua::State* L) { + if (auto player = get_player(L, 1)) { + player->setSuspended(lua::toboolean(L, 2)); + } + return 0; +} + const luaL_Reg playerlib[] = { {"get_pos", lua::wrap}, {"set_pos", lua::wrap}, @@ -293,6 +307,8 @@ const luaL_Reg playerlib[] = { {"set_rot", lua::wrap}, {"get_dir", lua::wrap}, {"get_inventory", lua::wrap}, + {"is_suspended", lua::wrap}, + {"set_suspended", lua::wrap}, {"is_flight", lua::wrap}, {"set_flight", lua::wrap}, {"is_noclip", lua::wrap}, diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index f80fffa7..e0a4a49e 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -224,6 +224,14 @@ float Player::getSpeed() const { return speed; } +bool Player::isSuspended() const { + return suspended; +} + +void Player::setSuspended(bool flag) { + suspended = flag; +} + bool Player::isFlight() const { return flight; } diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index 1e87e2a7..8caf7a63 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -47,6 +47,7 @@ class Player : public Serializable { glm::vec3 position; glm::vec3 spawnpoint {}; std::shared_ptr inventory; + bool suspended = false; bool flight = false; bool noclip = false; bool infiniteItems = true; @@ -85,6 +86,9 @@ public: int getChosenSlot() const; float getSpeed() const; + bool isSuspended() const; + void setSuspended(bool flag); + bool isFlight() const; void setFlight(bool flag); diff --git a/src/objects/Players.cpp b/src/objects/Players.cpp index 1a683a34..edd74274 100644 --- a/src/objects/Players.cpp +++ b/src/objects/Players.cpp @@ -4,6 +4,7 @@ #include "items/Inventories.hpp" #include "world/Level.hpp" #include "world/World.hpp" +#include "objects/Entities.hpp" Players::Players(Level& level) : level(level) {} @@ -36,6 +37,26 @@ Player* Players::create() { return player; } +void Players::suspend(int64_t id) { + if (auto player = get(id)) { + if (player->isSuspended()) { + return; + } + player->setSuspended(true); + level.entities->despawn(player->getEntity()); + player->setEntity(0); + } +} + +void Players::resume(int64_t id) { + if (auto player = get(id)) { + if (!player->isSuspended()) { + return; + } + player->setSuspended(false); + } +} + void Players::remove(int64_t id) { players.erase(id); } diff --git a/src/objects/Players.hpp b/src/objects/Players.hpp index 74f5c565..74146ade 100644 --- a/src/objects/Players.hpp +++ b/src/objects/Players.hpp @@ -25,6 +25,10 @@ public: Player* create(); + void suspend(int64_t id); + + void resume(int64_t id); + void remove(int64_t id); dv::value serialize() const override;