From 1eac3436191d7668aa3944d826836d4d8663821f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 17 Jul 2024 14:51:55 +0300 Subject: [PATCH] add entities.get_all(...), .get_all_in_box(...), .get_all_in_radius(...) --- doc/en/scripting/builtins/libentities.md | 16 ++++++++++++++ doc/ru/scripting/builtins/libentities.md | 16 ++++++++++++++ res/modules/internal/stdcomp.lua | 11 ++++++++++ res/scripts/stdlib.lua | 11 ++++++++++ src/logic/scripting/lua/libentity.cpp | 28 ++++++++++++++++++++++++ src/objects/Entities.cpp | 17 ++++++++++++++ src/objects/Entities.hpp | 1 + 7 files changed, 100 insertions(+) diff --git a/doc/en/scripting/builtins/libentities.md b/doc/en/scripting/builtins/libentities.md index c25f7301..2dfe2736 100644 --- a/doc/en/scripting/builtins/libentities.md +++ b/doc/en/scripting/builtins/libentities.md @@ -14,6 +14,22 @@ entities.spawn(name: str, pos: vec3, [optional] args: table) -- Checks the existence of an entity by a unique identifier. entities.exists(uid: int) -> bool + +-- Returns a table of all loaded entities +entities.get_all() -> table + +-- Returns a table of loaded entities based on the passed list of UIDs +entities.get_all(uids: array) -> table + +-- Returns a list of UIDs of entities inside the rectangular area +-- pos - minimal area corner +-- size - area size +entities.get_all_in_box(pos: vec3, size: vec3) -> array + +-- Returns a list of UIDs of entities inside the radius +-- center - center of the area +-- radius - radius of the area +entities.get_all_in_radius(center: vec3, radius: number) -> array ``` ```lua diff --git a/doc/ru/scripting/builtins/libentities.md b/doc/ru/scripting/builtins/libentities.md index 4a3e96a0..fa805797 100644 --- a/doc/ru/scripting/builtins/libentities.md +++ b/doc/ru/scripting/builtins/libentities.md @@ -14,6 +14,22 @@ entities.spawn(name: str, pos: vec3, [optional] args: table) -- Проверяет наличие сущности по уникальному идентификатору. entities.exists(uid: int) -> bool + +-- Возвращает таблицу всех загруженных сущностей +entities.get_all() -> table + +-- Возвращает таблицу загруженных сущностей по переданному списку UID +entities.get_all(uids: array) -> table + +-- Возвращает список UID сущностей, попадающих в прямоугольную область +-- pos - минимальный угол области +-- size - размер области +entities.get_all_in_box(pos: vec3, size: vec3) -> array + +-- Возвращает список UID сущностей, попадающих в радиус +-- center - центр области +-- radius - радиус области +entities.get_all_in_radius(center: vec3, radius: number) -> array ``` ```lua diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 9f9e75d6..e3f5589f 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -111,5 +111,16 @@ return { end end end + end, + get_all = function(uids) + if uids == nil then + return entities + else + local values = {} + for _, uid in ipairs(uids) do + values[uid] = entities[uid] + end + return values + end end } diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index ed5c4863..22b315d1 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -307,6 +307,17 @@ end stdcomp = require "core:internal/stdcomp" entities.get = stdcomp.get_Entity +entities.get_all = function(uids) + if uids == nil then + local values = {} + for k,v in pairs(stdcomp.get_all()) do + values[k] = v + end + return values + else + return stdcomp.get_all(uids) + end +end math.randomseed(time.uptime()*1536227939) diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 84e34d48..c2790737 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -57,6 +57,32 @@ static int l_set_skeleton(lua::State* L) { return 0; } +static int l_get_all_in_box(lua::State* L) { + auto pos = lua::tovec<3>(L, 1); + auto size = lua::tovec<3>(L, 2); + auto found = level->entities->getAllInside(AABB(pos, pos + size)); + lua::createtable(L, found.size(), 0); + for (size_t i = 0; i < found.size(); i++) { + const auto& entity = found[i]; + lua::pushinteger(L, entity.getUID()); + lua::rawseti(L, i+1); + } + return 1; +} + +static int l_get_all_in_radius(lua::State* L) { + auto pos = lua::tovec<3>(L, 1); + auto radius = lua::tonumber(L, 2); + auto found = level->entities->getAllInRadius(pos, radius); + lua::createtable(L, found.size(), 0); + for (size_t i = 0; i < found.size(); i++) { + const auto& entity = found[i]; + lua::pushinteger(L, entity.getUID()); + lua::rawseti(L, i+1); + } + return 1; +} + static int l_raycast(lua::State* L) { auto start = lua::tovec<3>(L, 1); auto dir = lua::tovec<3>(L, 2); @@ -128,6 +154,8 @@ const luaL_Reg entitylib [] = { {"despawn", lua::wrap}, {"get_skeleton", lua::wrap}, {"set_skeleton", lua::wrap}, + {"get_all_in_box", lua::wrap}, + {"get_all_in_radius", lua::wrap}, {"raycast", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 7a888293..a6c2f528 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -503,3 +503,20 @@ std::vector Entities::getAllInside(AABB aabb) { } return collected; } + +std::vector Entities::getAllInRadius(glm::vec3 center, float radius) { + std::vector collected; + auto view = registry.view(); + for (auto [entity, transform] : view.each()) { + if (glm::distance2(transform.pos, center) <= radius*radius) { + const auto& found = uids.find(entity); + if (found == uids.end()) { + continue; + } + if (auto wrapper = get(found->second)) { + collected.push_back(*wrapper); + } + } + } + return collected; +} diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index bbb847a3..8dd87813 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -210,6 +210,7 @@ public: void onSave(const Entity& entity); bool hasBlockingInside(AABB aabb); std::vector getAllInside(AABB aabb); + std::vector getAllInRadius(glm::vec3 center, float radius); void despawn(entityid_t id); dynamic::Value serialize(const Entity& entity);