mirror of
https://github.com/minetest/minetest.git
synced 2024-12-22 14:12:24 +01:00
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:
parent
dc21924f31
commit
f2c66b9ceb
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user