add new players finding functions

This commit is contained in:
MihailRis 2025-10-16 20:43:03 +03:00
parent 2210ba8218
commit 9cb9b095e8
3 changed files with 86 additions and 0 deletions

View File

@ -322,6 +322,38 @@ static int l_set_suspended(lua::State* L) {
return 0;
}
static int l_get_all_in_radius(lua::State* L) {
auto center = lua::tovec3(L, 1);
auto radius = static_cast<float>(lua::tonumber(L, 2));
auto players = level->players->getAllInRadius(center, radius);
lua::createtable(L, players.size(), 0);
for (size_t i = 0; i < players.size(); i++) {
lua::pushinteger(L, players[i]->getId());
lua::rawseti(L, i + 1);
}
return 1;
}
static int l_get_all(lua::State* L) {
auto players = level->players->getAll();
lua::createtable(L, players.size(), 0);
for (size_t i = 0; i < players.size(); i++) {
lua::pushinteger(L, players[i]->getId());
lua::rawseti(L, i + 1);
}
return 1;
}
static int l_get_nearest(lua::State* L) {
auto position = lua::tovec3(L, 1);
if (auto player = level->players->getNearest(position)) {
lua::pushinteger(L, player->getId());
return 1;
}
return 0;
}
const luaL_Reg playerlib[] = {
{"get_pos", lua::wrap<l_get_pos>},
{"set_pos", lua::wrap<l_set_pos>},
@ -358,5 +390,8 @@ const luaL_Reg playerlib[] = {
{"set_name", lua::wrap<l_set_name>},
{"create", lua::wrap<l_create>},
{"delete", lua::wrap<l_delete>},
{"get_all_in_radius", lua::wrap<l_get_all_in_radius>},
{"get_all", lua::wrap<l_get_all>},
{"get_nearest", lua::wrap<l_get_nearest>},
{nullptr, nullptr}
};

View File

@ -1,5 +1,8 @@
#include "Players.hpp"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/norm.hpp>
#include "Player.hpp"
#include "items/Inventories.hpp"
#include "world/Level.hpp"
@ -20,6 +23,48 @@ Player* Players::get(int64_t id) const {
return found->second.get();
}
std::vector<Player*> Players::getAllInRadius(
const glm::vec3& center, float radius
) const {
std::vector<Player*> foundPlayers;
for (const auto& pair : players) {
auto player = pair.second.get();
auto relativePos = player->getPosition() - center;
if (!player->isSuspended() && glm::length2(relativePos) <= radius) {
foundPlayers.emplace_back(player);
}
}
return foundPlayers;
}
std::vector<Player*> Players::getAll() const {
std::vector<Player*> allPlayers;
allPlayers.reserve(players.size());
for (const auto& pair : players) {
allPlayers.emplace_back(pair.second.get());
}
return allPlayers;
}
Player* Players::getNearest(const glm::vec3& position) const {
Player* nearest = nullptr;
float nearestDist2 = std::numeric_limits<float>::max();
for (const auto& pair : players) {
auto player = pair.second.get();
if (player->isSuspended()) {
continue;
}
auto relativePos = player->getPosition() - position;
auto dist2 = glm::length2(relativePos);
if (dist2 < nearestDist2) {
nearestDist2 = dist2;
nearest = player;
}
}
return nearest;
}
Player* Players::create(int64_t id) {
int64_t& nextPlayerID = level.getWorld()->getInfo().nextPlayerId;
if (id == NONE) {

View File

@ -1,7 +1,9 @@
#pragma once
#include <memory>
#include <vector>
#include <unordered_map>
#include <glm/vec3.hpp>
#include "typedefs.hpp"
#include "interfaces/Serializable.hpp"
@ -34,6 +36,10 @@ public:
void remove(int64_t id);
std::vector<Player*> getAllInRadius(const glm::vec3& center, float radius) const;
std::vector<Player*> getAll() const;
Player* getNearest(const glm::vec3& position) const;
dv::value serialize() const override;
void deserialize(const dv::value& src) override;