• entries
    206
  • comments
    217
  • views
    224485

RPG Anvil: The Lua Tutorial Part 4

Sign in to follow this  

576 views



Today, how to call a C++ function from your Lua script.

The previous installments of this tutorial are here:



As you may recall from previous installments of this tutorial, the goal of the tutorial is for our C++ game code to call into a Lua script to determine whether the player can open a door or not. Today, we'll call a Lua script, which will then call back into C++ code to get the player's Lockpicking level, to determine whether or not the player can open the door.

First, let's update our Lua script:

char *szLua =
"x = GetLockpickLevel() "
"return ( x > 7 ) ";


Previously, the script just did "x = 8"; now we call a function to get the player's Lockpicking level. As you'll see below, this is a C++ function.

Here's the C++ function:

int lua_GetLockpickLevel( lua_State *luaState )
{
lua_pushinteger( luaState, 6 );
return( 1 );
}


Lua C++ (or C) functions always get the lua_State as their one parameter; this is the object that allows us to manipulate or examine the Lua virtual machine. As you can see, we use this state to push the return value onto the Lua stack, via lua_pushinteger. (In this case, I'm returning a fixed value of 6). Lua C++ functions return an integer, simply the number of return values. Since I pushed one return value onto the stack, I return 1.

One last step, we need to tell Lua about the lua_GetLockpickLevel function, so Lua knows what C++ function to call. We do this right after initializing the Lua state:

    lua_register( lState, "GetLockpickLevel", lua_GetLockpickLevel );


Build and run the code, and you should get the message "Door still closed", since the player's Lockpick skill of 6 doesn't allow him to open the door (the Lua script requires greater than 7). Here's the complete listing of luatest.cpp:

// luatest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include
#include

char *szLua =
"x = GetLockpickLevel() "
"return ( x > 7 ) ";

int lua_GetLockpickLevel( lua_State *luaState )
{
lua_pushinteger( luaState, 6 );
return( 1 );
}

int _tmain(int argc, _TCHAR* argv[])
{
lua_State *lState;

lState = luaL_newstate();
luaL_openlibs( lState );

lua_register( lState, "GetLockpickLevel", lua_GetLockpickLevel );

int iStatus = luaL_loadstring( lState, szLua );
if( iStatus )
{
std::cout << "Error: " << lua_tostring( lState, -1 );
return 1;
}
iStatus = lua_pcall( lState, 0, 1, 0 );
if( iStatus )
{
std::cout << "Error: " << lua_tostring( lState, -1 );
return 1;
}

int iRet = (int) lua_toboolean( lState, -1 );
if( iRet )
{
std::cout << "Door opened!" << std::endl;
}
else
{
std::cout << "Door still closed." << std::endl;
}

lua_close( lState );

return 0;
}


So, we called a Lua script, and it called C++. We're done, right? Not so fast! Right now, lua_GetLockpickLevel returns a fixed value of 6. In a real game, we would want to look in some structure or class to get that value. Since all it has access to is the lua_State, how can it get the "real" value? Find out in the next thrilling installment of "RPG Anvil: The Lua Tutorial"!
Sign in to follow this  


1 Comment


Recommended Comments

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now