SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help > Tutorials

Reply
 
Thread Tools Display Modes
Old 17/04/2012, 09:53 AM   #1
TheBetaFox
Huge Clucker
 
TheBetaFox's Avatar
 
Join Date: Jan 2011
Location: Nowhere.
Posts: 265
Reputation: 88
Default Things to do with OnPlayerText

Things to do with OnPlayerText


First of all, as you may know, the callback OnPlayerText gets called every single time a player types something in the server chat.
There are many uses for it which could help in personalizing your server or even enhancing the way the gamemode itself is played, so I am going to show you some of the more basic uses.
NOTE: This tutorial assumes that you have at least a basic knowledge of the PAWN language and of the default SA-MP functions.
1. Introduction
OnPlayerText itself is easy to understand.
It has two parameters, 'playerid' and 'text[]'.
  • playerid is an integer (i.e a whole number) and it represents the ID of the player who has typed the message.
  • text[] is a string and it represents the text that the player has typed into the chat.
pawn Code:
public OnPlayerText(playerid, text[])
{
    return 1;
}
  • Returning 1 sends the default message, like: "Your name: Message"
  • Returning 0 doesn't send the default message, allowing you to... improvise.
By exploiting this function, we can do various things.

2. Uses
  • Changing the text that was supposed to show up
The messages you send by the chat usually show up in SA-MP as "Your name: Message". But what if you want to add the ID, and make it "Your name: [ID] Message"?

First of all we change 'return 1;' to 'return 0;'. If we do so, the original message will not be sent.
pawn Code:
public OnPlayerText(playerid, text[])
{
    return 0;
}

Then, we define a new string of size 128. Call it whatever you want, but in this tutorial I will call it 'msg'.
pawn Code:
public OnPlayerText(playerid, text[])
{
    new msg[128]; // The string. We do not need to have it larger than 128, because a message can't be larger than that.
    return 0;
}

Now, we'll have to format the string. As we wish to insert the player's ID (an integer) in the text, we will use the format function, to turn the string into '[%d] %s' as so:
%d means integer, and we will put the player ID in its place.
%s means string, and we will put the text in its place.
pawn Code:
public OnPlayerText(playerid, text[])
{
    new msg[128]; // The string. We do not need to have it larger than 128, because a message can't be larger than that.
    format(msg, sizeof(msg), "[%d] %s", playerid, text); // The formatted message. Remember, %d means integer (whole number) and %s is string - they are associated with playerid, respectively text.
    return 0;
}

It may look like we're done, but we are not. The message is formatted, but it hasn't been sent yet! Therefore, if you try to chat right now, no message will come out - and I don't think that helps much, if at all, so there's one last thing to do.
Call SendPlayerMessageToAll, with senderid as playerid and with the text as 'msg', as so:
pawn Code:
public OnPlayerText(playerid, text[])
{
    new msg[128]; // The string. We do not need to have it larger than 128, because a message can't be larger than that.
    format(msg, sizeof(msg), "[%d] %s", playerid, text); // The formatted message. Remember, %d means integer (whole number) and %s is string - they are associated with playerid, respectively text.
    SendPlayerMessageToAll(playerid, msg); // SendPlayerMessageToAll will send a message from the player to everyone, like what would happen normally when a player chats, but with the message we choose.
    return 0;
}
Now, the message will look like "Your name: [ID] Message"!

