summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCServer/Plugins/APIDump/Hooks/OnPlayerFoodLevelChange.lua27
-rw-r--r--src/Bindings/Plugin.h1
-rw-r--r--src/Bindings/PluginLua.cpp20
-rw-r--r--src/Bindings/PluginLua.h1
-rw-r--r--src/Bindings/PluginManager.cpp19
-rw-r--r--src/Bindings/PluginManager.h2
-rw-r--r--src/ClientHandle.cpp2
-rw-r--r--src/Entities/Player.cpp50
8 files changed, 94 insertions, 28 deletions
diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerFoodLevelChange.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerFoodLevelChange.lua
new file mode 100644
index 000000000..53637d5f1
--- /dev/null
+++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerFoodLevelChange.lua
@@ -0,0 +1,27 @@
+return
+{
+ HOOK_PLAYER_FOOD_LEVEL_CHANGE =
+ {
+ CalledWhen = "Called before the player food level changed. Plugin may override",
+ DefaultFnName = "OnPlayerFoodLevelChange", -- also used as pagename
+ Desc = [[
+ This hook is called before the food level changes.
+ The food level is not changed yet, plugins may choose
+ to refuse the change.
+ ]],
+ Params =
+ {
+ { Name = "Player", Type = "{{cPlayer}}", Notes = "The player who changes the food level." },
+ { Name = "NewFoodLevel", Type = "number", Notes = "The new food level." },
+ },
+ Returns = [[
+ If the function returns false or no value, the next plugin's callback is called. Afterwards, the
+ server changes the food level of the player. If the function returns true, no
+ other callback is called for this event and the player's food level doesn't change.
+ ]],
+ }, -- HOOK_PLAYER_FOOD_LEVEL_CHANGE
+};
+
+
+
+
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index c6461c861..8ba20c026 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -72,6 +72,7 @@ public:
virtual bool OnPlayerEating (cPlayer & a_Player) = 0;
virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) = 0;
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) = 0;
+ virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0;
virtual bool OnPlayerJoined (cPlayer & a_Player) = 0;
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0;
virtual bool OnPlayerMoved (cPlayer & a_Player) = 0;
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index 97366cc4c..344031995 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -715,6 +715,26 @@ bool cPluginLua::OnPlayerEating(cPlayer & a_Player)
+bool cPluginLua::OnPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel)
+{
+ cCSLock Lock(m_CriticalSection);
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FOOD_LEVEL_CHANGE];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ m_LuaState.Call((int)(**itr), &a_Player, a_NewFoodLevel, cLuaState::Return, res);
+ if (res)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
bool cPluginLua::OnPlayerFished(cPlayer & a_Player, const cItems & a_Reward)
{
cCSLock Lock(m_CriticalSection);
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index 598e031c0..9c9de95c6 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -95,6 +95,7 @@ public:
virtual bool OnPlayerEating (cPlayer & a_Player) override;
virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) override;
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override;
+ virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override;
virtual bool OnPlayerJoined (cPlayer & a_Player) override;
virtual bool OnPlayerMoved (cPlayer & a_Player) override;
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override;
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index c50100d6f..3cb8c99a1 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -695,6 +695,25 @@ bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player)
+bool cPluginManager::CallHookPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel)
+{
+ FIND_HOOK(HOOK_PLAYER_FOOD_LEVEL_CHANGE);
+ VERIFY_HOOK;
+
+ for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
+ {
+ if ((*itr)->OnPlayerFoodLevelChange(a_Player, a_NewFoodLevel))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Reward)
{
FIND_HOOK(HOOK_PLAYER_FISHED);
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index be40bd2f7..72cedfae1 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -87,6 +87,7 @@ public: // tolua_export
HOOK_PLAYER_EATING,
HOOK_PLAYER_FISHED,
HOOK_PLAYER_FISHING,
+ HOOK_PLAYER_FOOD_LEVEL_CHANGE,
HOOK_PLAYER_JOINED,
HOOK_PLAYER_LEFT_CLICK,
HOOK_PLAYER_MOVING,
@@ -188,6 +189,7 @@ public: // tolua_export
bool CallHookPlayerEating (cPlayer & a_Player);
bool CallHookPlayerFished (cPlayer & a_Player, const cItems a_Reward);
bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward);
+ bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel);
bool CallHookPlayerJoined (cPlayer & a_Player);
bool CallHookPlayerMoving (cPlayer & a_Player);
bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 6b71f0924..efa734b44 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -1223,9 +1223,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
{
// A plugin won't let us eat, abort (send the proper packets to the client, too):
m_Player->AbortEating();
- return;
}
- return;
}
else
{
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index daf1ef2cc..ab2dbc0cf 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -37,9 +37,9 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
: super(etPlayer, 0.6, 1.8)
, m_bVisible(true)
, m_FoodLevel(MAX_FOOD_LEVEL)
- , m_FoodSaturationLevel(5)
+ , m_FoodSaturationLevel(5.0)
, m_FoodTickTimer(0)
- , m_FoodExhaustionLevel(0)
+ , m_FoodExhaustionLevel(0.0)
, m_FoodPoisonedTicksRemaining(0)
, m_LastJumpHeight(0)
, m_LastGroundHeight(0)
@@ -521,7 +521,15 @@ void cPlayer::Heal(int a_Health)
void cPlayer::SetFoodLevel(int a_FoodLevel)
{
- m_FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL));
+ int FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL));
+
+ if (cRoot::Get()->GetPluginManager()->CallHookPlayerFoodLevelChange(*this, FoodLevel))
+ {
+ m_FoodSaturationLevel = 5.0;
+ return;
+ }
+
+ m_FoodLevel = FoodLevel;
SendHealth();
}
@@ -571,11 +579,9 @@ bool cPlayer::Feed(int a_Food, double a_Saturation)
{
return false;
}
-
- m_FoodLevel = std::min(a_Food + m_FoodLevel, (int)MAX_FOOD_LEVEL);
- m_FoodSaturationLevel = std::min(m_FoodSaturationLevel + a_Saturation, (double)m_FoodLevel);
-
- SendHealth();
+
+ SetFoodSaturationLevel(m_FoodSaturationLevel + a_Saturation);
+ SetFoodLevel(m_FoodLevel + a_Food);
return true;
}
@@ -969,7 +975,7 @@ void cPlayer::Respawn(void)
// Reset food level:
m_FoodLevel = MAX_FOOD_LEVEL;
- m_FoodSaturationLevel = 5;
+ m_FoodSaturationLevel = 5.0;
// Reset Experience
m_CurrentXp = 0;
@@ -1895,16 +1901,13 @@ void cPlayer::TickBurning(cChunk & a_Chunk)
void cPlayer::HandleFood(void)
{
// Ref.: http://www.minecraftwiki.net/wiki/Hunger
-
+
if (IsGameModeCreative())
{
// Hunger is disabled for Creative
return;
}
-
- // Remember the food level before processing, for later comparison
- int LastFoodLevel = m_FoodLevel;
-
+
// Heal or damage, based on the food level, using the m_FoodTickTimer:
if ((m_FoodLevel > 17) || (m_FoodLevel <= 0))
{
@@ -1917,7 +1920,7 @@ void cPlayer::HandleFood(void)
{
// Regenerate health from food, incur 3 pts of food exhaustion:
Heal(1);
- m_FoodExhaustionLevel += 3;
+ m_FoodExhaustionLevel += 3.0;
}
else if ((m_FoodLevel <= 0) && (m_Health > 1))
{
@@ -1926,7 +1929,7 @@ void cPlayer::HandleFood(void)
}
}
}
-
+
// Apply food poisoning food exhaustion:
if (m_FoodPoisonedTicksRemaining > 0)
{
@@ -1939,24 +1942,19 @@ void cPlayer::HandleFood(void)
}
// Apply food exhaustion that has accumulated:
- if (m_FoodExhaustionLevel >= 4)
+ if (m_FoodExhaustionLevel >= 4.0)
{
- m_FoodExhaustionLevel -= 4;
+ m_FoodExhaustionLevel -= 4.0;
- if (m_FoodSaturationLevel >= 1)
+ if (m_FoodSaturationLevel >= 1.0)
{
- m_FoodSaturationLevel -= 1;
+ m_FoodSaturationLevel -= 1.0;
}
else
{
- m_FoodLevel = std::max(m_FoodLevel - 1, 0);
+ SetFoodLevel(m_FoodLevel - 1);
}
}
-
- if (m_FoodLevel != LastFoodLevel)
- {
- SendHealth();
- }
}