diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index a9e834361..1d441d8fb 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -582,10 +582,10 @@ function HandleTestWndCmd(a_Split, a_Player) -- Test out the OnClosing callback's ability to refuse to close the window local attempt = 1; - local OnClosing = function(Window, Player) - Player:SendMessage("Window closing attempt #" .. attempt); + local OnClosing = function(Window, Player, CanRefuse) + Player:SendMessage("Window closing attempt #" .. attempt .. "; CanRefuse = " .. tostring(CanRefuse)); attempt = attempt + 1; - return (attempt <= 3); -- refuse twice, then allow + return CanRefuse and (attempt <= 3); -- refuse twice, then allow, unless CanRefuse is set to true end -- Log the slot changes diff --git a/source/LuaWindow.cpp b/source/LuaWindow.cpp index f6277250c..13d06eeb6 100644 --- a/source/LuaWindow.cpp +++ b/source/LuaWindow.cpp @@ -117,20 +117,20 @@ void cLuaWindow::SetOnSlotChanged(cPlugin_NewLua * a_Plugin, int a_FnRef) -bool cLuaWindow::ClosedByPlayer(cPlayer & a_Player) +bool cLuaWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) { // First notify the plugin through the registered callback: if (m_OnClosingFnRef != LUA_REFNIL) { ASSERT(m_Plugin != NULL); - if (m_Plugin->CallbackWindowClosing(m_OnClosingFnRef, *this, a_Player)) + if (m_Plugin->CallbackWindowClosing(m_OnClosingFnRef, *this, a_Player, a_CanRefuse)) { - // The callback disagrees + // The callback disagrees (the higher levels check the CanRefuse flag compliance) return false; } } - return super::ClosedByPlayer(a_Player); + return super::ClosedByPlayer(a_Player, a_CanRefuse); } diff --git a/source/LuaWindow.h b/source/LuaWindow.h index dc4497df7..de24170df 100644 --- a/source/LuaWindow.h +++ b/source/LuaWindow.h @@ -83,7 +83,7 @@ protected: int m_OnSlotChangedFnRef; // cWindow overrides: - virtual bool ClosedByPlayer(cPlayer & a_Player) override; + virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) override; virtual void Destroy(void) override; // cItemGrid::cListener overrides: diff --git a/source/Player.cpp b/source/Player.cpp index 519837f6a..dd71ca834 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -128,7 +128,7 @@ void cPlayer::Initialize( cWorld* a_World ) void cPlayer::Destroyed() { - CloseWindow(); + CloseWindow(false); m_ClientHandle = NULL; } @@ -437,7 +437,7 @@ void cPlayer::OpenWindow(cWindow * a_Window) { if (a_Window != m_CurrentWindow) { - CloseWindow(); + CloseWindow(false); } a_Window->OpenedByPlayer(*this); m_CurrentWindow = a_Window; @@ -448,7 +448,7 @@ void cPlayer::OpenWindow(cWindow * a_Window) -void cPlayer::CloseWindow(void) +void cPlayer::CloseWindow(bool a_CanRefuse) { if (m_CurrentWindow == NULL) { @@ -456,7 +456,7 @@ void cPlayer::CloseWindow(void) return; } - if (m_CurrentWindow->ClosedByPlayer(*this)) + if (m_CurrentWindow->ClosedByPlayer(*this, a_CanRefuse) || !a_CanRefuse) { // Close accepted, go back to inventory window (the default): m_CurrentWindow = m_InventoryWindow; @@ -473,7 +473,7 @@ void cPlayer::CloseWindow(void) -void cPlayer::CloseWindowIfID(char a_WindowID) +void cPlayer::CloseWindowIfID(char a_WindowID, bool a_CanRefuse) { if ((m_CurrentWindow == NULL) || (m_CurrentWindow->GetWindowID() != a_WindowID)) { diff --git a/source/Player.h b/source/Player.h index 5617b9785..c582c1802 100644 --- a/source/Player.h +++ b/source/Player.h @@ -93,11 +93,11 @@ public: // tolua_begin - /// Closes the current window, resets current window to m_InventoryWindow - void CloseWindow(void); + /// Closes the current window, resets current window to m_InventoryWindow. A plugin may refuse the closing if a_CanRefuse is true + void CloseWindow(bool a_CanRefuse = true); /// Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow - void CloseWindowIfID(char a_WindowID); + void CloseWindowIfID(char a_WindowID, bool a_CanRefuse = true); cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index a76b51806..885184c12 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -1665,7 +1665,7 @@ void cPlugin_NewLua::Unreference(int a_LuaRef) -bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player) +bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player, bool a_CanRefuse) { ASSERT(a_FnRef != LUA_REFNIL); @@ -1673,9 +1673,10 @@ bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPla lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called tolua_pushusertype(m_LuaState, &a_Window, "cWindow"); tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + tolua_pushboolean (m_LuaState, a_CanRefuse ? 1 : 0); // Call function: - int s = lua_pcall(m_LuaState, 2, 1, 0); + int s = lua_pcall(m_LuaState, 3, 1, 0); if (report_errors(m_LuaState, s)) { LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index 34ab85ca4..de6077a55 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -106,7 +106,7 @@ public: void Unreference(int a_LuaRef); /// Calls the plugin-specified "cLuaWindow closing" callback. Returns true only if the callback returned true - bool CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player); + bool CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player, bool a_CanRefuse); /// Calls the plugin-specified "cLuaWindow slot changed" callback. void CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, int a_SlotNum); diff --git a/source/UI/Window.cpp b/source/UI/Window.cpp index f353d0721..3c28f33b0 100644 --- a/source/UI/Window.cpp +++ b/source/UI/Window.cpp @@ -251,7 +251,7 @@ void cWindow::OpenedByPlayer(cPlayer & a_Player) -bool cWindow::ClosedByPlayer(cPlayer & a_Player) +bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) { // Checks whether the player is still holding an item if (a_Player.IsDraggingItem()) diff --git a/source/UI/Window.h b/source/UI/Window.h index 68774aa59..0ff87dc70 100644 --- a/source/UI/Window.h +++ b/source/UI/Window.h @@ -108,7 +108,7 @@ public: void OpenedByPlayer(cPlayer & a_Player); /// Called when a player closes this window; notifies all slot areas. Returns true if close accepted - virtual bool ClosedByPlayer(cPlayer & a_Player); + virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse); void SendWholeWindow(cClientHandle & a_Client); void BroadcastWholeWindow(void);