You could potentially adjust this so you can see anything you want - if you have a function in your gamemode that returns something like the team name or the rank of the player as a string (i.e as a (group of) word(s), not as a number), we could use it and show it in the message.
pawn Code:
public OnPlayerText(playerid, text[])
{
    new msg[128]; // The string. We do not need to have it larger than 128, because a message can't be larger than that.
    format(msg, sizeof(msg), "[%s] %s", GetPlayerTeamName(playerid), text); // The formatted message. Remember, %s means string - the strings are associated with GetPlayerTeamName(playerid), respectively text.
    SendPlayerMessageToAll(playerid, msg); // SendPlayerMessageToAll will send a message from the player to everyone, like what would happen normally when a player chats, but with the message we choose.
    return 0;
}
(There is no function like that, and nor have we defined it. This is just an example. Say, if your team name is 'Red' then in place of the ID you will see [Red]. You could've also done this by changing the player colour, and therefore you would have no need for the such, but this is just an example.)
  • Making an admin chat

Say, you want to discuss things with your admins in private on the server, but without PMing each of them - that's why you need an admin chat! You could also make it with a command, but why not simplify it:
If the admin makes a message that starts with #, it will automatically be shown to other admins!
We will once again start from the 'default' OnPlayerText, but you can continue on the 'old' one as well.
pawn Code:
public OnPlayerText(playerid, text[])
{
    return 1;
}

First, add a check to see if the player is an admin. We will use IsPlayerAdmin, which is used to check if a player is logged in RCON, but you can change it with any other function/variable which shows the player's admin level.
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsPlayerAdmin(playerid))
    {
         // our code will be here
    }
    return 1;
}

To the if statement we have just created, we will add "&& text[0] == '#'" to check if the first character in the text is #. You can change it to whatever other character you'd choose for admin chat.
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsPlayerAdmin(playerid) && text[0] == '#')
    {
         // our code will be here
    }
    return 1;
}

Then, we will create a new string, with the size of 128 (like in the previous parts, name it whatever you'd like), and format it as so:
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsPlayerAdmin(playerid) && text[0] == '#')
    {
         new msg[128];
         format(msg, sizeof(msg), "[ADMIN CHAT] %s: %s", pName, text[1]);
    }
    return 1;
}

But wait! We don't have any 'pName' variable. Create it as a string with the size of MAX_PLAYER_NAME, and use the GetPlayerName function to get the player's name. In this tutorial we assume that you know how to use the basic functions, so we won't explain the usage of GetPlayerName in detail - however, there's not much to explain at all.
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsPlayerAdmin(playerid) && text[0] == '#')
    {
         new msg[128], pName[MAX_PLAYER_NAME];
         GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
         format(msg, sizeof(msg), "[ADMIN CHAT] %s: %s", pName, text[1]);
    }
    return 1;
}

Perfect! Now we need to show it to all admins.
Add this to the end of your gamemode:
pawn Code:
stock SendMessageToAdmins(text[])
{
    for(new i = 0, i < MAX_PLAYERS, i++)
    {
        if(IsPlayerAdmin(i))
        {
            SendClientMessage(i, -1, text);
        }
    }
}
Change IsPlayerAdmin(i) with any other function or variable containing your admin level, such as PlayerInfo[i][pAdmin]. If you have multiple levels, you can do it like "if(GetPlayerAdmin(playerid) >= 1)" (assuming you have such a function).

Now, add it as so into OnPlayerText:
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsPlayerAdmin(playerid) && text[0] == '#')
    {
         new msg[128], pName[MAX_PLAYER_NAME];
         GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
         format(msg, sizeof(msg), "[ADMIN CHAT] %s: %s", pName, text[1]);
         SendMessageToAdmins(msg);
    }
    return 1;
}

You could also add the ID as in the previous example, like so:
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsPlayerAdmin(playerid) && text[0] == '#')
    {
         new msg[128], pName[MAX_PLAYER_NAME];
         GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
         format(msg, sizeof(msg), "[ADMIN CHAT] %s (ID %d): %s", pName, playerid, text[1]);
         SendMessageToAdmins(msg);
    }
    return 1;
}
And our admin chat is done!
Strfind will look in the string for a certain word.
This can be used for various things, and I will give an example.
Once again, we start with the 'base' OnPlayerText.
pawn Code:
public OnPlayerText(playerid, text[])
{
    return 1;
}

We will first add an if statement which checks for two 'words' in the text: 'how' and 'get car'.
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(strfind(text, "how", true) != -1 && strfind(text, "get car", true) != -1) {
        // our code goes here
    }
    return 1;
}

