aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt9
-rw-r--r--src/content_sao.cpp17
-rw-r--r--src/content_sao.h16
-rw-r--r--src/script/cpp_api/s_base.cpp4
-rw-r--r--src/script/lua_api/l_object.cpp7
5 files changed, 39 insertions, 14 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 538e2dee7..41e8e0c96 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -3738,15 +3738,16 @@ Call these functions only at load time!
giving a type - use this for custom damage types.
* `punch`: Was punched. `reason.object` will hold the puncher, or nil if none.
* `fall`
- * `node_damage`: damage_per_second from a neighbouring node.
+ * `node_damage`: `damage_per_second` from a neighbouring node.
+ `reason.node` will hold the node name or nil.
* `drown`
* `respawn`
* Any of the above types may have additional fields from mods.
* `reason.from` will be `mod` or `engine`.
* `modifier`: when true, the function should return the actual `hp_change`.
- Note: modifiers only get a temporary hp_change that can be modified by later modifiers.
- modifiers can return true as a second argument to stop the execution of further functions.
- Non-modifiers receive the final hp change calculated by the modifiers.
+ Note: modifiers only get a temporary `hp_change` that can be modified by later modifiers.
+ Modifiers can return true as a second argument to stop the execution of further functions.
+ Non-modifiers receive the final HP change calculated by the modifiers.
* `minetest.register_on_dieplayer(function(ObjectRef, reason))`
* Called when a player dies
* `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index cb0a969eb..2f849d3fc 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -1022,6 +1022,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
if (m_node_hurt_interval.step(dtime, 1.0f)) {
u32 damage_per_second = 0;
+ std::string nodename;
// Lowest and highest damage points are 0.1 within collisionbox
float dam_top = m_prop.collisionbox.MaxEdge.Y - 0.1f;
@@ -1031,20 +1032,26 @@ void PlayerSAO::step(float dtime, bool send_recommended)
v3s16 p = floatToInt(m_base_position +
v3f(0.0f, dam_height * BS, 0.0f), BS);
MapNode n = m_env->getMap().getNodeNoEx(p);
- damage_per_second = std::max(damage_per_second,
- m_env->getGameDef()->ndef()->get(n).damage_per_second);
+ const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n);
+ if (c.damage_per_second > damage_per_second) {
+ damage_per_second = c.damage_per_second;
+ nodename = c.name;
+ }
}
// Top damage point
v3s16 ptop = floatToInt(m_base_position +
v3f(0.0f, dam_top * BS, 0.0f), BS);
MapNode ntop = m_env->getMap().getNodeNoEx(ptop);
- damage_per_second = std::max(damage_per_second,
- m_env->getGameDef()->ndef()->get(ntop).damage_per_second);
+ const ContentFeatures &c = m_env->getGameDef()->ndef()->get(ntop);
+ if (c.damage_per_second > damage_per_second) {
+ damage_per_second = c.damage_per_second;
+ nodename = c.name;
+ }
if (damage_per_second != 0 && m_hp > 0) {
s32 newhp = (s32)m_hp - (s32)damage_per_second;
- PlayerHPChangeReason reason(PlayerHPChangeReason::NODE_DAMAGE);
+ PlayerHPChangeReason reason(PlayerHPChangeReason::NODE_DAMAGE, nodename);
setHP(newhp, reason);
m_env->getGameDef()->SendPlayerHPOrDie(this, reason);
}
diff --git a/src/content_sao.h b/src/content_sao.h
index f54bc16c2..1321edb91 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -401,10 +401,14 @@ struct PlayerHPChangeReason {
};
Type type = SET_HP;
- ServerActiveObject *object;
bool from_mod = false;
int lua_reference = -1;
+ // For PLAYER_PUNCH
+ ServerActiveObject *object = nullptr;
+ // For NODE_DAMAGE
+ std::string node;
+
inline bool hasLuaReference() const
{
return lua_reference >= 0;
@@ -450,7 +454,15 @@ struct PlayerHPChangeReason {
}
}
- PlayerHPChangeReason(Type type, ServerActiveObject *object=NULL):
+ PlayerHPChangeReason(Type type):
+ type(type)
+ {}
+
+ PlayerHPChangeReason(Type type, ServerActiveObject *object):
type(type), object(object)
{}
+
+ PlayerHPChangeReason(Type type, std::string node):
+ type(type), node(node)
+ {}
};
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp
index a8ed902dd..e73f613ce 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -404,6 +404,10 @@ void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeR
objectrefGetOrCreate(L, reason.object);
lua_setfield(L, -2, "object");
}
+ if (!reason.node.empty()) {
+ lua_pushstring(L, reason.node.c_str());
+ lua_setfield(L, -2, "node");
+ }
}
Server* ScriptApiBase::getServer()
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 597cb84a8..2efcd894a 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -170,8 +170,8 @@ int ObjectRef::l_punch(lua_State *L)
ObjectRef *puncher_ref = checkobject(L, 2);
ServerActiveObject *co = getobject(ref);
ServerActiveObject *puncher = getobject(puncher_ref);
- if (co == NULL) return 0;
- if (puncher == NULL) return 0;
+ if (!co || !puncher)
+ return 0;
v3f dir;
if (lua_type(L, 5) != LUA_TTABLE)
dir = co->getBasePosition() - puncher->getBasePosition();
@@ -192,7 +192,8 @@ int ObjectRef::l_punch(lua_State *L)
// If the punched is a player, and its HP changed
if (src_original_hp != co->getHP() &&
co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
- getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
+ getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co,
+ PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
}
// If the puncher is a player, and its HP changed