add world.raycast

This commit is contained in:
MihailRis 2026-07-16 21:52:32 +03:00
parent baa952a172
commit ad6b72f87c
2 changed files with 78 additions and 59 deletions

View file

@ -312,6 +312,8 @@ entities.get_all = function(uids)
return stdcomp.get_all(uids) return stdcomp.get_all(uids)
end end
end end
world.raycast = entities.__world_raycast
entities.__world_raycast = nil
__vc_scripts_registry = require "core:internal/scripts_registry" __vc_scripts_registry = require "core:internal/scripts_registry"

View file

@ -197,7 +197,8 @@ static int l_raycast(
const glm::vec3& dir, const glm::vec3& dir,
float maxDistance, float maxDistance,
const blocks_agent::RaycastSettings& voxelRaycast, const blocks_agent::RaycastSettings& voxelRaycast,
const Entities::RaycastSettings& entityRaycast const Entities::RaycastSettings& entityRaycast,
bool entities
) { ) {
glm::vec3 end; glm::vec3 end;
glm::ivec3 normal; glm::ivec3 normal;
@ -218,7 +219,10 @@ static int l_raycast(
maxDistance = glm::distance(start, end); maxDistance = glm::distance(start, end);
block = voxel->id; block = voxel->id;
} }
auto ray = level->entities->rayCast(start, dir, maxDistance, entityRaycast); auto ray =
entities
? level->entities->rayCast(start, dir, maxDistance, entityRaycast)
: std::nullopt;
return l_push_ray(L, ray, block, start, dir, end, iend, normal); return l_push_ray(L, ray, block, start, dir, end, iend, normal);
} }
@ -248,7 +252,7 @@ static void load_entities_filter(lua::State* L, int idx, std::set<entitydefid_t>
} }
} }
static int l_raycast(lua::State* L) { static int l_world_raycast(lua::State* L) {
blocks_agent::RaycastSettings blocksRaycast {}; blocks_agent::RaycastSettings blocksRaycast {};
Entities::RaycastSettings entityRaycast {}; Entities::RaycastSettings entityRaycast {};
@ -257,9 +261,8 @@ static int l_raycast(lua::State* L) {
glm::vec3 start, dir; glm::vec3 start, dir;
float maxDistance; float maxDistance;
bool entities = true;
const int luaStackSize = lua::gettop(L);
if (luaStackSize == 1) {
if (!lua::istable(L, 1)) { if (!lua::istable(L, 1)) {
throw std::runtime_error("invalid function overload"); throw std::runtime_error("invalid function overload");
} }
@ -275,12 +278,18 @@ static int l_raycast(lua::State* L) {
lua::pop(L, 3); lua::pop(L, 3);
if (lua::getfield(L, "entities", 1)) {
entities = lua::toboolean(L, -1);
lua::pop(L);
}
if (lua::getfield(L, "ignore_uid", 1)) { if (lua::getfield(L, "ignore_uid", 1)) {
entityRaycast.ignoredUid = lua::tointeger(L, -1); entityRaycast.ignoredUid = lua::tointeger(L, -1);
lua::pop(L); lua::pop(L);
} }
if (lua::getfield(L, "ignore_entities")) { if (lua::getfield(L, "ignore_entities")) {
load_entities_filter(L, -1, filteredEntities); load_entities_filter(L, -1, filteredEntities);
blocksRaycast.filter = &filteredEntities;
lua::pop(L); lua::pop(L);
} }
if (lua::getfield(L, "entities_exclusion")) { if (lua::getfield(L, "entities_exclusion")) {
@ -289,21 +298,33 @@ static int l_raycast(lua::State* L) {
} }
if (lua::getfield(L, "filter_blocks", 1)) { if (lua::getfield(L, "filter_blocks", 1)) {
load_blocks_filter(L, -1, filteredBlocks); load_blocks_filter(L, -1, filteredBlocks);
blocksRaycast.filter = &filteredBlocks;
lua::pop(L); lua::pop(L);
} }
if (lua::getfield(L, "nonselect_blocks", 1)) { if (lua::getfield(L, "nonselect_blocks", 1)) {
blocksRaycast.includeNonSelectable = lua::toboolean(L, -1); blocksRaycast.includeNonSelectable = lua::toboolean(L, -1);
lua::pop(L); lua::pop(L);
} }
} else { return l_raycast(
start = lua::tovec<3>(L, 1); L, start, dir, maxDistance, blocksRaycast, entityRaycast, entities
dir = lua::tovec<3>(L, 2); );
maxDistance = lua::tonumber(L, 3); }
static int l_raycast(lua::State* L) {
blocks_agent::RaycastSettings blocksRaycast {};
Entities::RaycastSettings entityRaycast {};
std::set<blockid_t> filteredBlocks {};
const int luaStackSize = lua::gettop(L);
glm::vec3 start = lua::tovec<3>(L, 1);
glm::vec3 dir = lua::tovec<3>(L, 2);
float maxDistance = lua::tonumber(L, 3);
entityRaycast.ignoredUid = lua::tointeger(L, 4); entityRaycast.ignoredUid = lua::tointeger(L, 4);
if (luaStackSize >= 6) { if (luaStackSize >= 6) {
if (lua::istable(L, 6)) { if (lua::istable(L, 6)) {
load_blocks_filter(L, 6, filteredBlocks); load_blocks_filter(L, 6, filteredBlocks);
blocksRaycast.filter = &filteredBlocks;
} else { } else {
throw std::runtime_error("table expected for filter"); throw std::runtime_error("table expected for filter");
} }
@ -311,14 +332,9 @@ static int l_raycast(lua::State* L) {
if (luaStackSize >= 7) { if (luaStackSize >= 7) {
blocksRaycast.includeNonSelectable = lua::toboolean(L, 6); blocksRaycast.includeNonSelectable = lua::toboolean(L, 6);
} }
} return l_raycast(
if (!filteredBlocks.empty()) { L, start, dir, maxDistance, blocksRaycast, entityRaycast, true
blocksRaycast.filter = &filteredBlocks; );
}
if (!filteredEntities.empty()) {
blocksRaycast.filter = &filteredEntities;
}
return l_raycast(L, start, dir, maxDistance, blocksRaycast, entityRaycast);
} }
static int l_reload_component(lua::State* L) { static int l_reload_component(lua::State* L) {
@ -355,6 +371,7 @@ const luaL_Reg entitylib[] = {
{"get_all_in_box", lua::wrap<l_get_all_in_box>}, {"get_all_in_box", lua::wrap<l_get_all_in_box>},
{"get_all_in_radius", lua::wrap<l_get_all_in_radius>}, {"get_all_in_radius", lua::wrap<l_get_all_in_radius>},
{"raycast", lua::wrap<l_raycast>}, {"raycast", lua::wrap<l_raycast>},
{"__world_raycast", lua::wrap<l_world_raycast>},
{"reload_component", lua::wrap<l_reload_component>}, {"reload_component", lua::wrap<l_reload_component>},
{nullptr, nullptr} {nullptr, nullptr}
}; };