Guest User

Untitled

a guest
Jan 7th, 2011
864
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "common/GMLuaModule.h" // Include the header for the required GMod Lua module definitions
  2.  
  3. GMOD_MODULE( Open, Close ); // State the functions we want to be called when the module loads and unloads
  4.  
  5. LUA_FUNCTION( PlayerInitialSpawnCallback ) // Declare our callback function that will be passed to hook.Add as the 3rd argument
  6. {
  7.     Lua()->CheckType( 1, GLua::TYPE_ENTITY ); // Ensure the first argument is type "Entity" - we can just assume its a player
  8.  
  9.     int playerRef = Lua()->GetReference( 1 ); // Get a reference to the player for later use (using GetUserData results in garbage collection, causing errors elsewhere)
  10.  
  11.     if ( playerRef != -1 ) // Make sure our reference is valid
  12.     {
  13.         ILuaObject *playerMeta = Lua()->GetMetaTable( "Player", GLua::TYPE_ENTITY ); // Retrieve the "Player" metatable, equivalent to "playerMeta = _R.Player"
  14.  
  15.         if ( playerMeta ) // Make sure the result is valid
  16.         {
  17.             if ( playerMeta->isTable() ) // Check that our reference is a table
  18.             {
  19.                 ILuaObject *playerChatPrint = playerMeta->GetMember( "ChatPrint" ); // Lookup _R.Player.ChatPrint
  20.  
  21.                 if ( playerChatPrint ) // Does _R.Player.ChatPrint exist?
  22.                 {
  23.                     if ( playerChatPrint->isFunction() ) // Is _R.Player.ChatPrint a function?
  24.                     {
  25.                         // To call a meta function, we need to push it onto the stack using ILuaInterface::Push
  26.                         // The meta function must be pushed first, followed by the userdata, followed by its arguments
  27.  
  28.                         Lua()->Push( playerChatPrint ); // Push the meta function
  29.                         Lua()->PushReference( playerRef ); // Push the player object (userdata)
  30.                         Lua()->Push( "You've just spawned!" ); // Push the argument
  31.  
  32.                         // We've pushed 2 arguments and don't care about any return values
  33.                         Lua()->Call( 2, 0 );
  34.                     }
  35.  
  36.                     playerChatPrint->UnReference(); // The function has been called, we can unreference
  37.                 }
  38.             }
  39.  
  40.             playerMeta->UnReference(); // We're done, unreference
  41.         }
  42.  
  43.         Lua()->FreeReference( playerRef ); // Free our player object reference, it isn't needed anymore
  44.     }
  45.  
  46.     return 0; // Zero return values
  47. }
  48.  
  49. int Open( lua_State *L ) // Declare the function we want to be called when the module loads
  50. {
  51.     ILuaObject *hookTable = Lua()->GetGlobal( "hook" ); // Find the global "hook", equivalent of "hookTable = hook", or "hookTable = _G.hook" in Lua
  52.  
  53.     if ( hookTable ) // If hook wasn't found then GetGlobal returns NULL; we make sure it was successful before continuing
  54.     {
  55.         if ( hookTable->isTable() ) // Hook may have been found, but we should check that it's a table
  56.         {
  57.             ILuaObject *hookAdd = hookTable->GetMember( "Add" ); // Hook appears to be a valid table so we lookup its "Add" member ( "hookAdd = hook.Add" in Lua )
  58.            
  59.             if ( hookAdd ) // Was hook.Add successfully retrieved?
  60.             {
  61.                 if ( hookAdd->isFunction() ) // Is hook.Add a function?
  62.                 {
  63.                     // To call a function, we need to push it onto the stack using ILuaInterface::Push
  64.                     // The function must be pushed first, followed by its arguments
  65.  
  66.                     Lua()->Push( hookAdd ); // hookAdd is now the equivalent to the "hook.Add" function in Lua, so we push it onto the Lua stack
  67.                     Lua()->Push( "PlayerInitialSpawn" ); // hook.Add takes the hook type as its first argument
  68.                     Lua()->Push( "hookname" ); // The next argument is the unique hook name
  69.                     Lua()->Push( PlayerInitialSpawnCallback ); // Push our callback function which will be called when PlayerInitialSpawn is triggered
  70.                    
  71.                     // We've pushed 3 arguments and don't care about any return values
  72.                     Lua()->Call( 3, 0 );
  73.                 }
  74.                
  75.                 hookAdd->UnReference(); // We've added our hook and no longer need access to the "hook.Add" function, unreference it
  76.             }
  77.         }
  78.        
  79.         hookTable->UnReference(); // The hook table isn't required any further, unreference it
  80.     }
  81.  
  82.     return 0;
  83. }
  84.  
  85. int Close( lua_State *L ) // Declare the function we want to be called when the module unloads
  86. {
  87.     // You need to remove the hook here because the callback function will become invalid
  88.     // Hopefully after reading through this, you'll be able to do it yourself
  89.  
  90.     return 0;
  91. }
RAW Paste Data