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 <ClobberXD@gmail.com>
This commit is contained in:
Wuzzy 2019-02-21 00:36:17 +01:00 committed by sfan5
parent 3296952ae5
commit ec3142af99
5 changed files with 25 additions and 19 deletions

@ -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

@ -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.

@ -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

@ -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)

@ -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)