Add possibility to easier override HP and breath engine logic by Lua (#14179)

Co-authored-by: Lars Mueller <appgurulars@gmx.de>
This commit is contained in:
sfence 2024-08-21 20:24:43 +02:00 committed by GitHub
parent dc21924f31
commit f2c66b9ceb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 66 additions and 4 deletions

@ -8495,6 +8495,14 @@ child will follow movement and rotation of that bone.
* Result is a table with the same fields as `light_definition` in `set_lighting`.
* `respawn()`: Respawns the player using the same mechanism as the death screen,
including calling `on_respawnplayer` callbacks.
* `get_flags()`: returns a table of player flags (the following boolean fields):
* `breathing`: Whether breathing (regaining air) is enabled, default `true`.
* `drowning`: Whether drowning (losing air) is enabled, default `true`.
* `node_damage`: Whether the player takes damage from nodes, default `true`.
* `set_flags(flags)`: sets flags
* takes a table in the same format as returned by `get_flags`
* absent fields are left unchanged
`PcgRandom`
-----------

@ -291,7 +291,7 @@ const std::array<const char *, 33> object_property_keys = {
"use_texture_alpha",
"shaded",
"damage_texture_modifier",
"show_on_minimap"
"show_on_minimap",
};
/******************************************************************************/

@ -2688,6 +2688,41 @@ int ObjectRef::l_respawn(lua_State *L)
return 1;
}
// set_flags(self, flags)
int ObjectRef::l_set_flags(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
auto *psao = getplayersao(ref);
if (psao == nullptr)
return 0;
if (!lua_istable(L, -1))
throw LuaError("expected a table of flags");
auto &flags = psao->m_flags;
flags.drowning = getboolfield_default(L, -1, "drowning", flags.drowning);
flags.breathing = getboolfield_default(L, -1, "breathing", flags.breathing);
flags.node_damage = getboolfield_default(L, -1, "node_damage", flags.node_damage);
return 0;
}
// get_flags(self)
int ObjectRef::l_get_flags(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
const auto *psao = getplayersao(ref);
if (psao == nullptr)
return 0;
lua_createtable(L, 0, 3);
lua_pushboolean(L, psao->m_flags.drowning);
lua_setfield(L, -2, "drowning");
lua_pushboolean(L, psao->m_flags.breathing);
lua_setfield(L, -2, "breathing");
lua_pushboolean(L, psao->m_flags.node_damage);
lua_setfield(L, -2, "node_damage");
return 1;
}
ObjectRef::ObjectRef(ServerActiveObject *object):
m_object(object)
@ -2838,6 +2873,8 @@ luaL_Reg ObjectRef::methods[] = {
luamethod(ObjectRef, set_lighting),
luamethod(ObjectRef, get_lighting),
luamethod(ObjectRef, respawn),
luamethod(ObjectRef, set_flags),
luamethod(ObjectRef, get_flags),
{0,0}
};

@ -411,4 +411,10 @@ private:
// respawn(self)
static int l_respawn(lua_State *L);
// set_flags(self, flags)
static int l_set_flags(lua_State *L);
// get_flags(self)
static int l_get_flags(lua_State *L);
};

@ -156,7 +156,10 @@ void PlayerSAO::getStaticData(std::string * result) const
void PlayerSAO::step(float dtime, bool send_recommended)
{
if (!isImmortal() && m_drowning_interval.step(dtime, 2.0f)) {
bool not_immortal = !isImmortal();
if (not_immortal && m_flags.drowning
&& m_drowning_interval.step(dtime, 2.0f)) {
// Get nose/mouth position, approximate with eye position
v3s16 p = floatToInt(getEyePosition(), BS);
MapNode n = m_env->getMap().getNode(p);
@ -174,7 +177,8 @@ void PlayerSAO::step(float dtime, bool send_recommended)
}
}
if (m_breathing_interval.step(dtime, 0.5f) && !isImmortal()) {
if (not_immortal && m_flags.breathing
&& m_breathing_interval.step(dtime, 0.5f)) {
// Get nose/mouth position, approximate with eye position
v3s16 p = floatToInt(getEyePosition(), BS);
MapNode n = m_env->getMap().getNode(p);
@ -185,7 +189,8 @@ void PlayerSAO::step(float dtime, bool send_recommended)
setBreath(m_breath + 1);
}
if (!isImmortal() && m_node_hurt_interval.step(dtime, 1.0f)) {
if (not_immortal && m_flags.node_damage
&& m_node_hurt_interval.step(dtime, 1.0f)) {
u32 damage_per_second = 0;
std::string nodename;
v3s16 node_pos;

@ -228,6 +228,12 @@ private:
SimpleMetadata m_meta;
public:
struct {
bool breathing : 1;
bool drowning : 1;
bool node_damage : 1;
} m_flags = {true, true, true};
bool m_physics_override_sent = false;
};