Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting "pointabilities" for Lua raycasts #14390

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 13 additions & 10 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6202,13 +6202,16 @@ Environment access
* Returns the position of the blocking node when `false`
* `pos1`: First position
* `pos2`: Second position
* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast`
* `minetest.raycast(pos1, pos2, objects, liquids, pointabilities)`: returns `Raycast`
* Creates a `Raycast` object.
* `pos1`: start of the ray
* `pos2`: end of the ray
* `objects`: if false, only nodes will be returned. Default is `true`.
* `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be
returned. Default is `false`.
* `pointabilities`: Allows overriding the `pointable` property of
nodes and objects. Uses the same format as the `pointabilities` property
of item definitions. Default is `nil`.
* `minetest.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)`
* returns table containing path that can be walked on
* returns a table of 3D points representing a path from `pos1` to `pos2` or
Expand Down Expand Up @@ -8932,16 +8935,16 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
-- even those for which `pointable = false`

pointabilities = {
nodes = {
["default:stone"] = "blocking",
["group:leaves"] = false,
},
objects = {
["modname:entityname"] = true,
["group:ghosty"] = true, -- (an armor group)
}
nodes = {
["default:stone"] = "blocking",
["group:leaves"] = false,
},
objects = {
["modname:entityname"] = true,
["group:ghosty"] = true, -- (an armor group)
},
},
-- Contains lists to override the `pointable` property of pointed nodes and objects.
-- Contains lists to override the `pointable` property of nodes and objects.
-- The index can be a node/entity name or a group with the prefix `"group:"`.
-- (For objects `armor_groups` are used and for players the entity name is irrelevant.)
-- If multiple fields fit, the following priority order is applied:
Expand Down
1 change: 1 addition & 0 deletions games/devtest/mods/unittests/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ dofile(modpath .. "/get_version.lua")
dofile(modpath .. "/itemstack_equals.lua")
dofile(modpath .. "/content_ids.lua")
dofile(modpath .. "/metadata.lua")
dofile(modpath .. "/raycast.lua")

--------------

Expand Down
36 changes: 36 additions & 0 deletions games/devtest/mods/unittests/raycast.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
local function raycast_with_pointabilities(start_pos, end_pos, pointabilities)
local ray = core.raycast(start_pos, end_pos, nil, nil, pointabilities)
for hit in ray do
if hit.type == "node" then
return hit.under
end
end
return nil
end

local function test_raycast_pointabilities(player, pos1)
local pos2 = pos1:offset(0, 0, 1)
local pos3 = pos1:offset(0, 0, 2)

local oldnode1 = core.get_node(pos1)
local oldnode2 = core.get_node(pos2)
local oldnode3 = core.get_node(pos3)
core.swap_node(pos1, {name = "air"})
core.swap_node(pos2, {name = "testnodes:not_pointable"})
core.swap_node(pos3, {name = "testnodes:pointable"})

local p = nil
assert(raycast_with_pointabilities(pos1, pos3, p) == pos3)

p = core.registered_items["testtools:blocked_pointing_staff"].pointabilities
assert(raycast_with_pointabilities(pos1, pos3, p) == nil)

p = core.registered_items["testtools:ultimate_pointing_staff"].pointabilities
assert(raycast_with_pointabilities(pos1, pos3, p) == pos2)

core.swap_node(pos1, oldnode1)
core.swap_node(pos2, oldnode2)
core.swap_node(pos3, oldnode3)
end

unittests.register("test_raycast_pointabilities", test_raycast_pointabilities, {map=true})
6 changes: 5 additions & 1 deletion src/script/lua_api/l_env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ int LuaRaycast::create_object(lua_State *L)

bool objects = true;
bool liquids = false;
std::optional<Pointabilities> pointabilities = std::nullopt;

v3f pos1 = checkFloatPos(L, 1);
v3f pos2 = checkFloatPos(L, 2);
Expand All @@ -186,9 +187,12 @@ int LuaRaycast::create_object(lua_State *L)
if (lua_isboolean(L, 4)) {
liquids = readParam<bool>(L, 4);
}
if (lua_istable(L, 5)) {
pointabilities = read_pointabilities(L, 5);
}

LuaRaycast *o = new LuaRaycast(core::line3d<f32>(pos1, pos2),
objects, liquids, std::nullopt);
objects, liquids, pointabilities);

*(void **) (lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className);
Expand Down