From ec3142af990ea55775185e04e46ebf8eb16e2268 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 21 Feb 2019 00:36:17 +0100 Subject: [PATCH] Group "immortal" also protects players from damage Document new meaning of immortal=1 for players Disable breathing if player is immortal Hide builtin statbars if player immortal (delayed) Co-authored-by: ClobberXD --- builtin/game/statbars.lua | 7 ++++--- doc/lua_api.txt | 4 +++- src/content_sao.cpp | 15 ++++++++------- src/content_sao.h | 16 +++++++++------- src/server.cpp | 2 +- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/builtin/game/statbars.lua b/builtin/game/statbars.lua index da924d6f8..bb88356d5 100644 --- a/builtin/game/statbars.lua +++ b/builtin/game/statbars.lua @@ -50,7 +50,8 @@ local function update_builtin_statbars(player) end local hud = hud_ids[name] - if flags.healthbar and enable_damage then + local immortal = player:get_armor_groups().immortal == 1 + if flags.healthbar and enable_damage and not immortal then local number = scaleToDefault(player, "hp") if hud.id_healthbar == nil then local hud_def = table.copy(health_bar_definition) @@ -65,7 +66,7 @@ local function update_builtin_statbars(player) end local breath_max = player:get_properties().breath_max - if flags.breathbar and enable_damage and + if flags.breathbar and enable_damage and not immortal and player:get_breath() < breath_max then local number = 2 * scaleToDefault(player, "breath") if hud.id_breathbar == nil then @@ -116,7 +117,7 @@ local function player_event_handler(player,eventname) end end - if eventname == "hud_changed" then + if eventname == "hud_changed" or eventname == "properties_changed" then update_builtin_statbars(player) return true end diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 22bd6f548..4026821dd 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1533,7 +1533,9 @@ Another example: Make red wool from white wool and red dye: Special groups -------------- -* `immortal`: Disables the group damage system for an entity +* `immortal`: Skips all damage and breath handling for an object. This group + will also hide the integrated HUD status bars for players, and is + automatically set to all players when damage is disabled on the server. * `punch_operable`: For entities; disables the regular damage mechanism for players punching it by hand or a non-tool item, so that it can do something else than take damage. diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 84a09d977..c0bc25a4d 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -134,7 +134,7 @@ void UnitSAO::setArmorGroups(const ItemGroupList &armor_groups) m_armor_groups_sent = false; } -const ItemGroupList &UnitSAO::getArmorGroups() +const ItemGroupList &UnitSAO::getArmorGroups() const { return m_armor_groups; } @@ -1015,14 +1015,14 @@ void PlayerSAO::step(float dtime, bool send_recommended) } } - if (m_breathing_interval.step(dtime, 0.5f)) { + if (m_breathing_interval.step(dtime, 0.5f) && !isImmortal()) { // Get nose/mouth position, approximate with eye position v3s16 p = floatToInt(getEyePosition(), BS); MapNode n = m_env->getMap().getNodeNoEx(p); const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); - // If player is alive & no drowning & not in ignore, breathe - if (m_breath < m_prop.breath_max && - c.drowning == 0 && n.getContent() != CONTENT_IGNORE && m_hp > 0) + // If player is alive & not drowning & not in ignore & not immortal, breathe + if (m_breath < m_prop.breath_max && c.drowning == 0 && + n.getContent() != CONTENT_IGNORE && m_hp > 0) setBreath(m_breath + 1); } @@ -1069,6 +1069,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) // create message and add to list ActiveObjectMessage aom(getId(), true, str); m_messages_out.push(aom); + m_env->getScriptIface()->player_event(this, "properties_changed"); } // If attached, check that our parent is still there. If it isn't, detach. @@ -1287,8 +1288,8 @@ int PlayerSAO::punch(v3f dir, FATAL_ERROR_IF(!puncher, "Punch action called without SAO"); - // No effect if PvP disabled - if (!g_settings->getBool("enable_pvp")) { + // No effect if PvP disabled or if immortal + if (isImmortal() || !g_settings->getBool("enable_pvp")) { if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) { std::string str = gob_cmd_punched(getHP()); // create message and add to list diff --git a/src/content_sao.h b/src/content_sao.h index 0c503b4cb..c579474ee 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -45,11 +45,12 @@ public: inline bool isAttached() const { return getParent(); } + inline bool isImmortal() const - { return itemgroup_get(m_armor_groups, "immortal"); } + { return itemgroup_get(getArmorGroups(), "immortal"); } void setArmorGroups(const ItemGroupList &armor_groups); - const ItemGroupList &getArmorGroups(); + const ItemGroupList &getArmorGroups() const; void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop); void getAnimation(v2f *frame_range, float *frame_speed, float *frame_blend, bool *frame_loop); void setAnimationSpeed(float frame_speed); @@ -107,7 +108,7 @@ class LuaEntitySAO : public UnitSAO { public: LuaEntitySAO(ServerEnvironment *env, v3f pos, - const std::string &name, const std::string &state); + const std::string &name, const std::string &state); ~LuaEntitySAO(); ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_LUAENTITY; } @@ -115,16 +116,16 @@ public: { return ACTIVEOBJECT_TYPE_GENERIC; } virtual void addedToEnvironment(u32 dtime_s); static ServerActiveObject* create(ServerEnvironment *env, v3f pos, - const std::string &data); + const std::string &data); void step(float dtime, bool send_recommended); std::string getClientInitializationData(u16 protocol_version); bool isStaticAllowed() const { return m_prop.static_save; } void getStaticData(std::string *result) const; int punch(v3f dir, - const ToolCapabilities *toolcap=NULL, - ServerActiveObject *puncher=NULL, - float time_from_last_punch=1000000); + const ToolCapabilities *toolcap = nullptr, + ServerActiveObject *puncher = nullptr, + float time_from_last_punch = 1000000); void rightClick(ServerActiveObject *clicker); void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); @@ -132,6 +133,7 @@ public: std::string getDescription(); void setHP(s32 hp, const PlayerHPChangeReason &reason); u16 getHP() const; + /* LuaEntitySAO-specific */ void setVelocity(v3f velocity); void addVelocity(v3f velocity) diff --git a/src/server.cpp b/src/server.cpp index f3c13bad1..b3a6b4909 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1429,7 +1429,7 @@ void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason if (playersao->isImmortal()) return; - session_t peer_id = playersao->getPeerID(); + session_t peer_id = playersao->getPeerID(); bool is_alive = playersao->getHP() > 0; if (is_alive)