diff --git a/Plugins/Core/onblockplace.lua b/Plugins/Core/onblockplace.lua index 45d9a082..64ab5492 100644 --- a/Plugins/Core/onblockplace.lua +++ b/Plugins/Core/onblockplace.lua @@ -1,5 +1,3 @@ -local BlockData = {} - function OnBlockPlace( Block, Player ) -- dont check if the direction is in the air @@ -12,8 +10,39 @@ function OnBlockPlace( Block, Player ) if( Y >= 128 or Y < 0 ) then return true end + + local CheckCollision = function( Player ) + -- drop the decimals, we only care about the full block X,Y,Z + local PlayerX = math.floor(Player:GetPosX(), 0) + local PlayerY = math.floor(Player:GetPosY(), 0) + local PlayerZ = math.floor(Player:GetPosZ(), 0) - BlockData = Block + local BlockX = Block.m_PosX + local BlockY = Block.m_PosY + local BlockZ = Block.m_PosZ + + -- player height is 2 blocks, so we check the position and then offset it up one + -- so they can't place a block on there face + + local collision = false + if Block.m_Direction == 0 then if PlayerY == BlockY-2 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end + if Block.m_Direction == 1 then if PlayerY == BlockY+1 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end + + if Block.m_Direction == 2 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end + if Block.m_Direction == 2 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end + + if Block.m_Direction == 3 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end + if Block.m_Direction == 3 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end + + if Block.m_Direction == 4 then if PlayerY == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end + if Block.m_Direction == 4 then if PlayerY+1 == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end + + if Block.m_Direction == 5 then if PlayerY == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end + if Block.m_Direction == 5 then if PlayerY+1 == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end + + return collision + end + if( Player:GetWorld():ForEachPlayer( CheckCollision ) == false ) then return true else @@ -24,36 +53,4 @@ function OnBlockPlace( Block, Player ) return false -end - -function CheckCollision( Player ) - -- drop the decimals, we only care about the full block X,Y,Z - local PlayerX = math.floor(Player:GetPosX(), 0) - local PlayerY = math.floor(Player:GetPosY(), 0) - local PlayerZ = math.floor(Player:GetPosZ(), 0) - - local BlockX = BlockData.m_PosX - local BlockY = BlockData.m_PosY - local BlockZ = BlockData.m_PosZ - - -- player height is 2 blocks, so we check the position and then offset it up one - -- so they can't place a block on there face - - local collision = false - if BlockData.m_Direction == 0 then if PlayerY == BlockY-2 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end - if BlockData.m_Direction == 1 then if PlayerY == BlockY+1 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end - - if BlockData.m_Direction == 2 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end - if BlockData.m_Direction == 2 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end - - if BlockData.m_Direction == 3 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end - if BlockData.m_Direction == 3 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end - - if BlockData.m_Direction == 4 then if PlayerY == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end - if BlockData.m_Direction == 4 then if PlayerY+1 == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end - - if BlockData.m_Direction == 5 then if PlayerY == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end - if BlockData.m_Direction == 5 then if PlayerY+1 == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end - - return collision end \ No newline at end of file diff --git a/Plugins/Core/playerlist.lua b/Plugins/Core/playerlist.lua index 63990e82..f06dfed8 100644 --- a/Plugins/Core/playerlist.lua +++ b/Plugins/Core/playerlist.lua @@ -1,7 +1,9 @@ -local PlayerTable = {} - function HandlePlayerListCommand( Split, Player ) - PlayerTable = {} + + local PlayerTable = {} + local AppendToTable = function( Player ) + table.insert(PlayerTable, Player:GetName() ) + end Player:GetWorld():ForEachPlayer( AppendToTable ) local Message = cChatColor.Green .. "Connected players: (".. cChatColor.White.. #PlayerTable .. cChatColor.Green .. ")" @@ -9,8 +11,4 @@ function HandlePlayerListCommand( Split, Player ) Player:SendMessage( table.concat(PlayerTable, " ") ) return true -end - -function AppendToTable( Player ) - table.insert(PlayerTable, Player:GetName() ) end \ No newline at end of file diff --git a/Plugins/Core/web_playerlist.lua b/Plugins/Core/web_playerlist.lua index 62ccb1d4..ed6b7667 100644 --- a/Plugins/Core/web_playerlist.lua +++ b/Plugins/Core/web_playerlist.lua @@ -1,6 +1,3 @@ -local PlayerHTML = "" -local PlayerNum = 0 - function HandleRequest_PlayerList( Request ) local World = cRoot:Get():GetWorld() local Content = "" @@ -19,25 +16,21 @@ function HandleRequest_PlayerList( Request ) Content = Content .. "

