mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
Expose collision information to LuaEntity on_step
This commit is contained in:
parent
aef59f2ad9
commit
3475759d1a
@ -16,6 +16,7 @@ core.features = {
|
|||||||
formspec_version_element = true,
|
formspec_version_element = true,
|
||||||
area_store_persistent_ids = true,
|
area_store_persistent_ids = true,
|
||||||
pathfinder_works = true,
|
pathfinder_works = true,
|
||||||
|
object_step_has_moveresult = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
@ -4147,6 +4147,8 @@ Utilities
|
|||||||
area_store_persistent_ids = true,
|
area_store_persistent_ids = true,
|
||||||
-- Whether minetest.find_path is functional (5.2.0)
|
-- Whether minetest.find_path is functional (5.2.0)
|
||||||
pathfinder_works = true,
|
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`
|
* `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_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),
|
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
|
-- 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
|
ABM (ActiveBlockModifier) definition
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "common/c_types.h"
|
#include "common/c_types.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "object_properties.h"
|
#include "object_properties.h"
|
||||||
|
#include "collision.h"
|
||||||
#include "cpp_api/s_node.h"
|
#include "cpp_api/s_node.h"
|
||||||
#include "lua_api/l_object.h"
|
#include "lua_api/l_object.h"
|
||||||
#include "lua_api/l_item.h"
|
#include "lua_api/l_item.h"
|
||||||
@ -2002,3 +2003,56 @@ HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
|
|||||||
}
|
}
|
||||||
return stat;
|
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");
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
@ -63,7 +63,9 @@ struct EnumString;
|
|||||||
struct NoiseParams;
|
struct NoiseParams;
|
||||||
class Schematic;
|
class Schematic;
|
||||||
class ServerActiveObject;
|
class ServerActiveObject;
|
||||||
|
struct collisionMoveResult;
|
||||||
|
|
||||||
|
extern struct EnumString es_TileAnimationType[];
|
||||||
|
|
||||||
ContentFeatures read_content_features (lua_State *L, int index);
|
ContentFeatures read_content_features (lua_State *L, int index);
|
||||||
void push_content_features (lua_State *L,
|
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);
|
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);
|
||||||
|
@ -178,12 +178,11 @@ void ScriptApiEntity::luaentity_GetProperties(u16 id,
|
|||||||
lua_pop(L, 1);
|
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
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
|
||||||
|
|
||||||
int error_handler = PUSH_ERROR_HANDLER(L);
|
int error_handler = PUSH_ERROR_HANDLER(L);
|
||||||
|
|
||||||
// Get core.luaentities[id]
|
// Get core.luaentities[id]
|
||||||
@ -199,9 +198,14 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
|
|||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
lua_pushnumber(L, dtime); // dtime
|
lua_pushnumber(L, dtime); // dtime
|
||||||
|
/* moveresult */
|
||||||
|
if (moveresult)
|
||||||
|
push_collision_move_result(L, *moveresult);
|
||||||
|
else
|
||||||
|
lua_pushnil(L);
|
||||||
|
|
||||||
setOriginFromTable(object);
|
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
|
lua_pop(L, 2); // Pop object and error handler
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
struct ObjectProperties;
|
struct ObjectProperties;
|
||||||
struct ToolCapabilities;
|
struct ToolCapabilities;
|
||||||
|
struct collisionMoveResult;
|
||||||
|
|
||||||
class ScriptApiEntity
|
class ScriptApiEntity
|
||||||
: virtual public ScriptApiBase
|
: virtual public ScriptApiBase
|
||||||
@ -36,7 +37,8 @@ public:
|
|||||||
std::string luaentity_GetStaticdata(u16 id);
|
std::string luaentity_GetStaticdata(u16 id);
|
||||||
void luaentity_GetProperties(u16 id,
|
void luaentity_GetProperties(u16 id,
|
||||||
ServerActiveObject *self, ObjectProperties *prop);
|
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,
|
bool luaentity_Punch(u16 id,
|
||||||
ServerActiveObject *puncher, float time_from_last_punch,
|
ServerActiveObject *puncher, float time_from_last_punch,
|
||||||
const ToolCapabilities *toolcap, v3f dir, s16 damage);
|
const ToolCapabilities *toolcap, v3f dir, s16 damage);
|
||||||
|
@ -135,6 +135,8 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||||||
|
|
||||||
m_last_sent_position_timer += dtime;
|
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
|
// 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 the object gets detached this comes into effect automatically from the last known origin
|
||||||
if(isAttached())
|
if(isAttached())
|
||||||
@ -150,7 +152,6 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||||||
aabb3f box = m_prop.collisionbox;
|
aabb3f box = m_prop.collisionbox;
|
||||||
box.MinEdge *= BS;
|
box.MinEdge *= BS;
|
||||||
box.MaxEdge *= BS;
|
box.MaxEdge *= BS;
|
||||||
collisionMoveResult moveresult;
|
|
||||||
f32 pos_max_d = BS*0.25; // Distance per iteration
|
f32 pos_max_d = BS*0.25; // Distance per iteration
|
||||||
v3f p_pos = m_base_position;
|
v3f p_pos = m_base_position;
|
||||||
v3f p_velocity = m_velocity;
|
v3f p_velocity = m_velocity;
|
||||||
@ -159,6 +160,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||||||
pos_max_d, box, m_prop.stepheight, dtime,
|
pos_max_d, box, m_prop.stepheight, dtime,
|
||||||
&p_pos, &p_velocity, p_acceleration,
|
&p_pos, &p_velocity, p_acceleration,
|
||||||
this, m_prop.collideWithObjects);
|
this, m_prop.collideWithObjects);
|
||||||
|
moveresult_p = &moveresult;
|
||||||
|
|
||||||
// Apply results
|
// Apply results
|
||||||
m_base_position = p_pos;
|
m_base_position = p_pos;
|
||||||
@ -188,8 +190,8 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_registered){
|
if(m_registered) {
|
||||||
m_env->getScriptIface()->luaentity_Step(m_id, dtime);
|
m_env->getScriptIface()->luaentity_Step(m_id, dtime, moveresult_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!send_recommended)
|
if (!send_recommended)
|
||||||
|
Loading…
Reference in New Issue
Block a user