From 1ec85a2b2cb285bcc019258c8fddcddfcda84fa8 Mon Sep 17 00:00:00 2001 From: Lane Kolbly Date: Thu, 17 Aug 2017 09:27:43 -0500 Subject: Add cLuaWindow OnClicked Callback (#3901) --- src/Bindings/LuaState.cpp | 11 +++++++++++ src/Bindings/LuaState.h | 1 + src/Bindings/LuaWindow.cpp | 36 +++++++++++++++++++++++++++++++++++- src/Bindings/LuaWindow.h | 12 ++++++++++++ src/Bindings/ManualBindings.cpp | 1 + src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 10 ++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 19 +++++++++++++++++++ src/Bindings/PluginManager.h | 3 +++ src/Entities/Player.cpp | 6 ++++++ src/UI/Window.h | 2 +- 12 files changed, 101 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index e30d0ed5f..07a91f49e 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -875,6 +875,17 @@ void cLuaState::Push(const char * a_Value) +void cLuaState::Push(const cItem & a_Item) +{ + ASSERT(IsValid()); + auto c = new cItem(a_Item); + tolua_pushusertype_and_takeownership(m_LuaState, c, "cItem"); +} + + + + + void cLuaState::Push(const cNil & a_Nil) { ASSERT(IsValid()); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 3d5b1e645..1d2598813 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -614,6 +614,7 @@ public: void Push(const AStringMap & a_Dictionary); void Push(const AStringVector & a_Vector); void Push(const char * a_Value); + void Push(const cItem & a_Item); void Push(const cNil & a_Nil); void Push(const cRef & a_Ref); void Push(const Vector3d & a_Vector); diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index fd714390e..2802c69db 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -9,7 +9,7 @@ #include "PluginLua.h" #include "Root.h" #include "lua/src/lauxlib.h" // Needed for LUA_REFNIL - +#include "ClientHandle.h" @@ -86,6 +86,19 @@ cLuaWindow::~cLuaWindow() +void cLuaWindow::SetOnClicked(cLuaState::cCallbackPtr && a_OnClicked) +{ + // Only one Lua state can be a cLuaWindow object callback: + ASSERT(a_OnClicked->IsSameLuaState(*m_LuaState)); + + // Store the new reference, releasing the old one if appropriate: + m_OnClicked = std::move(a_OnClicked); +} + + + + + void cLuaWindow::SetOnClosing(cLuaState::cCallbackPtr && a_OnClosing) { // Only one Lua state can be a cLuaWindow object callback: @@ -206,3 +219,24 @@ void cLuaWindow::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) + +void cLuaWindow::Clicked(cPlayer & a_Player, int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) +{ + if (m_OnClicked != nullptr) + { + // Plugin can stop a click + if (m_OnClicked->Call(this, &a_Player, a_SlotNum, a_ClickAction, a_ClickedItem)) + { + // Tell the client the actual state of the window + a_Player.GetClientHandle()->SendInventorySlot(-1, -1, a_Player.GetDraggingItem()); + BroadcastWholeWindow(); + return; + } + } + + cWindow::Clicked(a_Player, a_WindowID, a_SlotNum, a_ClickAction, a_ClickedItem); +} + + + + diff --git a/src/Bindings/LuaWindow.h b/src/Bindings/LuaWindow.h index fb21c1c4e..8f3349d00 100644 --- a/src/Bindings/LuaWindow.h +++ b/src/Bindings/LuaWindow.h @@ -49,6 +49,10 @@ public: // tolua_end + /** Sets the Lua callback to call when the player clicks on the window. + The window can stop the click from propogating. */ + void SetOnClicked(cLuaState::cCallbackPtr && a_OnClicked); + /** Sets the Lua callback function to call when the window is about to close */ void SetOnClosing(cLuaState::cCallbackPtr && a_OnClosing); @@ -63,6 +67,9 @@ protected: /** The canon Lua state that has opened the window and owns the m_LuaRef */ cLuaState * m_LuaState; + /** The Lua callback to call when the player clicked on a slot */ + cLuaState::cCallbackPtr m_OnClicked; + /** The Lua callback to call when the window is closing for any player */ cLuaState::cCallbackPtr m_OnClosing; @@ -80,6 +87,11 @@ protected: // cWindow overrides: virtual void OpenedByPlayer(cPlayer & a_Player) override; + virtual void Clicked( + cPlayer & a_Player, int a_WindowID, + short a_SlotNum, eClickAction a_ClickAction, + const cItem & a_ClickedItem + ) override; virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) override; virtual void Destroy(void) override; virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override; diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index e4410dd14..2251c64b9 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -3816,6 +3816,7 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "new", tolua_cLuaWindow_new); tolua_function(tolua_S, "new_local", tolua_cLuaWindow_new_local); tolua_function(tolua_S, ".call", tolua_cLuaWindow_new_local); + tolua_function(tolua_S, "SetOnClicked", tolua_SetObjectCallback); tolua_function(tolua_S, "SetOnClosing", tolua_SetObjectCallback); tolua_function(tolua_S, "SetOnSlotChanged", tolua_SetObjectCallback); tolua_endmodule(tolua_S); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 3276fde67..22e8f15e2 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -80,6 +80,7 @@ public: 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 OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0; + virtual bool OnPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) = 0; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) = 0; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) = 0; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index e3aa63aa1..5af336a95 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -659,6 +659,15 @@ bool cPluginLua::OnEntityTeleport(cEntity & a_Entity, const Vector3d & a_OldPosi +bool cPluginLua::OnPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) +{ + return CallSimpleHooks(cPluginManager::HOOK_PLAYER_OPENING_WINDOW, &a_Player, &a_Window); +} + + + + + bool cPluginLua::OnPlayerPlacedBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange) { return CallSimpleHooks(cPluginManager::HOOK_PLAYER_PLACED_BLOCK, @@ -1056,6 +1065,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) case cPluginManager::HOOK_PLAYER_JOINED: return "OnPlayerJoined"; case cPluginManager::HOOK_PLAYER_LEFT_CLICK: return "OnPlayerLeftClick"; case cPluginManager::HOOK_PLAYER_MOVING: return "OnPlayerMoving"; + case cPluginManager::HOOK_PLAYER_OPENING_WINDOW: return "OnPlayerOpeningWindow"; case cPluginManager::HOOK_PLAYER_PLACED_BLOCK: return "OnPlayerPlacedBlock"; case cPluginManager::HOOK_PLAYER_PLACING_BLOCK: return "OnPlayerPlacingBlock"; case cPluginManager::HOOK_PLAYER_RIGHT_CLICK: return "OnPlayerRightClick"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index ff5e8d726..4de5751e7 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -101,6 +101,7 @@ public: virtual bool OnPlayerJoined (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; virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) override; + virtual bool OnPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) override; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) override; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange) override; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 066ccf9d7..1d977fcde 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -999,6 +999,25 @@ bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d & a +bool cPluginManager::CallHookPlayerOpeningWindow(cPlayer & a_Player, cWindow & a_Window) +{ + FIND_HOOK(HOOK_PLAYER_OPENING_WINDOW); + VERIFY_HOOK; + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPlayerOpeningWindow(a_Player, a_Window)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, const sSetBlock & a_BlockChange) { FIND_HOOK(HOOK_PLAYER_PLACED_BLOCK); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index f38ac8fa1..f3fc3551a 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -24,6 +24,7 @@ class cPickup; class cPlayer; class cPlugin; class cProjectileEntity; +class cWindow; class cWorld; class cSettingsRepositoryInterface; class cDeadlockDetect; @@ -111,6 +112,7 @@ public: HOOK_PLAYER_JOINED, HOOK_PLAYER_LEFT_CLICK, HOOK_PLAYER_MOVING, + HOOK_PLAYER_OPENING_WINDOW, HOOK_PLAYER_PLACED_BLOCK, HOOK_PLAYER_PLACING_BLOCK, HOOK_PLAYER_RIGHT_CLICK, @@ -257,6 +259,7 @@ public: bool CallHookPlayerJoined (cPlayer & a_Player); bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition); + bool CallHookPlayerOpeningWindow (cPlayer & a_Player, cWindow & a_Window); bool CallHookPlayerPlacedBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange); bool CallHookPlayerPlacingBlock (cPlayer & a_Player, const sSetBlock & a_BlockChange); bool CallHookPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 3bbe334fb..3e6d912dd 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1321,10 +1321,16 @@ cTeam * cPlayer::UpdateTeam(void) void cPlayer::OpenWindow(cWindow & a_Window) { + if (cRoot::Get()->GetPluginManager()->CallHookPlayerOpeningWindow(*this, a_Window)) + { + return; + } + if (&a_Window != m_CurrentWindow) { CloseWindow(false); } + a_Window.OpenedByPlayer(*this); m_CurrentWindow = &a_Window; a_Window.SendWholeWindow(*GetClientHandle()); diff --git a/src/UI/Window.h b/src/UI/Window.h index 5bb90a75e..d7a29dc47 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -113,7 +113,7 @@ public: void GetSlots(cPlayer & a_Player, cItems & a_Slots) const; /** Handles a click event from a player */ - void Clicked( + virtual void Clicked( cPlayer & a_Player, int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem -- cgit v1.2.3