mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Allow damage for attached objects, add attach/detach callbacks (#6786)
* Allow right-clicking on attached LuaEntities
This commit is contained in:
parent
0b5b32b026
commit
ba91624d8c
9 changed files with 136 additions and 78 deletions
|
@ -262,7 +262,9 @@ bool ScriptApiEntity::luaentity_Punch(u16 id,
|
|||
return retval;
|
||||
}
|
||||
|
||||
bool ScriptApiEntity::luaentity_on_death(u16 id, ServerActiveObject *killer)
|
||||
// Calls entity[field](ObjectRef self, ObjectRef sao)
|
||||
bool ScriptApiEntity::luaentity_run_simple_callback(u16 id,
|
||||
ServerActiveObject *sao, const char *field)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
|
@ -273,14 +275,14 @@ bool ScriptApiEntity::luaentity_on_death(u16 id, ServerActiveObject *killer)
|
|||
int object = lua_gettop(L);
|
||||
// State: object is at top of stack
|
||||
// Get function
|
||||
lua_getfield(L, -1, "on_death");
|
||||
lua_getfield(L, -1, field);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 2); // Pop on_death and entity
|
||||
lua_pop(L, 2); // Pop callback field and entity
|
||||
return false;
|
||||
}
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
lua_pushvalue(L, object); // self
|
||||
objectrefGetOrCreate(L, killer); // killer reference
|
||||
objectrefGetOrCreate(L, sao); // killer reference
|
||||
|
||||
setOriginFromTable(object);
|
||||
PCALL_RES(lua_pcall(L, 2, 1, error_handler));
|
||||
|
@ -290,33 +292,28 @@ bool ScriptApiEntity::luaentity_on_death(u16 id, ServerActiveObject *killer)
|
|||
return retval;
|
||||
}
|
||||
|
||||
// Calls entity:on_rightclick(ObjectRef clicker)
|
||||
void ScriptApiEntity::luaentity_Rightclick(u16 id,
|
||||
ServerActiveObject *clicker)
|
||||
bool ScriptApiEntity::luaentity_on_death(u16 id, ServerActiveObject *killer)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
||||
|
||||
int error_handler = PUSH_ERROR_HANDLER(L);
|
||||
|
||||
// Get core.luaentities[id]
|
||||
luaentity_get(L, id);
|
||||
int object = lua_gettop(L);
|
||||
// State: object is at top of stack
|
||||
// Get function
|
||||
lua_getfield(L, -1, "on_rightclick");
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 2); // Pop on_rightclick and entity
|
||||
return;
|
||||
}
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
lua_pushvalue(L, object); // self
|
||||
objectrefGetOrCreate(L, clicker); // Clicker reference
|
||||
|
||||
setOriginFromTable(object);
|
||||
PCALL_RES(lua_pcall(L, 2, 0, error_handler));
|
||||
|
||||
lua_pop(L, 2); // Pop object and error handler
|
||||
return luaentity_run_simple_callback(id, killer, "on_death");
|
||||
}
|
||||
|
||||
// Calls entity:on_rightclick(ObjectRef clicker)
|
||||
void ScriptApiEntity::luaentity_Rightclick(u16 id, ServerActiveObject *clicker)
|
||||
{
|
||||
luaentity_run_simple_callback(id, clicker, "on_rightclick");
|
||||
}
|
||||
|
||||
void ScriptApiEntity::luaentity_on_attach_child(u16 id, ServerActiveObject *child)
|
||||
{
|
||||
luaentity_run_simple_callback(id, child, "on_attach_child");
|
||||
}
|
||||
|
||||
void ScriptApiEntity::luaentity_on_detach_child(u16 id, ServerActiveObject *child)
|
||||
{
|
||||
luaentity_run_simple_callback(id, child, "on_detach_child");
|
||||
}
|
||||
|
||||
void ScriptApiEntity::luaentity_on_detach(u16 id, ServerActiveObject *parent)
|
||||
{
|
||||
luaentity_run_simple_callback(id, parent, "on_detach");
|
||||
}
|
||||
|
|
|
@ -41,6 +41,11 @@ public:
|
|||
ServerActiveObject *puncher, float time_from_last_punch,
|
||||
const ToolCapabilities *toolcap, v3f dir, s16 damage);
|
||||
bool luaentity_on_death(u16 id, ServerActiveObject *killer);
|
||||
void luaentity_Rightclick(u16 id,
|
||||
ServerActiveObject *clicker);
|
||||
void luaentity_Rightclick(u16 id, ServerActiveObject *clicker);
|
||||
void luaentity_on_attach_child(u16 id, ServerActiveObject *child);
|
||||
void luaentity_on_detach_child(u16 id, ServerActiveObject *child);
|
||||
void luaentity_on_detach(u16 id, ServerActiveObject *parent);
|
||||
private:
|
||||
bool luaentity_run_simple_callback(u16 id, ServerActiveObject *sao,
|
||||
const char *field);
|
||||
};
|
||||
|
|
|
@ -103,12 +103,8 @@ int ObjectRef::l_remove(lua_State *L)
|
|||
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
||||
return 0;
|
||||
|
||||
const std::unordered_set<int> &child_ids = co->getAttachmentChildIds();
|
||||
for (int child_id : child_ids) {
|
||||
// Child can be NULL if it was deleted earlier
|
||||
if (ServerActiveObject *child = env->getActiveObject(child_id))
|
||||
child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
|
||||
}
|
||||
co->clearChildAttachments();
|
||||
co->clearParentAttachment();
|
||||
|
||||
verbosestream << "ObjectRef::l_remove(): id=" << co->getId() << std::endl;
|
||||
co->m_pending_removal = true;
|
||||
|
@ -721,21 +717,7 @@ int ObjectRef::l_set_detach(lua_State *L)
|
|||
if (co == NULL)
|
||||
return 0;
|
||||
|
||||
int parent_id = 0;
|
||||
std::string bone;
|
||||
v3f position;
|
||||
v3f rotation;
|
||||
co->getAttachment(&parent_id, &bone, &position, &rotation);
|
||||
ServerActiveObject *parent = NULL;
|
||||
if (parent_id) {
|
||||
parent = env->getActiveObject(parent_id);
|
||||
co->setAttachment(0, "", position, rotation);
|
||||
} else {
|
||||
co->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
|
||||
}
|
||||
// Do it
|
||||
if (parent != NULL)
|
||||
parent->removeAttachmentChild(co->getId());
|
||||
co->clearParentAttachment();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue