PDA

View Full Version : Function Calling API assistance


Ibanezez
10-04-2014, 11:41
I'm not entirely understanding the Function Calling API area of sourcemod.
If I had a plugin like this:

#include <sourcemod>

public OnPluginStart()
{
RegAdminCmd("sm_hello", commandHello, ADMFLAG_GENERIC, "Print to Chat Hello!);
}

public OnClientPutInServer(client)
{
public Action:commandHello(client, args)
{
PrintToChat(client, "Hello!");
return Plugin_Handled;
}
}

How could I make the:
public OnClientPutInServer(client)
{
public Action:commandhello(client, args)
}
be possible?
I tried using the alliedmods wiki, but with no success. Could someone explain to me how this works, and give an example of what it would look like in this plugin? ^^^^^^^^^^

(I may be wrong about what Function Calling API does, if so, please let me know. :D)

Drixevel
10-04-2014, 19:14
#include <sourcemod>

public OnPluginStart()
{
RegAdminCmd("sm_hello", commandHello, ADMFLAG_GENERIC, "Print to Chat Hello!);
}

public OnClientPutInServer(client)
{
SayHello(client);
}

public Action:commandHello(client, args)
{
SayHello(client);
return Plugin_Handled;
}

SayHello(client)
{
ReplyToCommand(client, "Hello!");
}


I'm assuming you're referring to a stock function so.

Marcus_Brown001
10-04-2014, 19:38
From what you were trying to do inside the original post, I believe this is what you are looking for.

#include <sourcemod>

public OnPluginStart()
{
RegAdminCmd("sm_hello", Command_Hello, 0, "Greets the client.");
}

public OnClientPutInServer(iClient)
{
Command_Hello(iClient, 0);
}

public Action:Command_Hello(iClient, iArgs)
{
PrintToChat(iClient, "Hello %N!", iClient);

return Plugin_Handled;
}

Ibanezez
10-04-2014, 19:53
A bit more complicated, but how would I do it with something like this:

#include <sourcemod>

public Action:OnEnteredProtectedZone(zone, client, const String:prefix[])
{
static Handle:ShowZones = INVALID_HANDLE;
if (!ShowZones) ShowZones = FindConVar("sm_zones_show_messages");

if (1 <= client <= MaxClients)
{
decl String:m_iName[MAX_NAME_LENGTH*2];
GetEntPropString(zone, Prop_Data, "m_iName", m_iName, sizeof(m_iName));

if (StrEqual(m_iName[8], "test", false))
{
if (GetConVarBool(ShowZones))
{
PrintToChat(client, "%sYou have entered \"%s\" zone.", prefix, m_iName[8]);
//////////////////////////////////////////////////////////////////////////////////// I WANT THE "public OnClientPutInServer(client)" section to be inside here!
}
}
}
}

public Action:OnLeftProtectedZone(zone, client, const String:prefix[])
{
static Handle:ShowZones = INVALID_HANDLE;
if (!ShowZones) ShowZones = FindConVar("sm_zones_show_messages");

if (1 <= client <= MaxClients)
{
decl String:m_iName[MAX_NAME_LENGTH*2];
GetEntPropString(zone, Prop_Data, "m_iName", m_iName, sizeof(m_iName));

if (StrEqual(m_iName[8], "test", false))
{
if (GetConVarBool(ShowZones) && IsPlayerAlive(client))
{
PrintToChat(client, "%sYou have left \"%s\" zone.", prefix, m_iName[8]);
SayHello(client);
}
}
}
}

public OnClientPutInServer(client)
{
PrintToChat(client, "Welcome!");
PrintToChat(client, "Goodbye!");
TF2_RespawnPlayer(client)

return Plugin_Handled;
}


I want the public OnClientPutInServer(client) area to be put right under the PrintToChat(client, "You have entered %s zone", a;sdfka;"); place. How would I do that?

I was thinking something like this.
I would change the public OnClientPutInServer(client) to:

public OnClientPutInServer(client, <makeupname>)

and then wherever I want the section to be, I put:

PrintToChat(client, "%sYou have entered \"%s\" zone.", prefix, m_iName[8]_;
Get(<nameimadeup>);

or something. Do you know the correct way to do this?

Marcus_Brown001
10-04-2014, 20:19
You would want to place the code you want run in multiple places into a stock. Then call that stock where ever you want that code ran.

Here's an example:public OnClientPutInServer(iClient)
{
Void_GreetClient(iClient);
}

stock Void_GreetClient(iClient)
{
PrintToChat(iClient, "Hello %N!", iClient);
PrintToChat(iClient, "Goodbye %N!", iClient);
}

Ibanezez
10-04-2014, 20:36
This is starting to make a bit more sense. :)

I have a much bigger plugin where I have to put the taunt data inside that map zones plugin above. This is some of the script I need to put inside:

public Action:playsound(client, args)
{

}

public OnEntityCreated(entity, const String:classname[])
{

}

public SDKHookCB_OnSceneSpawnedPost(entity)
{

}

public Action:HUD(Handle:timer, any:client)
{

}


I guess my main question is how can I put separate public actions and On<inserthere> and other things inside other commands?

Would I do something like this:

public Action:HUD(Handle:timer, stock:namehere, any:client)
{

}

public Action:playsound(client, args, stock:namehere)
{

}

public OnEntityCreated(entity, const String:classname[], stock:namehere)
{

}


Would I add stock:<name> inside the parenthesis?

Marcus_Brown001
10-04-2014, 21:25
No. You can create custom stocks with any parameters that you will need. With that being said, 'stock' is not a valid tag inside SourceMod (again, visit the wiki (https://wiki.alliedmods.net/Tags_(Scripting)) for more information). Following on that, if you add parameters into natives or default function headers that shouldn't be there the compiler will spit you an error telling you exactly that.

This is an example using the three (which turned into two) functions you posted above. public Action:HUD(Handle:hTimer, any:iBuffer) // This is an example of the header of a timer callback.
{
// When you create a timer it is considered good form to pass a client's userid or serial instead of the client's index.
// The reason for this is in the time between when the timer is created and when the timer runs the client can leave the server, thus making that index invalid.

new iClient = GetClientFromSerial(iBuffer); // It is my personal preference to use client serials. Userids work just as well, too.

SomeRandomStock(iClient);
}

// Using public when you create the function means that it can be accessed from other plugins.
// If you are not planning to use that function in multiple plugins then stock works as well.

public OnEntityCreated(entity, const String:classname[])
{
// This function doesn't have a client index. Sooo, I don't know what you want to do here.
}

stock SomeRandomStock(iClient) // Do you need a client index inside this stock? If not, remove the iClient so it would be SomeRandomStock()
{
//Place the code that you want ran inside of the above functions.
}

I removed the middle function for a few reasons. I don't know what you want to do with it, but there are natives and includes around that allow you to play sounds to clients. I would suggest not trying to recreate a wheel, and use the natives that are inside SourceMod or use Powerlord's include: EmitSoundAny (https://forums.alliedmods.net/showthread.php?t=237045).

On a different note, you should take some time reading, rereading, and re-rereading the SourceMod wiki. Most of the answers to the questions you have asked can be found inside that wiki (recent questions including other threads you have posted as well). Also, there are so many plugins out there that you can download and look at for examples. My advice would be find someone who has the knowledge to, and doesn't mind, answering your questions. In my personal experience, one question can quickly turn into two, which turn into three, etc. Posting here is helpful in most cases, however, it can be very slow at times as well.

Ibanezez
10-05-2014, 12:02
Okay, thanks. I'll look through the wiki and see what I find.