[Tutorial] Making a /me /do /shout /b command
#1

A few useful commands for a RP server
What will this teach me?
This tutorial will teach you how to make a
* Blademaster680 command for an action
/do command for a OOC action
/shout command to allow you to shout
/b command for OOC chat.

Step 1:
First we need to include foreach, ZCMD and sscanf which I will put the download link at the bottom of the tutorial.
Code:
#include <foreach>
#include <ZCMD>
#include <sscanf2>
Step 2:
We need to make a strreplace which we can use to replace the "_" in their names for eg. "Jackie_Chan" will change to "Jackie Chan". See so we will be replacing the "_" with a space.
Code:
stock strreplace(string[], find, replace)
{
    for(new i=0; string[i]; i++)
    {
        if(string[i] == find)
        {
            string[i] = replace;
        }
    }
}
Step 3:
We need to make a ProxDetector and a GetName stock.
A ProxDetector is a stock that will make the chat fade the further away you are from the person talking and the GetName will just get the player's name.
Code:
stock ProxDetector(Float:radi, playerid, string[],color)
{
    new Float:x,Float:y,Float:z;
    GetPlayerPos(playerid,x,y,z);
    foreach(Player,i)
    {
        if(IsPlayerInRangeOfPoint(i,radi,x,y,z))
        {
            SendClientMessage(i,color,string);
        }
    }
}
Ok so now what does that mean?
Code:
new Float:x, Float:y, Float:z;
Were are declaring the float x, y, and z.
Code:
GetPlayerPos(playerid,x,y,z);
We are getting the Player's Position for later use.
Code:
    foreach(Player,i)
    {
        if(IsPlayerInRangeOfPoint(i,radi,x,y,z))
        {
            SendClientMessage(i,color,string);
        }
    }
That is checking if the player is in range, and if he is he will receive the message.
Code:
stock GetName(playerid)
{
    new name[24];
    GetPlayerName(playerid, name, sizeof(name));
    strreplace(name, '_', ' ');
    return name;
}
Code:
new name[24];
Defining the "name".
Code:
GetPlayerName(playerid, name, sizeof(name));
Getting the players name.
Code:
strreplace(name, '_', ' ');
That will replace the "_" in their name.
For example if their name is "John_Smith" it will make it "John Smith".
Code:
return name;
This is returning the new name.

Step 4:
Ok so now onto the commands, first we will do the /me command.

Code:
CMD:me(playerid, params[])
{
    new string[128], action[100];
    if(sscanf(params, "s[100]", action))
    {
        SendClientMessage(playerid, -1, "USAGE: /me [action]");
        return 1;
    }
    else
    {
        format(string, sizeof(string), "* %s %s", GetName(playerid), action);
        ProxDetector(30, playerid, string, COLOR_PURPLE);
    }
    return 1;
}  
if(sscanf(params, "s[100]", action))
    {
        SendClientMessage(playerid, -1, "USAGE: /me [action]");
        return 1;
    }
What this code does is it will check if the player typed /me and then the action, else it will tell them "USAGE: /me [action]".
Code:
    
else
    {
        format(string, sizeof(string), "* %s %s", GetName(playerid), action);
        ProxDetector(30, playerid, string, COLOR_PURPLE);
    }
This code is saying if he did put an action then it will do this piece.
Code:
format(string, sizeof(string), "* %s %s", GetName(playerid), action);
This is just using a string and the first %s will get the players name and the second %s will be the action he typed in.
Code:
ProxDetector(30, playerid, string, COLOR_PURPLE);
This is using the ProxDetector which we made earlier. The range is 30m and everyone within that 30m will see the action and it will display in purple.

Step 5:
Lets get onto the /do command.
Code:
CMD:do(playerid, params[])
{
    new string[128], action[100];
    if(sscanf(params, "s[100]", action))
    {
        SendClientMessage(playerid, -1, "USAGE: /do [action]");
        return 1;
    }
    else
    {
        format(string, sizeof(string), "* %s (( %s ))", action, GetName(playerid));
        ProxDetector(30, playerid, string, COLOR_PURPLE);
    }
    return 1;
}
Dont need to explain this it is exactly the same as the /me command except this just has the OOC brackets "(( ))".

Step 6:
Now for the shout command.
Code:
CMD:shout(playerid, params[])
{
    new string[128], shout[100];
    if(sscanf(params, "s[100]", shout))
    {
        SendClientMessage(playerid, -1, "USAGE: /(s)hout [message]");
        return 1;
    }
    else
    {
        format(string, sizeof(string), "%s shouts: %s!",GetName(playerid),shout);
        ProxDetector(50.0, playerid, string, -1);
    }
    return 1;
}
This command is similar to the /me and /do command's except it has a few different things.
Code:
 ProxDetector(50.0, playerid, string, -1);
Now the new range is 50m. So everyone will see this if they are within 50m of the person who shouted the message and it will desplay in grey.
Code:
CMD:s(playerid, params[]) return cmd_shout(playerid, params);
This is optional, What this means is instead of typing the whole /shout you can just type /s and it will return the whole shout command. It is just a shortcut.

Step 7:
Now onto the last command, the /b command.
Code:
CMD:b(playerid, params[])
{
	new string[128], text[100];
	if(sscanf(params, "s[100]", text)) return SendClientMessage(playerid, -1, "USAGE: /b [TEXT]");
 	format(string, sizeof(string), "(( %s says: %s ))", GetName(playerid), text);
	ProxDetector(30.0, playerid, string, COLOR_GREY);
	return 1;
}
Ok so now this one is a little different.
Code:
new string[128], text[100];
We are declaring the strings that we will use.
Code:
if(sscanf(params, "s[100]", text)) return SendClientMessage(playerid, -1, "USAGE: /b [TEXT]");
It will check if the person has said a message after he typed /b, and if he/she hasnt it will send "USAGE: /b [TEXT]" back to them.
Code:
format(string, sizeof(string), "(( %s says: %s ))", GetName(playerid), text);
	ProxDetector(30.0, playerid, string, COLOR_GREY);
This is just formatting the string like we did earlier but this one will say "(( %s says: %s ))" because all the text will be in the OOC brackets.
The ProxDetector range here is 30m and the messages will desplay in grey.

Downloads:
foreach:
https://sampforum.blast.hk/showthread.php?tid=92679
ZCMD:
https://sampforum.blast.hk/showthread.php?tid=91354
sscanf:
https://sampforum.blast.hk/showthread.php?tid=120356

Hope this helped and I hope you guys learned a few things and that you understand.
Leave a comment if you see I left something out or if you want me to explain something.






Reply
#2

We need the stock GetName, you know.
Reply
#3

Ok added and updated with the Stock GetName for you guys
Reply
#4

You don't need to use "sscanf" for only one string.

pawn Code:
CMD:me(playerid, params[])
{
    new
        string[128];

    if (isnull(params))
    {
        SendClientMessage(playerid, -1, "USAGE: /me [action]");
    }
    else
    {
        format(string, sizeof(string), "* %s %s", GetName(playerid), params);
        ProxDetector(30, playerid, string, COLOR_PURPLE);
    }
    return 1;
}
Also, "ProxDetector" won't work as it should inside interiors and virtual worlds.
Reply
#5

Yo, didn't read through exactly everything and sorry for that. One thing that you should add in your proxdetector is to check if the player sending the string is in the same virtual world as the player near them:
Code:
stock ProxDetector(Float:radi, playerid, string[],color)
{
    new Float:x,Float:y,Float:z;
    GetPlayerPos(playerid,x,y,z);
    foreach(Player,i)
    {
        if(IsPlayerInRangeOfPoint(i,radi,x,y,z))
        {
            SendClientMessage(i,color,string);
        }
    }
}
to

Code:
stock ProxDetector(Float:radio, playerid, string[], color)
{
    new Float:x,Float:y,Float:z;
    GetPlayerPos(playerid,x,y,z);
    foreach(Player,i)
    {
        if((IsPlayerInRangeOfPoint(i,radi,x,y,z)) && ((GetPlayerVirtualWorld(playerid)) == (GetPlayerVirtualWorld(i)))
        {
            SendClientMessage(i,color,string);
        }
    }
}
Why? Because people like me use different virtual worlds for different for instance bank interiors for role-play servers. Then I don't want someone in bank B see something that was written in bank A.
Reply
#6

Hi

I got this: "error 017: undefined symbol "strreplace""
Reply
#7

Quote:
Originally Posted by anou1
View Post
Hi

I got this: "error 017: undefined symbol "strreplace""
Ok lots of people have this already defined but I will update the tutorial now.
Reply
#8

good one!
Reply
#9

After placing the CMD:ME i get this:

Code:
C:\Users\Jan\Desktop\GM\gamemodes\NewOne.pwn(410) : error 035: argument type mismatch (argument 4)
C:\Users\Jan\Desktop\GM\gamemodes\NewOne.pwn(414) : error 010: invalid function or declaration
C:\Users\Jan\Desktop\GM\gamemodes\NewOne.pwn(417) : error 010: invalid function or declaration
Pawn compiler 3.2.3664	 	 	Copyright © 1997-2006, ITB CompuPhase


3 Errors.
Reply
#10

What line is 410 and 414 and 417?
Reply
#11

Yea, shes a lil old... BUT:
Quote:

stock GetName(playerid)
{
new name[24];
GetPlayerName(playerid, name, sizeof(name));
strreplace(name, '_', ' ');
return name;

}

The red CAN BE:
Quote:

stock GetName(playerid)
{
new name[24];
GetPlayerName(playerid, name, sizeof(name));
return strreplace(name, '_', ' ');
}

Its already returning the name in the strreplace stock!
Reply
#12

You could do that if you want. But I first learn how to do it like in the tutorial. So that's why I put it that way
Reply
#13

Some of the methods are outdated and can be replaced with newer ones, but either way great tutorial.
Reply
#14

Quote:

Some of the methods are outdated and can be replaced with newer ones,

Yeah but they do the same thing
Reply
#15

Thanks.
Reply
#16

Hey, I have encountered a problem while using this, I've been googling a lot(Perhaps not good enough) but I haven't found a solution.

Any line that has the %s in it, doesn't display my name, so when I /shout, it just does: shouts: blablabla

Any help, please?
Reply
#17

Quote:

Hey, I have encountered a problem while using this, I've been googling a lot(Perhaps not good enough) but I haven't found a solution.

Any line that has the %s in it, doesn't display my name, so when I /shout, it just does: shouts: blablabla

Any help, please?

Make sure that the "%s" is in the inverted commas...
Another thing is to make sure that you are getting the players name
Code:
format(string, sizeof(string), "%s shouts: %s!",GetName(playerid),shout);
ProxDetector(50.0, playerid, string, -1);
Reply
#18

Quote:
Originally Posted by Blademaster680
View Post
Make sure that the "%s" is in the inverted commas...
Another thing is to make sure that you are getting the players name
Code:
format(string, sizeof(string), "%s shouts: %s!",GetName(playerid),shout);
ProxDetector(50.0, playerid, string, -1);
Fixed it already, but thanks for offering help. Great tut by the way. Rep.
Reply
#19

Well explained and working tutorial Gj
Reply
#20

Thanks
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)