From 9684f90f8361fb314a60a387dc9ecf9bc4c3062a Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Thu, 30 May 2013 19:34:09 +0000 Subject: [PATCH] LuaWindow: Initial code, the window can be opened, but not much manipulated git-svn-id: http://mc-server.googlecode.com/svn/trunk@1532 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- MCServer/Plugins/Debuggers/Debuggers.lua | 69 ++- VC2008/MCServer.vcproj | 16 + source/AllToLua.pkg | 6 + source/Bindings.cpp | 594 ++++++++++++++++++++++- source/Bindings.h | 2 +- source/ClientHandle.cpp | 2 +- source/LuaWindow.cpp | 91 ++++ source/LuaWindow.h | 78 +++ source/ManualBindings.cpp | 80 ++- source/Player.cpp | 29 +- source/Player.h | 24 +- source/Plugin_NewLua.cpp | 10 + source/Plugin_NewLua.h | 7 +- source/UI/SlotArea.cpp | 31 ++ source/UI/SlotArea.h | 26 +- source/UI/Window.cpp | 37 +- source/UI/Window.h | 37 +- 17 files changed, 1077 insertions(+), 62 deletions(-) create mode 100644 source/LuaWindow.cpp create mode 100644 source/LuaWindow.h diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index edb638e22..076cec9ca 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -1,7 +1,7 @@ -- Global variables PLUGIN = {}; -- Reference to own plugin object -ShouldDumpFunctions = true; -- If set to true, all available functions are logged upon plugin initialization +ShouldDumpFunctions = true; -- If set to true, all available functions are written to the API.txt file upon plugin initialization g_DropSpensersToActivate = {}; -- A list of dispensers and droppers (as {World, X, Y Z} quadruplets) that are to be activated every tick @@ -21,9 +21,11 @@ function Initialize(Plugin) PluginManager:AddHook(Plugin, cPluginManager.HOOK_TAKE_DAMAGE); PluginManager:AddHook(Plugin, cPluginManager.HOOK_TICK); - PluginManager:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "Shows a list of all the loaded entities"); - PluginManager:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "Kills all the loaded entities"); - PluginManager:BindCommand("/wool", "debuggers", HandleWoolCmd, "Sets all your armor to blue wool"); + PluginManager:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "Shows a list of all the loaded entities"); + PluginManager:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "Kills all the loaded entities"); + PluginManager:BindCommand("/wool", "debuggers", HandleWoolCmd, "Sets all your armor to blue wool"); + PluginManager:BindCommand("/testwnd", "debuggers", HandleTestWndCmd, "Opens up a window using plugin API"); + PluginManager:BindCommand("/gc", "debuggers", HandleGCCmd, "Activates the Lua garbage collector"); -- Enable the following line for BlockArea / Generator interface testing: -- PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); @@ -443,6 +445,13 @@ end +--- When set to a positive number, the following OnTick() will perform GC and decrease until 0 again +GCOnTick = 0; + + + + + function OnTick() -- Activate all dropspensers in the g_DropSpensersToActivate list: local ActivateDrSp = function(DropSpenser) @@ -461,6 +470,13 @@ function OnTick() end end + + -- If GCOnTick > 0, do a garbage-collect and decrease by one + if (GCOnTick > 0) then + collectgarbage(); + GCOnTick = GCOnTick - 1; + end + return false; end @@ -545,4 +561,47 @@ function HandleWoolCmd(Split, Player) Player:GetInventory():SetArmorSlot(3, Wool); Player:SendMessage("You have been bluewooled :)"); return true; -end \ No newline at end of file +end + + + + + +function HandleTestWndCmd(a_Split, a_Player) + local WindowType = cWindow.Hopper; + local WindowSizeX = 5; + local WindowSizeY = 1; + if (#a_Split == 4) then + WindowType = tonumber(a_Split[2]); + WindowSizeX = tonumber(a_Split[3]); + WindowSizeY = tonumber(a_Split[4]); + elseif (#a_Split ~= 1) then + a_Player:SendMessage("Usage: /testwnd [WindowType WindowSizeX WindowSizeY]"); + return true; + end + + local Window = cLuaWindow(WindowType, WindowSizeX, WindowSizeY, "TestWnd"); + Window:SetSlot(a_Player, 0, cItem(E_ITEM_DIAMOND, 64)); + + a_Player:OpenWindow(Window); + + -- To make sure that the object has the correct life-management in Lua, + -- let's garbage-collect in the following few ticks + GCOnTick = 10; + + return true; +end + + + + + +function HandleGCCmd(a_Split, a_Player) + collectgarbage(); + return true; +end + + + + + diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 7a4a65a20..2d0e9d94e 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -1457,6 +1457,14 @@ RelativePath="..\source\LuaFunctions.h" > + + + + @@ -2557,6 +2565,14 @@ > + + + + diff --git a/source/AllToLua.pkg b/source/AllToLua.pkg index 736cd3ca1..1cb57ebd0 100644 --- a/source/AllToLua.pkg +++ b/source/AllToLua.pkg @@ -59,3 +59,9 @@ $cfile "Group.h" $cfile "BlockArea.h" $cfile "Generating/ChunkDesc.h" $cfile "CraftingRecipes.h" +$cfile "UI/Window.h" +$cfile "LuaWindow.h" + + + + diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 1b5e1193d..417943226 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/28/13 21:11:42. +** Generated automatically by tolua++-1.0.92 on 05/30/13 21:32:45. */ #ifndef __cplusplus @@ -58,10 +58,19 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "BlockArea.h" #include "Generating/ChunkDesc.h" #include "CraftingRecipes.h" +#include "UI/Window.h" +#include "LuaWindow.h" /* function to release collected object via destructor */ #ifdef __cplusplus +static int tolua_collect_cIniFile (lua_State* tolua_S) +{ + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + static int tolua_collect_cCraftingGrid (lua_State* tolua_S) { cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); @@ -153,9 +162,9 @@ static int tolua_collect_cTracer (lua_State* tolua_S) return 0; } -static int tolua_collect_cIniFile (lua_State* tolua_S) +static int tolua_collect_cLuaWindow (lua_State* tolua_S) { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + cLuaWindow* self = (cLuaWindow*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -175,10 +184,12 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"TakeDamageInfo"); tolua_usertype(tolua_S,"cCraftingRecipe"); tolua_usertype(tolua_S,"cPlugin_NewLua"); + tolua_usertype(tolua_S,"cCraftingGrid"); tolua_usertype(tolua_S,"cStringMap"); tolua_usertype(tolua_S,"cItemGrid"); tolua_usertype(tolua_S,"cBlockArea"); - tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cWindow"); + tolua_usertype(tolua_S,"cLuaWindow"); tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cRoot"); tolua_usertype(tolua_S,"cStairs"); @@ -8531,6 +8542,102 @@ static int tolua_AllToLua_cPlayer_MoveTo00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetWindow of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetWindow00 +static int tolua_AllToLua_cPlayer_GetWindow00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWindow'", NULL); +#endif + { + cWindow* tolua_ret = (cWindow*) self->GetWindow(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWindow"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWindow'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CloseWindow of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CloseWindow00 +static int tolua_AllToLua_cPlayer_CloseWindow00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CloseWindow'", NULL); +#endif + { + self->CloseWindow(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CloseWindow'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CloseWindowIfID of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CloseWindowIfID00 +static int tolua_AllToLua_cPlayer_CloseWindowIfID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + char a_WindowID = ((char) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CloseWindowIfID'", NULL); +#endif + { + self->CloseWindowIfID(a_WindowID); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CloseWindowIfID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetClientHandle of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetClientHandle00 static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S) @@ -25478,6 +25585,447 @@ static int tolua_AllToLua_cCraftingRecipe_Dump00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetWindowID of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_GetWindowID00 +static int tolua_AllToLua_cWindow_GetWindowID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWindow",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWindow* self = (const cWindow*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWindowID'", NULL); +#endif + { + char tolua_ret = (char) self->GetWindowID(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWindowID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWindowType of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_GetWindowType00 +static int tolua_AllToLua_cWindow_GetWindowType00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWindow",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWindow* self = (const cWindow*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWindowType'", NULL); +#endif + { + int tolua_ret = (int) self->GetWindowType(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWindowType'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSlot of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_GetSlot00 +static int tolua_AllToLua_cWindow_GetSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWindow",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWindow* self = (const cWindow*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSlot'", NULL); +#endif + { + const cItem* tolua_ret = (const cItem*) self->GetSlot(*a_Player,a_SlotNum); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetSlot of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_SetSlot00 +static int tolua_AllToLua_cWindow_SetSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWindow",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWindow* self = (cWindow*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,3,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetSlot'", NULL); +#endif + { + self->SetSlot(*a_Player,a_SlotNum,*a_Item); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsSlotInPlayerMainInventory of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_IsSlotInPlayerMainInventory00 +static int tolua_AllToLua_cWindow_IsSlotInPlayerMainInventory00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWindow",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWindow* self = (const cWindow*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsSlotInPlayerMainInventory'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsSlotInPlayerMainInventory(a_SlotNum); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsSlotInPlayerMainInventory'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsSlotInPlayerHotbar of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_IsSlotInPlayerHotbar00 +static int tolua_AllToLua_cWindow_IsSlotInPlayerHotbar00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWindow",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWindow* self = (const cWindow*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsSlotInPlayerHotbar'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsSlotInPlayerHotbar(a_SlotNum); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsSlotInPlayerHotbar'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsSlotInPlayerInventory of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_IsSlotInPlayerInventory00 +static int tolua_AllToLua_cWindow_IsSlotInPlayerInventory00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWindow",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWindow* self = (const cWindow*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsSlotInPlayerInventory'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsSlotInPlayerInventory(a_SlotNum); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsSlotInPlayerInventory'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWindowTitle of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_GetWindowTitle00 +static int tolua_AllToLua_cWindow_GetWindowTitle00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWindow",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWindow* self = (const cWindow*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWindowTitle'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetWindowTitle(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWindowTitle'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetWindowTitle of class cWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWindow_SetWindowTitle00 +static int tolua_AllToLua_cWindow_SetWindowTitle00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWindow",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWindow* self = (cWindow*) tolua_tousertype(tolua_S,1,0); + const AString a_WindowTitle = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWindowTitle'", NULL); +#endif + { + self->SetWindowTitle(a_WindowTitle); + tolua_pushcppstring(tolua_S,(const char*)a_WindowTitle); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetWindowTitle'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cLuaWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaWindow_new00 +static int tolua_AllToLua_cLuaWindow_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cLuaWindow",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_iscppstring(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWindow::WindowType a_WindowType = ((cWindow::WindowType) (int) tolua_tonumber(tolua_S,2,0)); + int a_SlotsX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_SlotsY = ((int) tolua_tonumber(tolua_S,4,0)); + const AString a_Title = ((const AString) tolua_tocppstring(tolua_S,5,0)); + { + cLuaWindow* tolua_ret = (cLuaWindow*) Mtolua_new((cLuaWindow)(a_WindowType,a_SlotsX,a_SlotsY,a_Title)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cLuaWindow"); + tolua_pushcppstring(tolua_S,(const char*)a_Title); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cLuaWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaWindow_new00_local +static int tolua_AllToLua_cLuaWindow_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cLuaWindow",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_iscppstring(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWindow::WindowType a_WindowType = ((cWindow::WindowType) (int) tolua_tonumber(tolua_S,2,0)); + int a_SlotsX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_SlotsY = ((int) tolua_tonumber(tolua_S,4,0)); + const AString a_Title = ((const AString) tolua_tocppstring(tolua_S,5,0)); + { + cLuaWindow* tolua_ret = (cLuaWindow*) Mtolua_new((cLuaWindow)(a_WindowType,a_SlotsX,a_SlotsY,a_Title)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cLuaWindow"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + tolua_pushcppstring(tolua_S,(const char*)a_Title); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cLuaWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaWindow_delete00 +static int tolua_AllToLua_cLuaWindow_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaWindow",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaWindow* self = (cLuaWindow*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetContents of class cLuaWindow */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaWindow_GetContents00 +static int tolua_AllToLua_cLuaWindow_GetContents00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaWindow",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaWindow* self = (cLuaWindow*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetContents'", NULL); +#endif + { + cItemGrid& tolua_ret = (cItemGrid&) self->GetContents(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItemGrid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetContents'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* Open function */ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) { @@ -26421,6 +26969,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SetLastBlockActionTime",tolua_AllToLua_cPlayer_SetLastBlockActionTime00); tolua_function(tolua_S,"SetGameMode",tolua_AllToLua_cPlayer_SetGameMode00); tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00); + tolua_function(tolua_S,"GetWindow",tolua_AllToLua_cPlayer_GetWindow00); + tolua_function(tolua_S,"CloseWindow",tolua_AllToLua_cPlayer_CloseWindow00); + tolua_function(tolua_S,"CloseWindowIfID",tolua_AllToLua_cPlayer_CloseWindowIfID00); tolua_function(tolua_S,"GetClientHandle",tolua_AllToLua_cPlayer_GetClientHandle00); tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cPlayer_SendMessage00); tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlayer_GetName00); @@ -27156,6 +27707,41 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"ConsumeIngredients",tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00); tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingRecipe_Dump00); tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cWindow","cWindow","",NULL); + tolua_beginmodule(tolua_S,"cWindow"); + tolua_constant(tolua_S,"Inventory",cWindow::Inventory); + tolua_constant(tolua_S,"Chest",cWindow::Chest); + tolua_constant(tolua_S,"Workbench",cWindow::Workbench); + tolua_constant(tolua_S,"Furnace",cWindow::Furnace); + tolua_constant(tolua_S,"DropSpenser",cWindow::DropSpenser); + tolua_constant(tolua_S,"Enchantment",cWindow::Enchantment); + tolua_constant(tolua_S,"Brewery",cWindow::Brewery); + tolua_constant(tolua_S,"NPCTrade",cWindow::NPCTrade); + tolua_constant(tolua_S,"Beacon",cWindow::Beacon); + tolua_constant(tolua_S,"Anvil",cWindow::Anvil); + tolua_constant(tolua_S,"Hopper",cWindow::Hopper); + tolua_function(tolua_S,"GetWindowID",tolua_AllToLua_cWindow_GetWindowID00); + tolua_function(tolua_S,"GetWindowType",tolua_AllToLua_cWindow_GetWindowType00); + tolua_function(tolua_S,"GetSlot",tolua_AllToLua_cWindow_GetSlot00); + tolua_function(tolua_S,"SetSlot",tolua_AllToLua_cWindow_SetSlot00); + tolua_function(tolua_S,"IsSlotInPlayerMainInventory",tolua_AllToLua_cWindow_IsSlotInPlayerMainInventory00); + tolua_function(tolua_S,"IsSlotInPlayerHotbar",tolua_AllToLua_cWindow_IsSlotInPlayerHotbar00); + tolua_function(tolua_S,"IsSlotInPlayerInventory",tolua_AllToLua_cWindow_IsSlotInPlayerInventory00); + tolua_function(tolua_S,"GetWindowTitle",tolua_AllToLua_cWindow_GetWindowTitle00); + tolua_function(tolua_S,"SetWindowTitle",tolua_AllToLua_cWindow_SetWindowTitle00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cLuaWindow","cLuaWindow","cWindow",tolua_collect_cLuaWindow); + #else + tolua_cclass(tolua_S,"cLuaWindow","cLuaWindow","cWindow",NULL); + #endif + tolua_beginmodule(tolua_S,"cLuaWindow"); + tolua_function(tolua_S,"new",tolua_AllToLua_cLuaWindow_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cLuaWindow_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cLuaWindow_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_cLuaWindow_delete00); + tolua_function(tolua_S,"GetContents",tolua_AllToLua_cLuaWindow_GetContents00); + tolua_endmodule(tolua_S); tolua_endmodule(tolua_S); return 1; } diff --git a/source/Bindings.h b/source/Bindings.h index b508452c7..0a25bec3d 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/28/13 21:11:43. +** Generated automatically by tolua++-1.0.92 on 05/30/13 21:32:45. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 501568fc6..a57e71374 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -1002,7 +1002,7 @@ void cClientHandle::HandleSlotSelected(short a_SlotNum) void cClientHandle::HandleWindowClose(char a_WindowID) { - m_Player->CloseWindow(a_WindowID); + m_Player->CloseWindowIfID(a_WindowID); } diff --git a/source/LuaWindow.cpp b/source/LuaWindow.cpp new file mode 100644 index 000000000..d7b67d552 --- /dev/null +++ b/source/LuaWindow.cpp @@ -0,0 +1,91 @@ + +// LuaWindow.cpp + +// Implements the cLuaWindow class representing a virtual window that plugins may create and open for the player + +#include "Globals.h" +#include "LuaWindow.h" +#include "UI/SlotArea.h" +#include "Plugin_NewLua.h" +#include "lauxlib.h" // Needed for LUA_REFNIL + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLuaWindow: + +cLuaWindow::cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title) : + super(a_WindowType, a_Title), + m_Contents(a_SlotsX, a_SlotsY), + m_Plugin(NULL), + m_LuaRef(LUA_REFNIL) +{ + m_SlotAreas.push_back(new cSlotAreaItemGrid(m_Contents, *this)); + + // If appropriate, add an Armor slot area: + switch (a_WindowType) + { + case cWindow::Inventory: + case cWindow::Workbench: + { + m_SlotAreas.push_back(new cSlotAreaArmor(*this)); + break; + } + } + m_SlotAreas.push_back(new cSlotAreaInventory(*this)); + m_SlotAreas.push_back(new cSlotAreaHotBar(*this)); +} + + + + + +cLuaWindow::~cLuaWindow() +{ + ASSERT(m_OpenedBy.empty()); +} + + + + + +void cLuaWindow::SetLuaRef(cPlugin_NewLua * a_Plugin, int a_LuaRef) +{ + ASSERT(m_Plugin == NULL); + ASSERT(m_LuaRef == LUA_REFNIL); + m_Plugin = a_Plugin; + m_LuaRef = a_LuaRef; +} + + + + + +bool cLuaWindow::IsLuaReferenced(void) const +{ + return ((m_Plugin != NULL) && (m_LuaRef != LUA_REFNIL)); +} + + + + + +void cLuaWindow::Destroy(void) +{ + super::Destroy(); + + if ((m_LuaRef != LUA_REFNIL) && (m_Plugin != NULL)) + { + // The object is referenced by Lua, un-reference it + m_Plugin->Unreference(m_LuaRef); + } + + // Lua will take care of this object, it will garbage-collect it, so we *must not* delete it! + m_IsDestroyed = false; +} + + + + diff --git a/source/LuaWindow.h b/source/LuaWindow.h new file mode 100644 index 000000000..c474fa1ab --- /dev/null +++ b/source/LuaWindow.h @@ -0,0 +1,78 @@ + +// LuaWindow.h + +// Declares the cLuaWindow class representing a virtual window that plugins may create and open for the player + + + + + +#pragma once + +#include "UI/Window.h" + + + + + +// fwd: Plugin_NewLua.h +class cPlugin_NewLua; + + + + + +// tolua_begin + +/** A window that has been created by a Lua plugin and is handled entirely by that plugin +This object needs extra care with its lifetime management: +- It is created by Lua, so Lua expects to garbage-collect it later +- normal cWindow objects are deleted in their ClosedByPlayer() function if the last player closes them +To overcome this, this object overloads the Destroy functions, which doesn't let the ClosedByPlayer() +delete the window, but rather leaves it dangling, with only Lua having the reference to it. +Additionally, to forbid Lua from deleting this object while it is used by players, the manual bindings for +cPlayer:OpenWindow check if the window is of this class, and if so, make a global Lua reference for this object. +This reference needs to be unreferenced in the Destroy() function. +*/ +class cLuaWindow : + public cWindow +{ + typedef cWindow super; + +public: + /// Create a window of the specified type, with a slot grid of a_SlotsX * a_SlotsY size + cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title); + + virtual ~cLuaWindow(); + + /// Returns the internal representation of the contents that are manipulated by Lua + cItemGrid & GetContents(void) { return m_Contents; } + + // tolua_end + + /** Sets the plugin reference and the internal Lua object reference index + used for preventing Lua's GC to collect this class while the window is open + */ + void SetLuaRef(cPlugin_NewLua * a_Plugin, int a_LuaRef); + + /// Returns true if SetLuaRef() has been called + bool IsLuaReferenced(void) const; + +protected: + /// Contents of the non-inventory part + cItemGrid m_Contents; + + /// The plugin that has opened the window and owns the m_LuaRef + cPlugin_NewLua * m_Plugin; + + /// The Lua object reference, used for keeping the object alive as long as any player has the window open + int m_LuaRef; + + // cWindow overrides: + virtual void Destroy(void) override; +} ; // tolua_export + + + + + diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 4fb801da9..ceb24da30 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -18,6 +18,7 @@ #include "BlockEntities/DropperEntity.h" #include "BlockEntities/FurnaceEntity.h" #include "md5/md5.h" +#include "LuaWindow.h" @@ -150,6 +151,25 @@ static int tolua_LOGERROR(lua_State* tolua_S) +cPlugin_NewLua * GetLuaPlugin(lua_State * L) +{ + // Get the plugin identification out of LuaState: + lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME); + if (!lua_islightuserdata(L, -1)) + { + LOGERROR("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); + return NULL; + } + cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1); + lua_pop(L, 1); + + return Plugin; +} + + + + + template< class Ty1, class Ty2, @@ -710,15 +730,11 @@ static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) static int tolua_cPluginManager_BindCommand(lua_State * L) { // Function signature: cPluginManager:BindCommand(Command, Permission, Function, HelpString) - - // Get the plugin identification out of LuaState: - lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME); - if (!lua_islightuserdata(L, -1)) + cPlugin_NewLua * Plugin = GetLuaPlugin(L); + if (Plugin == NULL) { - LOGERROR("cPluginManager:BindCommand() cannot get plugin instance, what have you done to my Lua state? Command-binding aborted."); + return 0; } - cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1); - lua_pop(L, 1); // Read the arguments to this API call: tolua_Error tolua_err; @@ -873,6 +889,55 @@ static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S) +static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) +{ + // Function signature: cPlayer:OpenWindow(Window) + + // Retrieve the plugin instance from the Lua state + cPlugin_NewLua * Plugin = GetLuaPlugin(tolua_S); + if (Plugin == NULL) + { + return 0; + } + + // Get the parameters: + cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); + cWindow * wnd = (cWindow *)tolua_tousertype(tolua_S, 2, NULL); + if ((self == NULL) || (wnd == NULL)) + { + LOGWARNING("%s: invalid self (%p) or wnd (%p)", __FUNCTION__, self, wnd); + return 0; + } + + // If cLuaWindow, add a reference, so that Lua won't delete the cLuaWindow object mid-processing + tolua_Error err; + if (tolua_isusertype(tolua_S, 2, "cLuaWindow", 0, &err)) + { + cLuaWindow * LuaWnd = (cLuaWindow *)wnd; + // Only if not already referenced + if (!LuaWnd->IsLuaReferenced()) + { + int LuaRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (LuaRef == LUA_REFNIL) + { + LOGWARNING("%s: Cannot create a window reference. Cannot open window \"%s\".", + __FUNCTION__, wnd->GetWindowTitle().c_str() + ); + return 0; + } + LuaWnd->SetLuaRef(Plugin, LuaRef); + } + } + + // Open the window + self->OpenWindow(wnd); + return 0; +} + + + + + static int tolua_cPlugin_NewLua_AddWebTab(lua_State * tolua_S) { cPlugin_NewLua * self = (cPlugin_NewLua*)tolua_tousertype(tolua_S,1,0); @@ -1197,6 +1262,7 @@ void ManualBindings::Bind( lua_State* tolua_S ) tolua_beginmodule(tolua_S, "cPlayer"); tolua_function(tolua_S, "GetGroups", tolua_cPlayer_GetGroups); tolua_function(tolua_S, "GetResolvedPermissions", tolua_cPlayer_GetResolvedPermissions); + tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlugin_NewLua"); diff --git a/source/Player.cpp b/source/Player.cpp index d659c949a..254e58655 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -128,7 +128,7 @@ void cPlayer::Initialize( cWorld* a_World ) void cPlayer::Destroyed() { - CloseWindow(-1); + CloseWindow(); m_ClientHandle = NULL; } @@ -433,9 +433,9 @@ Vector3d cPlayer::GetEyePosition() -void cPlayer::OpenWindow( cWindow* a_Window ) +void cPlayer::OpenWindow(cWindow * a_Window) { - CloseWindow(m_CurrentWindow ? (char)m_CurrentWindow->GetWindowType() : 0); + CloseWindow(); a_Window->OpenedByPlayer(*this); m_CurrentWindow = a_Window; } @@ -444,12 +444,29 @@ void cPlayer::OpenWindow( cWindow* a_Window ) -void cPlayer::CloseWindow(char a_WindowType) +void cPlayer::CloseWindow(void) { - if (m_CurrentWindow != NULL) + if (m_CurrentWindow == NULL) { - m_CurrentWindow->ClosedByPlayer(*this); + m_CurrentWindow = m_InventoryWindow; + return; } + + m_CurrentWindow->ClosedByPlayer(*this); + m_CurrentWindow = m_InventoryWindow; +} + + + + + +void cPlayer::CloseWindowIfID(char a_WindowID) +{ + if ((m_CurrentWindow == NULL) || (m_CurrentWindow->GetWindowID() != a_WindowID)) + { + return; + } + m_CurrentWindow->ClosedByPlayer(*this); m_CurrentWindow = m_InventoryWindow; } diff --git a/source/Player.h b/source/Player.h index 82a932cd0..5617b9785 100644 --- a/source/Player.h +++ b/source/Player.h @@ -85,18 +85,28 @@ public: /// Tries to move to a new position, with collision checks and stuff virtual void MoveTo( const Vector3d & a_NewPos ); // tolua_export - cWindow * GetWindow(void) { return m_CurrentWindow; } + cWindow * GetWindow(void) { return m_CurrentWindow; } // tolua_export const cWindow * GetWindow(void) const { return m_CurrentWindow; } - void OpenWindow( cWindow* a_Window ); - void CloseWindow(char a_WindowType); + /// Opens the specified window; closes the current one first using CloseWindow() + void OpenWindow(cWindow * a_Window); // Exported in ManualBindings.cpp + + // tolua_begin + + /// Closes the current window, resets current window to m_InventoryWindow + void CloseWindow(void); + + /// Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow + void CloseWindowIfID(char a_WindowID); - cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } // tolua_export + cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } - void SendMessage(const AString & a_Message); // tolua_export + void SendMessage(const AString & a_Message); - const AString & GetName(void) const { return m_PlayerName; } // tolua_export - void SetName(const AString & a_Name) { m_PlayerName = a_Name; } // tolua_export + const AString & GetName(void) const { return m_PlayerName; } + void SetName(const AString & a_Name) { m_PlayerName = a_Name; } + + // tolua_end typedef std::list< cGroup* > GroupList; typedef std::list< std::string > StringList; diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index 9afe78e93..df18cfa9b 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -1655,6 +1655,16 @@ void cPlugin_NewLua::BindConsoleCommand(const AString & a_Command, int a_FnRef) +void cPlugin_NewLua::Unreference(int a_LuaRef) +{ + cCSLock Lock(m_CriticalSection); + luaL_unref(m_LuaState, LUA_REGISTRYINDEX, a_LuaRef); +} + + + + + // Helper functions bool cPlugin_NewLua::PushFunction(const char * a_FunctionName, bool a_bLogError /* = true */) { diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index 8ba22477a..acc43c7a4 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -94,9 +94,12 @@ public: /// Binds the console command to call the function specified by a Lua function reference. Simply adds to CommandMap. void BindConsoleCommand(const AString & a_Command, int a_FnRef); - lua_State* GetLuaState() { return m_LuaState; } + lua_State * GetLuaState(void) { return m_LuaState; } - cCriticalSection & GetCriticalSection() { return m_CriticalSection; } + cCriticalSection & GetCriticalSection(void) { return m_CriticalSection; } + + /// Removes a previously referenced object (luaL_unref()) + void Unreference(int a_LuaRef); protected: cCriticalSection m_CriticalSection; diff --git a/source/UI/SlotArea.cpp b/source/UI/SlotArea.cpp index 0d26edbb7..8333d0574 100644 --- a/source/UI/SlotArea.cpp +++ b/source/UI/SlotArea.cpp @@ -657,6 +657,37 @@ void cSlotAreaArmor::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bo +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cSlotAreaItemGrid: + +cSlotAreaItemGrid::cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentWindow) : + super(a_ItemGrid.GetNumSlots(), a_ParentWindow), + m_ItemGrid(a_ItemGrid) +{ +} + + + + + +const cItem * cSlotAreaItemGrid::GetSlot(int a_SlotNum, cPlayer & a_Player) const +{ + return &m_ItemGrid.GetSlot(a_SlotNum); +} + + + + + +void cSlotAreaItemGrid::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) +{ + m_ItemGrid.SetSlot(a_SlotNum, a_Item); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cSlotAreaTemporary: diff --git a/source/UI/SlotArea.h b/source/UI/SlotArea.h index cdf14baad..0ad5296db 100644 --- a/source/UI/SlotArea.h +++ b/source/UI/SlotArea.h @@ -89,7 +89,7 @@ protected: -/// Handles the "inner" inventory of each player, excluding the armor and hotbar +/// Handles the main inventory of each player, excluding the armor and hotbar class cSlotAreaInventory : public cSlotAreaInventoryBase { @@ -106,7 +106,7 @@ public: -/// Handles the "outer" inevntory of each player - the hotbar +/// Handles the hotbar of each player class cSlotAreaHotBar : public cSlotAreaInventoryBase { @@ -123,7 +123,7 @@ public: -/// Handles the armor area of the inventory +/// Handles the armor area of the player's inventory class cSlotAreaArmor : public cSlotAreaInventoryBase { @@ -141,6 +141,26 @@ public: +/// Handles any slot area that is representing a cItemGrid; same items for all the players +class cSlotAreaItemGrid : + public cSlotArea +{ + typedef cSlotArea super; + +public: + cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentWindow); + + virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; + virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; + +protected: + cItemGrid & m_ItemGrid; +} ; + + + + + /** A cSlotArea with items layout that is private to each player and is temporary, such as a crafting grid or an enchantment table. This common ancestor stores the items in a per-player map. It also implements tossing items from the map. diff --git a/source/UI/Window.cpp b/source/UI/Window.cpp index 2b279a22c..661f9f62f 100644 --- a/source/UI/Window.cpp +++ b/source/UI/Window.cpp @@ -101,6 +101,39 @@ void cWindow::SetSlot(cPlayer & a_Player, int a_SlotNum, const cItem & a_Item) +bool cWindow::IsSlotInPlayerMainInventory(int a_SlotNum) const +{ + // Returns true if the specified slot is in the Player Main Inventory slotarea + // The player main inventory is always 27 slots, 9 slots from the end of the inventory + return ((a_SlotNum >= GetNumSlots() - 36) && (a_SlotNum < GetNumSlots() - 9)); +} + + + + + +bool cWindow::IsSlotInPlayerHotbar(int a_SlotNum) const +{ + // Returns true if the specified slot is in the Player Hotbar slotarea + // The hotbar is always the last 9 slots + return ((a_SlotNum >= GetNumSlots() - 9) && (a_SlotNum < GetNumSlots())); +} + + + + + +bool cWindow::IsSlotInPlayerInventory(int a_SlotNum) const +{ + // Returns true if the specified slot is in the Player Main Inventory or Hotbar slotareas. Note that returns false for Armor. + // The player combined inventory is always the last 36 slots + return ((a_SlotNum >= GetNumSlots() - 36) && (a_SlotNum < GetNumSlots())); +} + + + + + void cWindow::GetSlots(cPlayer & a_Player, cItems & a_Slots) const { a_Slots.clear(); @@ -264,9 +297,9 @@ void cWindow::OwnerDestroyed() // Close window for each player. Note that the last one needs special handling while (m_OpenedBy.size() > 1) { - (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); + (*m_OpenedBy.begin() )->CloseWindow(); } - (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); + (*m_OpenedBy.begin() )->CloseWindow(); } diff --git a/source/UI/Window.h b/source/UI/Window.h index c31ed8a4d..1f2495a46 100644 --- a/source/UI/Window.h +++ b/source/UI/Window.h @@ -68,7 +68,7 @@ public: cWindow(WindowType a_WindowType, const AString & a_WindowTitle); virtual ~cWindow(); - char GetWindowID(void) const { return m_WindowID; } + char GetWindowID(void) const { return m_WindowID; } // tolua_export int GetWindowType(void) const { return m_WindowType; } // tolua_export cWindowOwner * GetOwner(void) { return m_Owner; } @@ -84,6 +84,15 @@ public: /// Sets the item to the specified slot for the specified player void SetSlot(cPlayer & a_Player, int a_SlotNum, const cItem & a_Item); + /// Returns true if the specified slot is in the Player Main Inventory slotarea + bool IsSlotInPlayerMainInventory(int a_SlotNum) const; + + /// Returns true if the specified slot is in the Player Hotbar slotarea + bool IsSlotInPlayerHotbar(int a_SlotNum) const; + + /// Returns true if the specified slot is in the Player Main Inventory or Hotbar slotareas. Note that returns false for Armor. + bool IsSlotInPlayerInventory(int a_SlotNum) const; + // tolua_end /// Fills a_Slots with the slots read from m_SlotAreas[], for the specified player @@ -144,7 +153,8 @@ protected: static char m_WindowIDCounter; - void Destroy(void); + /// Sets the internal flag as "destroyed"; notifies the owner that the window is destroying + virtual void Destroy(void); /** Returns the correct slot area for the specified window-global SlotNum Also returns the area-local SlotNum corresponding to the GlobalSlotNum @@ -173,7 +183,7 @@ protected: /// Distributes a_NumToEachSlot items into the slots specified in a_SlotNums; returns the total number of items distributed int DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int a_NumToEachSlot, const cSlotNums & a_SlotNums); -} ; +} ; // tolua_export @@ -244,24 +254,3 @@ protected: - -// tolua_begin - -/// A window that has been created by a Lua plugin and is handled entirely by that plugin -class cLuaWindow : - public cWindow -{ -public: - /// Create a window of the specified type, with a slot grid of a_SlotsX * a_SlotsY size - cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title); - - // tolua_end - -protected: - /// Contents of the non-inventory part - cItemGrid m_Contents; -} ; - - - -