From 3475759d1adbd4a64c6250fd87981f783e64f69c Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 14 Apr 2020 14:11:33 +0200 Subject: [PATCH] Expose collision information to LuaEntity on_step --- builtin/game/features.lua | 1 + doc/lua_api.txt | 25 ++++++++++++++- src/script/common/c_content.cpp | 54 +++++++++++++++++++++++++++++++++ src/script/common/c_content.h | 4 ++- src/script/cpp_api/s_entity.cpp | 12 +++++--- src/script/cpp_api/s_entity.h | 4 ++- src/server/luaentity_sao.cpp | 8 +++-- 7 files changed, 98 insertions(+), 10 deletions(-) diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 623f8183b..a15475333 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -16,6 +16,7 @@ core.features = { formspec_version_element = true, area_store_persistent_ids = true, pathfinder_works = true, + object_step_has_moveresult = true, } function core.has_feature(arg) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 3ca32649a..5e4e18b62 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4147,6 +4147,8 @@ Utilities area_store_persistent_ids = true, -- Whether minetest.find_path is functional (5.2.0) pathfinder_works = true, + -- Whether Collision info is available to an objects' on_step (5.3.0) + object_step_has_moveresult = true, } * `minetest.has_feature(arg)`: returns `boolean, missing_features` @@ -6579,7 +6581,10 @@ Used by `minetest.register_entity`. on_activate = function(self, staticdata, dtime_s), - on_step = function(self, dtime), + on_step = function(self, dtime, moveresult), + -- Called every server step + -- dtime: Elapsed time + -- moveresult: Table with collision info (only available if physical=true) on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir), @@ -6594,6 +6599,24 @@ Used by `minetest.register_entity`. -- for more info) by using a '_' prefix } +Collision info passed to `on_step`: + + { + touching_ground = boolean, + collides = boolean, + standing_on_object = boolean, + collisions = { + { + type = string, -- "node" or "object", + axis = string, -- "x", "y" or "z" + node_pos = vector, -- if type is "node" + old_speed = vector, + new_speed = vector, + }, + ... + } + } + ABM (ActiveBlockModifier) definition ------------------------------------ diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 8335fccb5..6ff642738 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common/c_types.h" #include "nodedef.h" #include "object_properties.h" +#include "collision.h" #include "cpp_api/s_node.h" #include "lua_api/l_object.h" #include "lua_api/l_item.h" @@ -2002,3 +2003,56 @@ HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value) } return stat; } + +/******************************************************************************/ + +// Indices must match values in `enum CollisionType` exactly!! +static const char *collision_type_str[] = { + "node", + "object", +}; + +// Indices must match values in `enum CollisionAxis` exactly!! +static const char *collision_axis_str[] = { + "x", + "y", + "z", +}; + +void push_collision_move_result(lua_State *L, const collisionMoveResult &res) +{ + lua_createtable(L, 0, 4); + + setboolfield(L, -1, "touching_ground", res.touching_ground); + setboolfield(L, -1, "collides", res.collides); + setboolfield(L, -1, "standing_on_object", res.standing_on_object); + + /* collisions */ + lua_createtable(L, res.collisions.size(), 0); + int i = 1; + for (const auto &c : res.collisions) { + lua_createtable(L, 0, 5); + + lua_pushstring(L, collision_type_str[c.type]); + lua_setfield(L, -2, "type"); + + assert(c.axis != COLLISION_AXIS_NONE); + lua_pushstring(L, collision_axis_str[c.axis]); + lua_setfield(L, -2, "axis"); + + if (c.type == COLLISION_NODE) { + push_v3s16(L, c.node_p); + lua_setfield(L, -2, "node_pos"); + } + + push_v3f(L, c.old_speed / BS); + lua_setfield(L, -2, "old_speed"); + + push_v3f(L, c.new_speed / BS); + lua_setfield(L, -2, "new_speed"); + + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "collisions"); + /**/ +} diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 9e755682f..8f32e58eb 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -63,7 +63,9 @@ struct EnumString; struct NoiseParams; class Schematic; class ServerActiveObject; +struct collisionMoveResult; +extern struct EnumString es_TileAnimationType[]; ContentFeatures read_content_features (lua_State *L, int index); void push_content_features (lua_State *L, @@ -196,4 +198,4 @@ void push_hud_element (lua_State *L, HudElement *elem); HudElementStat read_hud_change (lua_State *L, HudElement *elem, void **value); -extern struct EnumString es_TileAnimationType[]; +void push_collision_move_result(lua_State *L, const collisionMoveResult &res); diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index 26c7e8cd4..ea9320051 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -178,12 +178,11 @@ void ScriptApiEntity::luaentity_GetProperties(u16 id, lua_pop(L, 1); } -void ScriptApiEntity::luaentity_Step(u16 id, float dtime) +void ScriptApiEntity::luaentity_Step(u16 id, float dtime, + const collisionMoveResult *moveresult) { SCRIPTAPI_PRECHECKHEADER - //infostream<<"scriptapi_luaentity_step: id="<getScriptIface()->luaentity_Step(m_id, dtime); + if(m_registered) { + m_env->getScriptIface()->luaentity_Step(m_id, dtime, moveresult_p); } if (!send_recommended)