Then, we return 0, so the message doesn't get sent, and we send the player this message: "To get a car, please use the /v command.".
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(strfind(text, "how", true) != -1 && strfind(text, "get car", true) != -1) {
        SendClientMessage(playerid, -1, "To get a car, please use the /v command.");
        return 0;
    }
    return 1;
}

You can use this with various other strings in order to make your fun/stunt server more awesome, for example if the player says 'help me up', you can set his position 10 meters higher.
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(strfind(text, "help me up", true)) {
        new Float:X, Float:Y, Float:Z;
        GetPlayerPos(playerid, X, Y, Z);
        SetPlayerPos(playerid, X, Y, Z + 10);
        SendClientMessage(playerid, -1, "I've set your position 10 meters higher - I hope you aren't stuck anymore!");
        return 0;
    }
    return 1;
}
(Yes, the very same thing can also be done with a simple command, but why not?)


  • Answering questions
For example, you can ask a question to the player, such as 'How old are you?', and you want the player to answer to this question directly by writing it into the chat.
Once again, we start with the base OnPlayerText function.
pawn Code:
public OnPlayerText(playerid, text[])
{
    return 1;
}

First of all, we will have to create some variables, but before that, please do the following if you haven't already:
At the top of your gamemode, put this:
pawn Code:
#undef MAX_PLAYERS
#define MAX_PLAYERS 200
Replace the '200' with your max player count. If it's less than 500, it will help, because it will use less space.

Now, we can create the variables! Make IsAnswering and pAge, with the size of MAX_PLAYERS, and define QUESTION_AGE as 1 and QUESTION_NONE as 0, like so:
pawn Code:
new IsAnswering[MAX_PLAYERS];
new pAge[MAX_PLAYERS];
#define QUESTION_NONE 0
#define QUESTION_AGE  1

Now, where shall we ask the question? Let's do it in OnPlayerSpawn.
pawn Code:
public OnPlayerSpawn(playerid)
{
    SendClientMessage(playerid, -1, "QUESTION: How old are you? (please answer the question in the chat.)");
    IsAnswering[playerid] = QUESTION_AGE;    
    return 1;
}
We have asked the player the question, and we have set IsAnswering to QUESTION_AGE so that we know what he will be answering in OnPlayerText.

Now, let's add an if statement which checks whether the player is answering QUESTION_AGE.
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsAnswering[playerid] == QUESTION_AGE)
    {
        // our code will be here!
    }
    return 1;
}

Now, let's think. What should we do? We should return 0 so the players don't see it, but how do we get the value as an integer, given that the text is a string?
Here's where we get saved by a very magic function - strval! We will declare a new variable and store the value of the string in it.
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsAnswering[playerid] == QUESTION_AGE)
    {
        new age; // Declare the age variable.
        age = strval(text); // Set it to the value of the text.
        pAge[playerid] = age; // Set the Age variable to the typed age, which can be saved with the system of your choice.
        IsAnswering[playerid] = QUESTION_NONE; // You can add multiple questions and change it to the ID of the next question, then put the next question below as a ClientMessage.
        return 0;
    }
    return 1;
}

Of course, we might want to keep players from lying about their age or to keep 'kids' off our servers...
pawn Code:
public OnPlayerText(playerid, text[])
{
    if(IsAnswering[playerid] == QUESTION_AGE)
    {
        new age;
        age = strval(text);
        if(age >= 18 && age <= 100) // If you're old enough to play San Andreas and in realistic boundaries of age
        {
            pAge[playerid] = age; // Set the Age variable to the typed age, which can be saved with the system of your choice.
        }
        else if(age <= 18)
        {
                SendClientMessage(playerid, -1, "You're not old enough to play San Andreas!");
            Kick(playerid);
        }
        else if(age >= 100)
        {
            SendClientMessage(playerid, -1, "You can't be that old, and if you are, why are you playing San Andreas?");
            Kick(playerid);
        }
        return 0;
    }
    return 1;
}
.... Just kidding; I am underage person myself! This is just an example of what can be done.

