summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-05-30 21:34:09 +0200
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-05-30 21:34:09 +0200
commit9684f90f8361fb314a60a387dc9ecf9bc4c3062a (patch)
tree37e595d7f4b6fdd51b18943db2be6b538ea1caea
parentProtoProxy: Added a note in the documentation about the need to switch off username verification (diff)
downloadcuberite-9684f90f8361fb314a60a387dc9ecf9bc4c3062a.tar
cuberite-9684f90f8361fb314a60a387dc9ecf9bc4c3062a.tar.gz
cuberite-9684f90f8361fb314a60a387dc9ecf9bc4c3062a.tar.bz2
cuberite-9684f90f8361fb314a60a387dc9ecf9bc4c3062a.tar.lz
cuberite-9684f90f8361fb314a60a387dc9ecf9bc4c3062a.tar.xz
cuberite-9684f90f8361fb314a60a387dc9ecf9bc4c3062a.tar.zst
cuberite-9684f90f8361fb314a60a387dc9ecf9bc4c3062a.zip
Diffstat (limited to '')
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua69
-rw-r--r--VC2008/MCServer.vcproj16
-rw-r--r--source/AllToLua.pkg6
-rw-r--r--source/Bindings.cpp594
-rw-r--r--source/Bindings.h2
-rw-r--r--source/ClientHandle.cpp2
-rw-r--r--source/LuaWindow.cpp91
-rw-r--r--source/LuaWindow.h78
-rw-r--r--source/ManualBindings.cpp80
-rw-r--r--source/Player.cpp29
-rw-r--r--source/Player.h24
-rw-r--r--source/Plugin_NewLua.cpp10
-rw-r--r--source/Plugin_NewLua.h7
-rw-r--r--source/UI/SlotArea.cpp31
-rw-r--r--source/UI/SlotArea.h26
-rw-r--r--source/UI/Window.cpp37
-rw-r--r--source/UI/Window.h37
17 files changed, 1077 insertions, 62 deletions
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
@@ -1458,6 +1458,14 @@
>
</File>
<File
+ RelativePath="..\source\LuaWindow.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\LuaWindow.h"
+ >
+ </File>
+ <File
RelativePath="..\source\ManualBindings.cpp"
>
</File>
@@ -2557,6 +2565,14 @@
>
</File>
</Filter>
+ <Filter
+ Name="Debuggers"
+ >
+ <File
+ RelativePath="..\MCServer\Plugins\Debuggers\Debuggers.lua"
+ >
+ </File>
+ </Filter>
</Filter>
</Files>
<Globals>
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
@@ -658,6 +658,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:
cSlotAreaTemporary::cSlotAreaTemporary(int a_NumSlots, cWindow & a_ParentWindow) :
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;
-} ;
-
-
-
-