AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Yak's FAQs on Scripting (https://forums.alliedmods.net/showthread.php?t=94187)

theY4Kman 06-07-2009 17:03

Yak's FAQs on Scripting
 

The thread will be kept for archival purposes, but all future additions and edits will be made to the wiki article. Please contribute to the wiki page for the benefit of all! Thanks, guys :)










Most of the time, we volunteer support specialists are in gs#sourcemod to answer all your questions. Unfortunately, some of us have lives (except for sawce) and we can't be on every waking moment. Fortunately, there is a solution. It is...
Yak's FAQs on Scripting!
A guide to common and not-so-common tasks in SourcePawn

If you have a question and/or answer to add, reply to the thread and I will tack it onto the list. Suggestions (and corrections) are welcome!

Table of Contents
1. How do I learn SourcePawn?
2. Where can I find all the SourcePawn functions and other information?
3. How do I find the classname of an entity? (e.g., "weapon_knife" or "prop_physics")
4. How do I block regular commands, such as kill and say?
5. How do I hook +commands, such as +zoom and +attack?
6. How do I get rid of loose indentation warnings?
7. How do I get rid of tag mismatch warnings?
8. How do I add color to my messages?
9. Why do I get an "unknown symbol" error when using an SDKTools native?
10. Why is Source telling me my command is an "Unknown command"?



1. How do I learn SourcePawn?
Look at the AlliedModders wiki: http://wiki.alliedmods.net/Introduction_to_SourcePawn


2. Where can I find all the SourcePawn functions and other information?
When you #include <sourcemod>, the compiler retrieves the file sourcemod.inc from the sourcemod/scripting/include/ folder. Every function, variable, and definition can be found in the .inc files inside scripting/include.

Searching through all those files can be quite tedious. Thankfully, the honorable Nican created an API reference on the web, complete with searching and commenting: http://docs.sourcemod.net/api/
If you are in gs#sourcemod, you can use the !api command to search Nican's API reference:
Code:

<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....oad=show&id=66)

3. 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(edict, String:clsname[], maxlength):
Code:
decl String:classname[128]; GetEdictClassname(myentity, classname, sizeof(classname));



4. How do I block regular commands, such as kill and say?
Use RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0) (API reference) to hook the command you wish to block. Then, in the callback for the command, return Plugin_Handled:
Code:
public OnPluginStart() {      RegConsoleCmd("say", SayCallback); } public Action:SayCallback(client, args) {          return Plugin_Handled; }
EDIT: As of version 1.3, there is a better way to hook and block commands that are already registered. Unlike RegConsoleCmd, the new AddCommandListener(CommandListener:callback, const String:command[]="") creates only a lightweight hook for when the command is run, instead of creating a whole new command and slowing down the command dispatch. Thus, you should always use AddCommandListener when possible. Here's how to use it:
Code:
public OnPluginStart() {     AddCommandListener(SayCallback, "say"); } public Action:SayCallback(client, const String:command[], argc) {     Return Plugin_Handled; }



5. How do I hook +commands, such as +zoom and +attack?
Unlike regular commands, the +commands are handled on the client, then sent to the server by other means. That means you cannot use RegConsoleCmd to hook +commands. It also means that unless you're using SourceMod 1.3, you can only hook +commands, you CANNOT block them. You must use loop through all the clients OnGameFrame() and call GetClientButtons(client) with the proper IN_ definition (see entity_prop_stocks.inc) to check if a client is using a +command:
Code:
public OnGameFrame() {     for (new i=1; i<=MaxClients; i++)     {         if (IsClientInGame(i) && GetClientButtons(i) & IN_DUCK)         {             // Client i is pressing their button bound to +duck         }     } }

A better method for hooking +commands was added in SourceMod 1.3, rev 2711: the forward OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon). This forward is fired every time a player uses a movement button. The great thing about this forward is that changes to the buttons are saved. Thus, we can actually block +commands:
Code:
public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon) {     // Block +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; }
A lot of the changes to the buttons won't look too great to the players, because of clientside prediction. Before the server can reply to the user's +command, the client acts out the +command to make the game as smooth as possible. Unfortunately, it makes the game very much not smooth if we edit buttons.


6. How do I get rid of loose indentation warnings?
Code:

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 just use one type of indentation. Because different editors have different settings for the size of tab stops, it is recommended that you use 4 spaces to indent.


7. How do I get rid of tag mismatch warnings?
Though every variable in SourcePawn is one cell (4 bytes), with the exception of strings, there are many different ways to interpret what's contained in the cell. To signify what is in a cell, tags are used. The most common are _ (the default tag: a vanilla cell. This tag is implied when no other tag is specified.), Float, bool, and String. See http://wiki.alliedmods.net/Introduct...Pawn#Variables for more information.

Functions wear these tags on their parameters so you can tell what needs to be passed to the function:
Code:
native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);
This function calls for entity, a cell with the implied tag _, type, with the developer-defined tag PropType, prop, with the built-in tag String, and value, with the built-in tag Float.
To call this function, then, you must pass values with the specified tags. For example:
Code:
SetEntPropFloat(1234, Prop_Send, "m_fNumber", 1.0);
This calls the function correctly: 1234 is a regular cell, Prop_Send is a variable defined in the enum PropType in entity.inc, "m_fNumber" is a String, and 1.0 is a Float. For a nonexample:
Code:
SetEntPropFloat(1234.0, 1, "m_fNumber", 1337);
This is incorrect! 1234.0 is a Float that should be a regular cell (_), 1 is a regular cell that should be a PropType, and 1337 is a regular cell that should be a Float. This call will generate a tag mismatch warning. To correct it, simply use a value with the correct tag. Most of the time, tags that are not built-in (such as PropType) can be found in the same file where a function uses them (you can find PropType in entity.inc).


8. How do I add color to my messages?
Thanks to antihacker for the question/answer and psychonic for some corrections.

Though the actual colors will vary depending on the mod, you can add color to any chat message using the characters 0x01 to 0x08. For example:
Code:
PrintToChatAll ("\x01 1 .. \x02 2 .. \x03 3 .. \x04 4 .. \x05 5 .. \x06 6 .. \x07 7 .. \x08 8");
Example output from Left 4 Dead (image courtesy of antihacker):
http://y4kstudios.com/sourcemod/yaks_faqs/sm_colors.png

With a little experimenting, you can learn the colors for a mod. However, the meaning behind the colors is generally as follows:
0x01 = Normal color
0x02 = Use team color to the end of a player's name. When used, it can be the only color used, and it must be at the start of the message.
0x03 = Team color
0x04 = Location color
This data comes from Counter-Strike: Source.

Unfortunately, to use players' team colors, you must use UserMessages, because there is no way for the current SourceMod functions to know what team color to use. Here's an example:
Code:
new Handle:hBf; hBf = StartMessageOne("SayText2", player_to); // To send the message to all players, use StartMessageAll("SayText2"); if (hBf != INVALID_HANDLE) {     BfWriteByte(hBf, player_from);     BfWriteByte(hBf, 0);     BfWriteString(hBf, "<\x03player_from team color\x01> My message");     EndMessage(); }
player_to is the client index to send the message to (Or use StartMessageAll() instead of StartMessageOne() to send the message to all players). player_from is the client index of the player whose team color will be utilized in the message. The message will now look like this (assuming player_from is on the RED team):
Code:

<player_from team color> My message
There's another catch, however: this is only known to work in CS:S and TF2. For other mods, your mileage may vary.

EDIT: exvel has released an excellent library of functions that will do all this work for you. Instead of using color codes, you merely write "{green}" or "{blue}".


9. Why do I get an "unknown symbol" error when using an SDKTools native?
Thanks to Tsunami

None of SourceMod's or SDKTools's functions are built into SourcePawn. Therefore, every time you use one of their functions, SourcePawn needs to know how to call the function. Normally, this is done using includes. Just like you would #include <sourcemod> to use SourceMod's functions, you need to:
Code:
#include <sdktools>
to use an SDKTools native.


10. Why is Source telling me my command is an "Unknown command"?
This is because you're not returning Plugin_Handled in your callback. If you don't, SourceMod believes you didn't want the Source Engine to know the command was registered, and it handles it so.

Dragonshadow 06-13-2009 10:05

Re: Yak's FAQs on Scripting
 
Thank you

antihacker 06-14-2009 12:31

Re: Yak's FAQs on Scripting
 
8. How to color your messages?
Use \x01, \x02 ... \x08 to color your message, example:
PHP Code:

PrintToChatAll ("\x01 1 .. \x02 2 .. \x03 3 .. \x04 4 .. \x05 5 .. \x06 6 .. \x07 7 .. \x08 8 .. \x09 9 .."); 

Example output (L4D):
http://i43.tinypic.com/2dvj1c5.png
You must find out wich color you get, because this is different for nearly every mod.

\x01 normal color
\x03 is the team depend color.
Also see this.

I hope you dont mind for posting here.

DJ Tsunami 06-16-2009 12:14

Re: Yak's FAQs on Scripting
 
9. Why do I get "unknown symbol" when using an SDKTools native?
Code:
#include <sdktools>
nuff said.

Dragonshadow 06-24-2009 09:48

Re: Yak's FAQs on Scripting
 
An addition to

6. How do I get rid of loose indentation warnings?

If using notepad++,

Rightclick
Select All
PHP Code:

Menubar (file/edit/search/etc
    
TextFX
        TextFX Edit
            Reindent C
++ Code 


lovemf 07-12-2009 19:21

Re: Yak's FAQs on Scripting
 
in left 4 dead

how can i spawn a don't fire tank?

theY4Kman 07-13-2009 18:56

Re: Yak's FAQs on Scripting
 
This is a more general FAQ about how to do general things in SourcePawn. If you're looking for something mod-specific, I suggest searching around the Scripting forum. If you can't find anything after searching your heart out, create a thread.

I'm trying to keep this thread as mod-neutral as possible.

Pulseczar 08-22-2009 22:55

Re: Yak's FAQs on Scripting
 
Quote:

Originally Posted by theY4Kman (Post 843875)
Because different editors have different settings for the size of tab stops, it is recommended that you use 4 spaces to indent.

I would love to plus rep you or something for that. God I hate the tab character. People just need to set their tab key to produce X number of spaces. Any text editor worth anything will be capable of that.

pRED* 10-16-2009 02:35

Re: Yak's FAQs on Scripting
 
Quote:

Originally Posted by Pulseczar (Post 909751)
I would love to plus rep you or something for that. God I hate the tab character. People just need to set their tab key to produce X number of spaces. Any text editor worth anything will be capable of that.

And let the terrorists win? I think not!

=MaTi= 01-20-2010 05:27

Re: Yak's FAQs on Scripting
 
#4 needs to be updated to use AddCommandListener ;)


All times are GMT -4. The time now is 15:37.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.