This tutorial might be updated soon with more examples!
(EDIT: as of the 17th of August, 2013, I have not yet managed to do this; however, expect an update soon!)
3. Challenges for beginners
  1. Make a VIP chat, alongside the admin chat! If you understood anything of what was going on, it should be a piece of cake for you. Otherwise, do read the tutorial again. (Extremely Easy)
  2. Show a chat bubble above the player with the text that he has typed! (tip: make use of SetPlayerChatBubble) (Extremely Easy)
  3. Make a mute system! If the player is muted, his message doesn't get sent and he gets a message like 'You are muted. You cannot talk.' (Easy)
  4. Make a full tutorial! This shouldn't be hard, and only requires you to add more defines and if statements. (Easy)
  5. Make chat channels! If the player is in channel 1, he can only get messages from channel 1, if he's in channel 2, only from channel 2 and so on. (Medium)
  6. Make a censorship script: if the player says something like 'hi, <bad word here> you' change it into 'hi, **** you' WITHOUT removing the entire message. (tip: make use of strfind) (Medium/Hard)

P.S: If you actually read the whole tutorial and you have found mistakes in the text, please tell me. Thank you in advance!

Last edited by TheBetaFox; 17/08/2013 at 09:14 PM. Reason: Corrections within the text, promises for updates.
TheBetaFox is offline   Reply With Quote
Old 17/04/2012, 10:09 AM   #2
Hoss
Huge Clucker
 
Join Date: Sep 2010
Posts: 201
Reputation: 85
Default Re: Things to do with OnPlayerText

Good tutorial
Hoss is offline   Reply With Quote
Old 17/04/2012, 11:56 AM   #3
ReneG
High-roller
 
Join Date: Oct 2011
Location: Sublime Text 2
Posts: 2,005
Reputation: 333
Default Re: Things to do with OnPlayerText

This is one of the very few tutorials that I liked. I like how you challenge the reader at the end. You should make more.
ReneG is offline   Reply With Quote
Old 17/04/2012, 12:38 PM   #4
TheBetaFox
Huge Clucker
 
TheBetaFox's Avatar
 
Join Date: Jan 2011
Location: Nowhere.
Posts: 265
Reputation: 88
Default Re: Things to do with OnPlayerText

Updated! I've added a section on 'Question answering', plus one new Easy challenge! Enjoy!

Quote:
Originally Posted by Hoss View Post
Good tutorial
Quote:
Originally Posted by VincentDunn View Post
This is one of the very few tutorials that I liked. I like how you challenge the reader at the end. You should make more.
Thanks a lot, guys! I appreciate that you like the tutorial. I'm still in the Easter vacation, so I have some time to make more tutorials.
__________________
Looking to work on something.
Send me a PM if you wish to talk to me privately,
as I will not respond to visitor messages.
TheBetaFox is offline   Reply With Quote
Old 17/04/2012, 01:32 PM   #5
Y_Less
Beta Tester
 
Y_Less's Avatar
 
Join Date: Jun 2008
Location: 629 - git.io/Y
Posts: 18,314
Reputation: 2579
Default Re: Things to do with OnPlayerText

Quote:
Originally Posted by VincentDunn View Post
This is one of the very few tutorials that I liked. I like how you challenge the reader at the end. You should make more.
Agreed, it's a good way to cement learning. Also:

Quote:
Originally Posted by TheBetaFox View Post
pawn Code:
stock SendMessageToAdmins(text[]) {
    for(new i = 0, i < MAX_PLAYERS, i++) {
        if(IsPlayerConnected(i)) {
            if(IsPlayerAdmin(i)) {
                SendClientMessage(playerid, -1, text);
            }
        }
    }
}
If they are not connected then they are not an admin:

Quote:
Originally Posted by TheBetaFox View Post
pawn Code:
stock SendMessageToAdmins(text[]) {
    for(new i = 0, i < MAX_PLAYERS, i++) {
        if(IsPlayerAdmin(i)) {
            SendClientMessage(i, -1, text);
        }
    }
}

Last edited by Y_Less; 17/04/2012 at 04:02 PM.
Y_Less is offline   Reply With Quote
Old 17/04/2012, 01:57 PM   #6
iggy1
High-roller
 
