Scripting FAQ (SourceMod)

From AlliedModders Wiki
Revision as of 19:21, 12 August 2012 by TheY4Kman (talk | contribs) (Started porting Yak's FAQ's)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

How do I learn SourcePawn?

A good start is on the Introduction to SourcePawn page, which will teach you the SourcePawn language. Then go through the Introduction to SourceMod Plugins, which will teach you how to write your first plug-in.

Where can I find all the SourcePawn functions and other information?

All SourceMod plug-ins have this line:

#include <sourcemod>

This line instructs the compiler to retrieve the file sourcemod.inc from the sourcemod/scripting/include folder. Every function, variable, and definition can be found in the .inc files inside the sourcemod/scripting/include folder.

But searching through all those files can be quite tedious. Thankfully, the honourable Nican created an API reference viewable on the web, complete with searching and commenting: http://docs.sourcemod.net/api/

Also, if you are in the SourceMod IRC channel (#sourcemod on GameSurge), you can use the !api command to search Nican's API reference:

<theY4Kman> !api Netclass
<yakbot> theY4Kman: GetEntityNetClass(edict, String:clsname[], maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (http://docs.sourcemod.net/api/index.php?fastload=show&id=66)

How do I find the classname of an entity? (e.g., "weapon_knife" or "prop_physics")

The classname of an entity (not to be confused with a netclass) is a unique identifier. It's the most well known of entity names. To find it, use the function GetEdictClassname():

decl String:classname[128];
GetEdictClassname(myentity, classname, sizeof(classname));
 
PrintToServer("myentity classname: %s", classname);
// myentity classname: weapon_knife

How do I block regular commands, such as kill and say?

As of version 1.3, the recommended way to hook and block commands is with AddCommandListener(). Previously, using RegConsoleCmd() with the command name was the only way to hook commands, but this creates a whole new command for the command dispatch to check every time any command is executed. AddCommandListener() creates only a lightweight hook, processed only when the specific command is executed.

Here's how to use it to block the say command:

public OnPluginStart()
{
    AddCommandListener(SayCallback, "say");
}
 
public Action:SayCallback(client, const String:command[], argc)
{
    Return Plugin_Handled;
}

How do I hook +commands, such as +zoom and +attack?

Unlike regular commands, +commands are handled on the client's computer, then sent to the server in a more compressed fashion. This means AddCommandListener() cannot be used to hook +commands. As of version 1.3, the recommended solution is to use the global forward OnPlayerRunCmd(). This forward is fired every time a player uses a movement button. To detect or block a +command, you'll first have to find out its proper IN_ constant (see entity_prop_stocks.inc).

Here's how to use it to block crouching when attacking:

public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon)
{
    // Check if the player is attacking (+attack)
    if ((buttons & IN_ATTACK) == IN_ATTACK)
    {
        // If so, block their crouching (+duck)
        buttons &= ~IN_DUCK;
    }
 
    // We must return Plugin_Continue to let the changes be processed.
    // Otherwise, we can return Plugin_Handled to block the commands
    return Plugin_Continue;
}

How do I get rid of loose indentation warnings?

myplugin.sp(#) : warning 217: loose indentation

Loose indentation warnings arise when indentation in your code is inconsistent. This usually means using both tabs and spaces as indentation. However, it can also mean a different amount of spaces or tabs are being used. Therefore, to correct it, use just one type of indentation. Because different editors have different settings for the size of tab stops, it is recommended you use 4 spaces to indent.

Good:

public OnPluginStart()
{
    new myvar = 5;
    if (myvar == (2 + 3))
        PrintToServer("myvar is %d", myvar);
}

Bad:

public OnPluginStart()
{
	new myvar = 5;
    if (myvar == (2 + 3))
		PrintToServer("myvar is %d", myvar);
}