GMod Module Help

So i’ve been messing with Garry’s Mod recently and I tried to call a function though a module:


debug.getregistry().Entity.GetNWString(pEntity, "isgettingrevived");

so I tried the following code:


pLuaInterface->PushSpecial(SPECIAL_REG);
pLuaInterface->GetField(-1, "Entity");
pLuaInterface->GetField(-1, "GetNWString");
pLuaInterface->PushUserdata((void*)pEntity);
pLuaInterface->PushString("isgettingrevived", 0);
pLuaInterface->Call(1, 1);
pLuaInterface->Pop(4);

std::string strTestOutput = "Nothing";
ILuaObject* pLuaObject = (ILuaObject*)pLuaInterface->GetObject(-1);
if (pLuaObject)
	strTestOutput = pLuaObject->GetMemberStr("key");

While pEntity is a C_BaseEntity pointer to a player.
The problem is that the game crashes with the following error:

http://puu.sh/jcBqz/e9fa2541f5.png

Does anyone have a clue on how to fix this please? (and sorry for possibly wrong english)

You need to define pEntity in your Lua code. The first argument to GetNWString is supposed to be the key string, not an entity.

That’s why I want to call the function from the Entity meta table, so I can pass it as an argument:

http://puu.sh/jcFxB/58ea9bdabb.png

The argument doesn’t just suddenly become defined as you access the metatable. You need a way to access pEntity in your code from an accessor or something besides a global variable.

:snip:

But is there a way to pass it as an argument instread? I don’t want to define a global variable.


pLuaInterface->Call(1, 1);

This means you call a function with 1 input and 1 output, while you pushed 2 strings to the function call.

Thanks, fixed it.
But now it returns “(null)”, am I getting the result the wrong way?



pLuaInterface->PushSpecial(SPECIAL_REG);		// 0
pLuaInterface->GetField(-1, "Entity");			// 1
pLuaInterface->GetField(-1, "GetNWString");		// 2


/* Args */
pLuaInterface->PushUserdata(pLocalPlayer);		// 3
pLuaInterface->PushString("usergroup", 0);		// 4		string key
// pLuaInterface->PushString("fallback", 0);		// 5		string fallback=""

/* Call */
pLuaInterface->Call(2, 2); // stack pos, arguments


/* Result */
printf("%s
", pLuaInterface->GetString(-1, 0));


/* Pop */
pLuaInterface->Pop(4);


GetNWString has one return value, not two.

The actual arguments to ILuaInterface::Call are (int iStackPos, int iArgs) so I switched to ILuaBase::Call since it matches what you said, ended up with this, and it still crashes:

http://puu.sh/jduXr/f7d9a72c18.png

I guess that it happens when I call ILuaBase::Pop(5); but I don’t understand why

You are overpopping the stack. Call pops the function and all of its arguments. You need to pop 3 values:

  1. The registry.
  2. The entity metatable.
  3. The return value from GetNWString.

I don’t know what PushString’s second argument does, but you don’t need it, so try removing that.

Thanks, that solved the crash, though it returns the fallback string, do you know if I can pass an entity pointer (pLocalPlayer is grabbed using IClientEntityList::GetClientEntity) or do I have to cast it to a Lua Object somehow?

You can’t use values created in the engine like that. You need to use a Lua value. For the local player, you can just call the LocalPlayer global and save the result.

Put this in your module’s global space.
[cpp]int LocalPlayer = 0;[/cpp]
Put this in your module’s open function.
[cpp]
pBase->PushSpecial(SPECIAL_GLOB);
pBase->GetField(-1, “LocalPlayer”);
pBase->Call(0, 1);
LocalPlayer = pBase->ReferenceCreate(); // ReferenceCreate pops the value from the stack, so you only need to pop the global table.
pBase->Pop();[/cpp]
Replace your call to pBase->PushUserdata with a call to pBase->ReferencePush(LocalPlayer)

Put this in your module’s close function.
[cpp]pBase->ReferenceFree(LocalPlayer);[/cpp]
Here’s a link about references, they’re super easy to use.

Alternatively, you can just call the LocalPlayer global every time instead of saving its return value.

I don’t really know why you need to use the registry for this, though. You can just call LocalPlayer (or get whatever other player you want on the stack), GetField the GetNWString function, and call that.

Thanks, it works perfectly!
I’ll just use Entity(entindex) to get entities then create a ref to them.