• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

OTClient Call C++ functions from Lua side

oen432

Legendary OT User
Joined
Oct 3, 2014
Messages
1,946
Solutions
55
Reaction score
2,183
Location
Poland
GitHub
Oen44
Hi,

What's the proper and best way to call C++ functions and mostly class methods from Lua side?

Example
C++:
void LocalPlayer::doStuff(Position& _position, uint16 _number, bool _alive)
{
    // Code here
}

Lua:
function localPlayerStuff()
  pos = { x = 123, y = 123, z = 7 }
  number = 123
  alive = true
  g_game.getLocalPlayer().doStuff(pos, number, alive)
end

What I'm struggling with right now are parameters. InGame Terminal is overflown with errors about casting. What am I missing? How to get this done?
 
Last edited:
Hi,

What's the proper and best way to call C++ functions and mostly class methods from Lua side?

Example
C++:
void LocalPlayer::doStuff(Position& _position, uint16 _number, bool _alive)
{
    // Code here
}

Lua:
function localPlayerStuff()
  pos = { x = 123, y = 123, z = 7 }
  number = 123
  alive = true
  g_game.getLocalPlayer().doStuff(pos, number, alive)
end

What I'm struggling with right now are parameters. InGame Terminal is overflown with errors about casting. What am I missing? How to get this done?
1st thing you'll need to do if it is not done already is load the lua libraries then you need to create an instance of lua and finally after you have defined a method it needs to be pushed onto the lua stack.
 
1st thing you'll need to do if it is not done already is load the lua libraries then you need to create an instance of lua and finally after you have defined a method it needs to be pushed onto the lua stack.
So like what is done from the beginning.
C++:
g_lua.bindClassMemberFunction<LocalPlayer>("doStuff", &LocalPlayer::doStuff);

It's not about calling function as is. It's more about parameters and type casting.
How to make { x = 123, y = 123, z = 7 } into Position& _position when using g_game.getLocalPlayer().doStuff()
 
easy, look at this little function:
Code:
void LuaScriptInterface::pushPosition(lua_State* L, const Position& position, int32_t stackpos/* = 0*/)
{
    lua_createtable(L, 0, 4);

    setField(L, "x", position.x);
    setField(L, "y", position.y);
    setField(L, "z", position.z);
    setField(L, "stackpos", stackpos);

    setMetatable(L, -1, "Position");
}
and
Code:
void LuaInterface::pushPosition(lua_State* L, const Position& position, uint32_t stackpos)
{
    lua_newtable(L);
    setField(L, "x", position.x);
    setField(L, "y", position.y);
    setField(L, "z", position.z);
    setField(L, "stackpos", stackpos);
}
 
easy, look at this little function:
Code:
void LuaScriptInterface::pushPosition(lua_State* L, const Position& position, int32_t stackpos/* = 0*/)
{
    lua_createtable(L, 0, 4);

    setField(L, "x", position.x);
    setField(L, "y", position.y);
    setField(L, "z", position.z);
    setField(L, "stackpos", stackpos);

    setMetatable(L, -1, "Position");
}
and
Code:
void LuaInterface::pushPosition(lua_State* L, const Position& position, uint32_t stackpos)
{
    lua_newtable(L);
    setField(L, "x", position.x);
    setField(L, "y", position.y);
    setField(L, "z", position.z);
    setField(L, "stackpos", stackpos);
}
But that's for FTS, I'm talking about OTClient here.
 
in this case, it costs nothing to use Visual Studio and look for similar examples throughout the project. with (cntrl+alt+f)

And how should I use that? It's C++ side. I can't even use numbers, it's not casting to int.

C++:
int push_luavalue(const Position& pos)
{
    if(pos.isValid()) {
        g_lua.createTable(0, 3);
        g_lua.pushInteger(pos.x);
        g_lua.setField("x");
        g_lua.pushInteger(pos.y);
        g_lua.setField("y");
        g_lua.pushInteger(pos.z);
        g_lua.setField("z");
    } else
        g_lua.pushNil();
    return 1;
}

bool luavalue_cast(int index, Position& pos)
{
    if(g_lua.isTable(index)) {
        g_lua.getField("x", index);
        pos.x = g_lua.popInteger();
        g_lua.getField("y", index);
        pos.y = g_lua.popInteger();
        g_lua.getField("z", index);
        pos.z = g_lua.popInteger();
        return true;
    }
    return false;
}
 
Back
Top