iggy1's Avatar
 
Join Date: Mar 2009
Location: One past the end.
Posts: 2,383
Reputation: 235
Default Re: Things to do with OnPlayerText

Nice tutorial. You can also format the text argument so you don't have to create an additional array. Not a big improvement but worth mentioning. This is assuming that it doesn't matter if "text[]" is altered.

Removed code that can cause possible bugs.
__________________
Quote:
Originally Posted by Y_Less
That code compiles perfectly, but I can tell you now it won't make me a cup of tea.
"No offense, but you are a stupid asshole." - Ron Burgundy

Last edited by iggy1; 17/04/2012 at 03:07 PM.
iggy1 is offline   Reply With Quote
Old 17/04/2012, 02:16 PM   #7
Y_Less
Beta Tester
 
Y_Less's Avatar
 
Join Date: Jun 2008
Location: 629 - git.io/Y
Posts: 18,314
Reputation: 2579
Default Re: Things to do with OnPlayerText

Quote:
Originally Posted by iggy1 View Post
Nice tutorial. You can also format the text argument so you don't have to create an additional array. Not a big improvement but worth mentioning. This is assuming that it doesn't matter if "text[]" is altered.

pawn Code:
public OnPlayerText(playerid, text[])
{
   
    format( text, 128, "[ADMIN CHAT] %s: %s", pName, text[1]);
    //send message
    return 1;
}
It can matter if you are making the string longer and putting it in to a buffer which may not be large enough.
Y_Less is offline   Reply With Quote
Old 17/04/2012, 03:53 PM   #8
AlExAlExAlEx
Gangsta
 
Join Date: Nov 2008
Posts: 693
Reputation: 5
Default Re: Things to do with OnPlayerText

pawn Code:
stock SendMessageToAdmins(text[]) {
    for(new i = 0, i < MAX_PLAYERS, i++) {
        if(IsPlayerConnected(i)) {
            if(IsPlayerAdmin(i)) {
                SendClientMessage(playerid, -1, text);
            }
        }
    }
}
undefined symbol "playerid"
__________________
AlExAlExAlEx is offline   Reply With Quote
Old 17/04/2012, 04:09 PM   #9
Wickeed
Big Clucker
 
Join Date: Jan 2012
Posts: 66
Reputation: -3
Default Re: Things to do with OnPlayerText

Good Tutorial
__________________


Hate this without reason...
Wickeed is offline   Reply With Quote
Old 17/04/2012, 04:13 PM   #10
Niko_boy
High-roller
 
Niko_boy's Avatar
 
Join Date: Aug 2010
Location: Somewhere i belong
Posts: 1,428
Reputation: 137
Default Re: Things to do with OnPlayerText

Nice tutorial useful for all
__________________
$$$ If anyone want to get any of these:
  • DM/TDM/Freeroam/Stunt server, filterscripts or Bug fixing.or some general mapping. Above all any of the logos and banners or signature sorta stuff aswell.at some cheap and worth-full prices.
can Contact me for more info or a deal.
•••[0.3x]LCS•Freeroam•DM•Stunts•Race•Parkour•••AutoArena [0.3z][No SkinShot][sixtytiger.com]Want a decent Attack Defend Gamemode?
176.31.120.76:7777176.31.229.148:7830Get This! Attack-Defend(v2.3.1)
Niko_boy is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
OnPlayerText hmm Twinki1993 Scripting Help 10 09/01/2012 02:17 AM
[Help] OnPlayerText JFT Scripting Help 1 19/09/2011 03:12 AM
[NGG] [NGRP] Well, So I'll just make a thread to highlight... certain things... to more, set things straight. Sew_Sumi Everything and Nothing 21 03/07/2011 05:29 PM
Weird things on OnPlayerText leong124 Help Archive 3 03/04/2011 03:50 AM
OnPlayerText Hash [NL-RP] Help Archive 5 27/07/2010 05:16 PM


All times are GMT. The time now is 02:46 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.