Skip to content

Commit

Permalink
Expose collision information to LuaEntity on_step
Browse files Browse the repository at this point in the history
  • Loading branch information
sfan5 committed Apr 27, 2020
1 parent aef59f2 commit 3475759
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 10 deletions.
1 change: 1 addition & 0 deletions builtin/game/features.lua
Expand Up @@ -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)
Expand Down
25 changes: 24 additions & 1 deletion doc/lua_api.txt
Expand Up @@ -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`
Expand Down Expand Up @@ -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),

Expand All @@ -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
------------------------------------

Expand Down
54 changes: 54 additions & 0 deletions src/script/common/c_content.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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");
/**/
}
4 changes: 3 additions & 1 deletion src/script/common/c_content.h
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
12 changes: 8 additions & 4 deletions src/script/cpp_api/s_entity.cpp
Expand Up @@ -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="<<id<<std::endl;

int error_handler = PUSH_ERROR_HANDLER(L);

// Get core.luaentities[id]
Expand All @@ -199,9 +198,14 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self
lua_pushnumber(L, dtime); // dtime
/* moveresult */
if (moveresult)
push_collision_move_result(L, *moveresult);
else
lua_pushnil(L);

setOriginFromTable(object);
PCALL_RES(lua_pcall(L, 2, 0, error_handler));
PCALL_RES(lua_pcall(L, 3, 0, error_handler));

lua_pop(L, 2); // Pop object and error handler
}
Expand Down
4 changes: 3 additions & 1 deletion src/script/cpp_api/s_entity.h
Expand Up @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

struct ObjectProperties;
struct ToolCapabilities;
struct collisionMoveResult;

class ScriptApiEntity
: virtual public ScriptApiBase
Expand All @@ -36,7 +37,8 @@ class ScriptApiEntity
std::string luaentity_GetStaticdata(u16 id);
void luaentity_GetProperties(u16 id,
ServerActiveObject *self, ObjectProperties *prop);
void luaentity_Step(u16 id, float dtime);
void luaentity_Step(u16 id, float dtime,
const collisionMoveResult *moveresult);
bool luaentity_Punch(u16 id,
ServerActiveObject *puncher, float time_from_last_punch,
const ToolCapabilities *toolcap, v3f dir, s16 damage);
Expand Down
8 changes: 5 additions & 3 deletions src/server/luaentity_sao.cpp
Expand Up @@ -135,6 +135,8 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)

m_last_sent_position_timer += dtime;

collisionMoveResult moveresult, *moveresult_p = nullptr;

// Each frame, parent position is copied if the object is attached, otherwise it's calculated normally
// If the object gets detached this comes into effect automatically from the last known origin
if(isAttached())
Expand All @@ -150,7 +152,6 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
aabb3f box = m_prop.collisionbox;
box.MinEdge *= BS;
box.MaxEdge *= BS;
collisionMoveResult moveresult;
f32 pos_max_d = BS*0.25; // Distance per iteration
v3f p_pos = m_base_position;
v3f p_velocity = m_velocity;
Expand All @@ -159,6 +160,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
pos_max_d, box, m_prop.stepheight, dtime,
&p_pos, &p_velocity, p_acceleration,
this, m_prop.collideWithObjects);
moveresult_p = &moveresult;

// Apply results
m_base_position = p_pos;
Expand Down Expand Up @@ -188,8 +190,8 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
}
}

if(m_registered){
m_env->getScriptIface()->luaentity_Step(m_id, dtime);
if(m_registered) {
m_env->getScriptIface()->luaentity_Step(m_id, dtime, moveresult_p);
}

if (!send_recommended)
Expand Down

0 comments on commit 3475759

Please sign in to comment.