T0X1N Posted December 27, 2016 Share Posted December 27, 2016 How do I specify parameters in C++ with Entity::CallFunction? Example, I have a "Hurt" function defined as the following: function Script:Hurt( damage ) In my C++ program, I want to call the "Hurt" function and specify the "damage". I found an old forum post (http://www.leadwerks.com/werkspace/topic/10745-passing-parameters-to-lua-via-callfunction/page__hl__entity::callfunction#entry78846), but I still do not understand how to specify parameters. I would like to do the following in my C++ program: entity->CallFunction("Hurt", damage) Quote Website | Twitter | Facebook | Steam Play Our Latest Game: Relic Rogue Link to comment Share on other sites More sharing options...
Josh Posted December 27, 2016 Share Posted December 27, 2016 There are a few different declarations of the function with different parameters. The one you describe above is not one. However, if you understand how the Lua stack works you can call any type of Lua functoin from C++. Here is my source code: bool Entity::CallFunction(const std::string& name, Object* extra) { if (component==NULL) return false; bool success = false; //Get the stack size to restore int stacksize = Interpreter::GetStackSize(); //Get the global error handler function int errorfunctionindex = 0; #ifdef DEBUG Interpreter::GetGlobal("LuaErrorHandler"); errorfunctionindex = Interpreter::GetStackSize(); #endif Push(); Interpreter::GetField("script"); if (Interpreter::IsTable()) { Interpreter::GetField(name); if (Interpreter::IsFunction()) { Interpreter::PushValue(-2);//Push script table onto stack extra->Push(); #ifdef DEBUG errorfunctionindex = -(Interpreter::GetStackSize()-errorfunctionindex+1); #endif success = Interpreter::Invoke(2,0,errorfunctionindex); } } Interpreter::SetStackSize(stacksize); return success; } Instead of extra->Push(), which is the same thing as calling Interpreter::PushObject(extra) you would call Interpreter::PushInt(damage). The Invoke function has two arguments, the entity itself and the number you supply. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
T0X1N Posted December 27, 2016 Author Share Posted December 27, 2016 I don't think I quite understand this yet. Do I have to write a Entity::CallFunction function in my c++ source code? If I do, how would I go about adding the int "damage" to the code since I cannot create a new declaration to the Entity:: class. Plus, would this function act as a Hook function? What is the "extra" object? Can't I use that to store the data in? If so, how could I go about storing the 'damage' variable into an Object class variable? Also, is it possible to have an example source code snippet that calls a function in LUA from C++ with custom parameters that I can look at to learn off of? That would be extremely helpful as I learn by example mainly. Thanks for the help! Quote Website | Twitter | Facebook | Steam Play Our Latest Game: Relic Rogue Link to comment Share on other sites More sharing options...
Josh Posted December 27, 2016 Share Posted December 27, 2016 That's what I posted above. That is the source code of the CallFunction() function. You can modify this, although you cannot make it a class function, so it would be something more like this: CallEntityFunction(Entity* entity, const std::string& name, const int i) My function passes an object to the Lua function. You want a function that passes an integer instead. So instead of adding the "extra" object parameter to the stack, add an integer with Interpreter::PushInt(). Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
T0X1N Posted December 27, 2016 Author Share Posted December 27, 2016 Ok, now we are cooking. However, I am facing some issues. Here is my function that I wrote which is basically a duplication of the CallFunction source that you posted with a few edits to just use "Hurt" function. bool FPSplayer::CallHurtFunction(Entity* entity, const int damage){ if (entity->component == NULL){ System::Print("ENTITY COMPONENT IS NULL!"); return false; } bool success = false; //Get the stack size to restore int stacksize = Interpreter::GetStackSize(); //Get the global error handler function int errorfunctionindex = 0; #ifdef DEBUG Interpreter::GetGlobal("LuaErrorHandler"); errorfunctionindex = Interpreter::GetStackSize(); #endif entity->Push(); Interpreter::GetField("script"); if (Interpreter::IsTable()) { Interpreter::GetField("Hurt"); if (Interpreter::IsFunction()) { System::Print("HURT FUNCTION EXISTS..."); Interpreter::PushValue(-2);//Push script table onto stack Interpreter::PushInt(damage); #ifdef DEBUG errorfunctionindex = -(Interpreter::GetStackSize() - errorfunctionindex + 1); #endif success = Interpreter::Invoke(2, 0, errorfunctionindex); }else{ System::Print("GetField(HURT) is False \n"); } } else { System::Print("IsTable() is false \n"); } Interpreter::SetStackSize(stacksize); return success; } and I am calling the function using this if( pickInfo.entity->ContainsFunction("Hurt") ){ // CALL HURT FUNCTION System::Print("HAS HURT FUNCTION... Calling! \n"); CallHurtFunction(pickInfo.entity, damage); }else if( pickInfo.entity->parent != NULL ){ if (pickInfo.entity->parent->ContainsFunction("Hurt")) { System::Print("HAS HURT FUNCTION... & Parent... calling! \n"); CallHurtFunction(pickInfo.entity, damage); } } However, it comes back that 'component' is NULL. If I take that away, the 'Interpreter::IsTable()' comes back false. I know I am doing something wrong here, obviously, as this is new to me. Again, thanks for the help. I really appreciate this. Quote Website | Twitter | Facebook | Steam Play Our Latest Game: Relic Rogue Link to comment Share on other sites More sharing options...
Josh Posted December 27, 2016 Share Posted December 27, 2016 It looks like the entity does not have a script set. No way it could be anything else. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
T0X1N Posted December 27, 2016 Author Share Posted December 27, 2016 Ah, yup! You were right! In my code when I call the function, I forgot to tell it to call the function using the entity's parent script (which is the one that has the script). After fixing that, it works perfectly. Here is the fixed code: if( pickInfo.entity->ContainsFunction("Hurt") ){ // CALL HURT FUNCTION CallHurtFunction(pickInfo.entity, damage); }else if( pickInfo.entity->parent != NULL ){ if (pickInfo.entity->parent->ContainsFunction("Hurt")) { CallHurtFunction(pickInfo.entity->parent, damage); } } Thank you for helping me. I can now say I learned something new today with Leadwerks and now a just another step closer to getting our game done! 1 Quote Website | Twitter | Facebook | Steam Play Our Latest Game: Relic Rogue Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.