aboutsummaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
authorAndrew Ward <rw@rubenwardy.com>2018-03-28 16:05:18 +0100
committerGitHub <noreply@github.com>2018-03-28 16:05:18 +0100
commitdfc81983491417c5cd1c99d7db05e421c409379d (patch)
tree7b0457f0ff86f038cfad1a095d3ab0b6c44f2def /src/script
parent2323842dd3dd336b087ca3cf9756e0680b3a1244 (diff)
downloadminetest-dfc81983491417c5cd1c99d7db05e421c409379d.tar.gz
minetest-dfc81983491417c5cd1c99d7db05e421c409379d.tar.bz2
minetest-dfc81983491417c5cd1c99d7db05e421c409379d.zip
Add reasons to on_dieplayer and on_hpchange
Diffstat (limited to 'src/script')
-rw-r--r--src/script/cpp_api/s_base.cpp23
-rw-r--r--src/script/cpp_api/s_base.h3
-rw-r--r--src/script/cpp_api/s_player.cpp20
-rw-r--r--src/script/cpp_api/s_player.h6
-rw-r--r--src/script/lua_api/l_object.cpp39
5 files changed, 73 insertions, 18 deletions
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp
index f451156bd..571bac611 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -43,6 +43,7 @@ extern "C" {
#include <cstdio>
#include <cstdarg>
#include "script/common/c_content.h"
+#include "content_sao.h"
#include <sstream>
@@ -151,7 +152,7 @@ void ScriptApiBase::clientOpenLibs(lua_State *L)
{ LUA_JITLIBNAME, luaopen_jit },
#endif
};
-
+
for (const std::pair<std::string, lua_CFunction> &lib : m_libs) {
lua_pushcfunction(L, lib.second);
lua_pushstring(L, lib.first.c_str());
@@ -381,6 +382,26 @@ void ScriptApiBase::objectrefGetOrCreate(lua_State *L,
}
}
+void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason)
+{
+ if (reason.lua_reference >= 0) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, reason.lua_reference);
+ luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference);
+ } else
+ lua_newtable(L);
+
+ lua_pushstring(L, reason.getTypeAsString().c_str());
+ lua_setfield(L, -2, "type");
+
+ lua_pushstring(L, reason.from_mod ? "mod" : "engine");
+ lua_setfield(L, -2, "from");
+
+ if (reason.object) {
+ objectrefGetOrCreate(L, reason.object);
+ lua_setfield(L, -2, "object");
+ }
+}
+
Server* ScriptApiBase::getServer()
{
return dynamic_cast<Server *>(m_gamedef);
diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h
index 4837f4f99..dc7b581e3 100644
--- a/src/script/cpp_api/s_base.h
+++ b/src/script/cpp_api/s_base.h
@@ -72,6 +72,7 @@ class IGameDef;
class Environment;
class GUIEngine;
class ServerActiveObject;
+class PlayerHPChangeReason;
class ScriptApiBase {
public:
@@ -139,6 +140,8 @@ protected:
void objectrefGetOrCreate(lua_State *L, ServerActiveObject *cobj);
+ void pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason& reason);
+
std::recursive_mutex m_luastackmutex;
std::string m_last_run_mod;
bool m_secure = false;
diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp
index 578298e24..cc2b96d5e 100644
--- a/src/script/cpp_api/s_player.cpp
+++ b/src/script/cpp_api/s_player.cpp
@@ -36,16 +36,20 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
}
-void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
+void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player, const PlayerHPChangeReason &reason)
{
SCRIPTAPI_PRECHECKHEADER
- // Get core.registered_on_dieplayers
+ // Get callback table
lua_getglobal(L, "core");
lua_getfield(L, -1, "registered_on_dieplayers");
- // Call callbacks
+
+ // Push arguments
objectrefGetOrCreate(L, player);
- runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+ pushPlayerHPChangeReason(L, reason);
+
+ // Run callbacks
+ runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
}
bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
@@ -71,7 +75,7 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
}
s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
- s16 hp_change)
+ s16 hp_change, const PlayerHPChangeReason &reason)
{
SCRIPTAPI_PRECHECKHEADER
@@ -82,9 +86,13 @@ s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
lua_getfield(L, -1, "registered_on_player_hpchange");
lua_remove(L, -2);
+ // Push arguments
objectrefGetOrCreate(L, player);
lua_pushnumber(L, hp_change);
- PCALL_RES(lua_pcall(L, 2, 1, error_handler));
+ pushPlayerHPChangeReason(L, reason);
+
+ // Call callbacks
+ PCALL_RES(lua_pcall(L, 3, 1, error_handler));
hp_change = lua_tointeger(L, -1);
lua_pop(L, 2); // Pop result and error handler
return hp_change;
diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h
index 562805695..59e1505ae 100644
--- a/src/script/cpp_api/s_player.h
+++ b/src/script/cpp_api/s_player.h
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/string.h"
struct ToolCapabilities;
+struct PlayerHPChangeReason;
class ScriptApiPlayer : virtual public ScriptApiBase
{
@@ -31,7 +32,7 @@ public:
virtual ~ScriptApiPlayer() = default;
void on_newplayer(ServerActiveObject *player);
- void on_dieplayer(ServerActiveObject *player);
+ void on_dieplayer(ServerActiveObject *player, const PlayerHPChangeReason &reason);
bool on_respawnplayer(ServerActiveObject *player);
bool on_prejoinplayer(const std::string &name, const std::string &ip,
std::string *reason);
@@ -42,7 +43,8 @@ public:
bool on_punchplayer(ServerActiveObject *player, ServerActiveObject *hitter,
float time_from_last_punch, const ToolCapabilities *toolcap,
v3f dir, s16 damage);
- s16 on_player_hpchange(ServerActiveObject *player, s16 hp_change);
+ s16 on_player_hpchange(ServerActiveObject *player, s16 hp_change,
+ const PlayerHPChangeReason &reason);
void on_playerReceiveFields(ServerActiveObject *player,
const std::string &formname, const StringMap &fields);
void on_auth_failure(const std::string &name, const std::string &ip);
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 5fc6f9d3c..e4c478df7 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -194,13 +194,14 @@ 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);
+ getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
}
// If the puncher is a player, and its HP changed
if (dst_origin_hp != puncher->getHP() &&
puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
- getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher);
+ getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher,
+ PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, co));
}
return 0;
}
@@ -226,17 +227,36 @@ int ObjectRef::l_right_click(lua_State *L)
int ObjectRef::l_set_hp(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
+
+ // Get Object
ObjectRef *ref = checkobject(L, 1);
luaL_checknumber(L, 2);
ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
+ if (co == NULL)
+ return 0;
+
+ // Get HP
int hp = lua_tonumber(L, 2);
- /*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
- <<" hp="<<hp<<std::endl;*/
+
+ // Get Reason
+ PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
+ reason.from_mod = true;
+ if (lua_istable(L, 3)) {
+ lua_pushvalue(L, 3);
+
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1) && !reason.setTypeFromString(lua_tostring(L, -1))) {
+ errorstream << "Bad type given!" << std::endl;
+ }
+ lua_pop(L, 1);
+
+ reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
// Do it
- co->setHP(hp);
+ co->setHP(hp, reason);
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
- getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co);
+ getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason);
// Return
return 0;
@@ -729,9 +749,10 @@ int ObjectRef::l_set_properties(lua_State *L)
return 0;
read_object_properties(L, 2, prop, getServer(L)->idef());
if (prop->hp_max < co->getHP()) {
- co->setHP(prop->hp_max);
+ PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
+ co->setHP(prop->hp_max, reason);
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
- getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co);
+ getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason);
}
co->notifyObjectPropertiesModified();
return 0;