Connected Players: " .. World:GetNumPlayers() .. "

" Content = Content .. "" - PlayerNum = 0 - PlayerHTML = "" - World:ForEachPlayer( CreatePlayerList ) + local PlayerNum = 0 + local AddPlayerToTable = function( Player ) + PlayerNum = PlayerNum + 1 + Content = Content .. "" + Content = Content .. "" + Content = Content .. "" + Content = Content .. "" + Content = Content .. "" + end + World:ForEachPlayer( AddPlayerToTable ) - if( PlayerHTML ~= "" ) then - Content = Content .. PlayerHTML - else + if( PlayerNum == 0 ) then Content = Content .. "" end Content = Content .. "
" .. PlayerNum .. "." .. Player:GetName() .. "Kick
None
" Content = Content .. "
" return Content -end - -function CreatePlayerList( Player, Data ) - PlayerNum = PlayerNum + 1 - PlayerHTML = PlayerHTML .. "" - PlayerHTML = PlayerHTML .. "" .. PlayerNum .. "." - PlayerHTML = PlayerHTML .. "" .. Player:GetName() .. "" - PlayerHTML = PlayerHTML .. "Kick" - PlayerHTML = PlayerHTML .. "" end \ No newline at end of file diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 840109a8..ea6c18e2 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -103,6 +103,13 @@ static int tolua_LOGERROR(lua_State* tolua_S) static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) { + int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self' + if( NumArgs != 1 && NumArgs != 2) + { + LOGWARN("Error in function call 'ForEachPlayer': Requires 1 or 2 arguments, got %i", NumArgs ); + return 0; + } + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); if( !lua_isfunction( tolua_S, 2 ) ) @@ -111,48 +118,69 @@ static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) return 0; } - - int Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if( Reference == LUA_REFNIL ) + // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top + int TableRef = LUA_REFNIL; + if( NumArgs == 2 ) { - LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference"); + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( TableRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get value reference of parameter #2"); + return 0; + } + } + + // table value is popped, and now function is on top of the stack + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( FuncRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference of parameter #1"); return 0; } - + class cLuaPlayerCallback : public cPlayerListCallback { + public: + cLuaPlayerCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: virtual bool Item(cPlayer * a_Player) override { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, Reference); + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference tolua_pushusertype( LuaState, a_Player, "cPlayer" ); - - int s = lua_pcall( LuaState, 1, 1, 0); + if( TableRef != LUA_REFNIL ) + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference + } + + int s = lua_pcall( LuaState, (TableRef==LUA_REFNIL?1:2), 1, 0); if( report_errors( LuaState, s ) ) { - return false; + return false; // Maybe we should return true? } if( lua_isboolean( LuaState, -1 ) ) { return (tolua_toboolean( LuaState, -1, 0) > 0); } - - LOGINFO("Stack size: %i", lua_gettop(LuaState) ); - return false; } - public: lua_State* LuaState; - int Reference; - } Callback; - - Callback.LuaState = tolua_S; - Callback.Reference = Reference; + int FuncRef; + int TableRef; + } Callback( tolua_S, FuncRef, TableRef ); bool bRetVal = self->ForEachPlayer( &Callback ); - luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); + // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references + luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); + luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); + // Push return value on stack tolua_pushboolean( tolua_S, bRetVal ); return 1; }