13.02.2013, 12:31
Making an NPC
[Non-playing character/bot]
[Non-playing character/bot]
Introduction
For those who do not know, SA-MP has support for NPC's or bots.
NPC's are non-playing characters.
These characters can move.
Today, I will teach you how to enable these NPC's to do a LOT more than just walking.
Today, we will learn how to -
For those who do not know, SA-MP has support for NPC's or bots.
NPC's are non-playing characters.
These characters can move.
Today, I will teach you how to enable these NPC's to do a LOT more than just walking.
Today, we will learn how to -
- Successfully make and connect an NPC
- Enable him to interact and talk
Making an NPC and connecting him/her
First of all, We need a .PWN file and .REC file.
Use any NPC-recording filterscript in order to do so.
NOTE - Avoid HUGE recordings since NPC's use a LOT of bandwidth
Now, we begin with the real shit
On top of your gamemode -
We will be using this variable for future reference in order to make the NPC perform normal player functions.
NOTE - If you have more NPC's, add more cells to the same var or whatever, but I'd still recommend only ONE NPC since they consume a LOT of bandwidth.
Now, we connect the NPC
This is a simple function used to connect an NPC.
NOTE - BE SURE THAT 'MAX NPCS' IN SERVER.CFG IS AT LEAST 1 ELSE IT WILL FAIL TO CONNECT!
Now, to avoid going through a loop ALL time, we do this -
This will save the NPC's ID into a variable called 'npcis' which we declared earlier.
I'll explain WHY are we using this variable instead of a loop
Think this for yourself for one minute -
What would be better,
1. To loop through all players just to find an NPC
2. To save the NPC's ID into a variable for global reference
Ob...viously it'll be the first one
Congrats! We've successfully created a NPC and successfully connected it!
First of all, We need a .PWN file and .REC file.
Use any NPC-recording filterscript in order to do so.
NOTE - Avoid HUGE recordings since NPC's use a LOT of bandwidth
Now, we begin with the real shit
On top of your gamemode -
pawn Код:
new npcis;
NOTE - If you have more NPC's, add more cells to the same var or whatever, but I'd still recommend only ONE NPC since they consume a LOT of bandwidth.
Now, we connect the NPC
pawn Код:
public OnGameModeInIt()
{
npcis = INVALID_PLAYER_ID; // This sets npcis to INVALID_PLAYER_ID to make sure there are no bugs further
ConnectNPC("name_as_string", "Name_of_.pwn_file_without_extension");
return 1;
}
pawn Код:
ConnectNPC(name [ ], filename [ ]);
NOTE - BE SURE THAT 'MAX NPCS' IN SERVER.CFG IS AT LEAST 1 ELSE IT WILL FAIL TO CONNECT!
Now, to avoid going through a loop ALL time, we do this -
pawn Код:
public OnPlayerConnect(playerid)
{
if(IsPlayerNPC(playerid))
{
npcis = playerid;
// Set his skin, admin level, animations, drunk level, score, kills, deaths, or whatever
return 1; // This makes sure our NPC doesn't freeze in your registered-checks or whatever
}
return 1;
}
pawn Код:
public OnPlayerDisconnect(playerid, reason)
{
if(playerid == npcis)
{
npcis = INVALID_PLAYER_ID; // To tell the server that NPC is not connected anymore, hence breaking further operations
}
return 1;
}
I'll explain WHY are we using this variable instead of a loop
Think this for yourself for one minute -
What would be better,
1. To loop through all players just to find an NPC
2. To save the NPC's ID into a variable for global reference
Ob...viously it'll be the first one
Congrats! We've successfully created a NPC and successfully connected it!
Extensive use
of NPC's
of NPC's
How can we further expand the use of this NPC to become more than just a walking dummy?
Here's the answer how -
Prepare an array with some random dialogues
In my case, I've taken some dialogues from Jim Carrey's movies and compiled them into an array -
This prepares an array called 'BotWords' with the following dialogues.
But does this automatically enable the script to send it using NPC's name? The answer is NO.
We need to create an implementation of this under OnPlayerText -
What does this do?
Okay, let's divide it
First, we detect if the text contains the NPC's name
Second, we choose a random dialogue, get the NPC's name, and declare new string which will have the message
Third, we format the message with NPC name, NPC ID, and random dialogue
Fourth, we send it in the colour of the NPC
NOTE - Be sure to use SetPlayerColour under OnPlayerConnect in if(IsPlayerNPC(playerid)) case or the message sent will be black.
Congrats! You've successfully made a way for NPC to talk
To simplify further, here's a sample script -
You can further expand the usage of this NPC simply.
I've implemented the usage of NPC's in my anti-cheat, and you can do it too!
You can expand the usage of NPC's in almost every sort of servers!
In all kinds of servers - these can be used for basic interactions
In RP's - these can used for job-reference, info, robberies (Implement OnPlayerTakeDamage and OnPlayerShootPlayer for this)
In CnR's - these can be used for robberies, help, reference
But in the end, an NPC is always an artificial player with no intelligence, it will do only what you tell it to do, and there is no way NPC's can replace players.
Of course the things mentioned above CAN be done without using an NPC, but oh well, if you like things entertaining and not just working, then I'd say go for an NPC-talking-bot with anti-cheat abilities.
P.S - I tried my best to explain everything, and if something lacks explanation, feel free to point it out
An example is
P.S Indentation is fucked up in pawn codes due to some copy-paste and some written on spot
Here's the answer how -
Prepare an array with some random dialogues
In my case, I've taken some dialogues from Jim Carrey's movies and compiled them into an array -
pawn Код:
new BotWords[][] = {
{"You're bored? Go fuck yourself, that'd be a good entertainment! "},
{"Ya know, there ain't no kid in town capable of bustin' nude hackers like meh! "},
{"I'm feeling a little itch on my right hand today, anybody feel like takin' a slap?! "},
{"Our love is like a red, red rose... and I am a little thorny. "},
{"You gotta ask yourself one question. 'Do I feel lucky?' Well, do ya? Punks! "},
{"You were good, kid, real good. But as long as I'm around, you'll always be second best, see?"},
{"B-E-A-UTIFUL"},
{"I CAN'T LIE!!!!"},
{"Why don't ya nigga's go plant some weed?!"},
{"Alllrightyy then, you asked for it!"},
{"I'll send you to Wonderland if you don't shut the fuck up! "},
{"Good dog, good dog, now come to papa! "}
};
But does this automatically enable the script to send it using NPC's name? The answer is NO.
We need to create an implementation of this under OnPlayerText -
pawn Код:
public OnPlayerText(playerid, text [ ])
{
if(strfind(text, "Jim", true) != -1 || strfind(text, "Carrey", true) != -1) // My NPC's name is Jim Carrey
// Replace 'Jim' here with your NPC's first name and 'Carrey' with his second name
{
new string[124], name[20]; // We declare 2 strings, one to store the message to be sent and one to store NPC's name
new rand = random(sizeof(BotWords)); // To choose one of the random dialogues from the array we made
format(string, sizeof(string), "%s[%d]:{FFFFFF} %s",GetPlayerName(playerid, name, 20),npcis, BotWords[rand][0]); // Formatting the message
SendClientMessageToAll(GetPlayerColor(npcis), string); // Sending it
}
return 1;
}
Okay, let's divide it
First, we detect if the text contains the NPC's name
Second, we choose a random dialogue, get the NPC's name, and declare new string which will have the message
Third, we format the message with NPC name, NPC ID, and random dialogue
Fourth, we send it in the colour of the NPC
NOTE - Be sure to use SetPlayerColour under OnPlayerConnect in if(IsPlayerNPC(playerid)) case or the message sent will be black.
Congrats! You've successfully made a way for NPC to talk
To simplify further, here's a sample script -
pawn Код:
new npcis;
new BotWords[][] = {
{"You're bored? Go fuck yourself, that'd be a good entertainment! "},
{"Ya know, there ain't no kid in town capable of bustin' nude hackers like meh! "},
{"I'm feeling a little itch on my right hand today, anybody feel like takin' a slap?! "},
{"Our love is like a red, red rose... and I am a little thorny. "},
{"You gotta ask yourself one question. 'Do I feel lucky?' Well, do ya? Punks! "},
{"You were good, kid, real good. But as long as I'm around, you'll always be second best, see?"},
{"B-E-A-UTIFUL"},
{"I CAN'T LIE!!!!"},
{"Why don't ya nigga's go plant some weed?!"},
{"Alllrightyy then, you asked for it!"},
{"I'll send you to Wonderland if you don't shut the fuck up! "},
{"Good dog, good dog, now come to papa! "}
};
public OnGameModeInIt( )
{
npcis = INVALID_PLAYER_ID;
ConnectNPC("Jim_Carrey", "NPC");
return 1;
}
public OnPlayerConnect(playerid)
{
if(IsPlayerNPC(playerid))
{
npcis = playerid;
SetPlayerColor(playerid, -1);
}
return 1;
}
public OnPlayerDisconnect(playerid)
{
if(IsPlayerNPC(playerid))
{
npcis = INVALID_PLAYER_ID;
}
return 1;
}
public OnPlayerText(playerid, text [ ])
{
if(strfind(text, "Jim", true) != -1 || strfind(text, "Carrey", true) != -1)
{
new string[124];
new rand = random(sizeof(BotWords));
format(string, sizeof(string), "%s[%d]:{FFFFFF} %s", pname(sInfo[npcis]), sInfo[npcis], BotWords[rand][0]);
SendClientMessageToAll(GetPlayerColor(sInfo[npcis]), string);
}
return 1;
}
I've implemented the usage of NPC's in my anti-cheat, and you can do it too!
You can expand the usage of NPC's in almost every sort of servers!
In all kinds of servers - these can be used for basic interactions
In RP's - these can used for job-reference, info, robberies (Implement OnPlayerTakeDamage and OnPlayerShootPlayer for this)
In CnR's - these can be used for robberies, help, reference
But in the end, an NPC is always an artificial player with no intelligence, it will do only what you tell it to do, and there is no way NPC's can replace players.
Of course the things mentioned above CAN be done without using an NPC, but oh well, if you like things entertaining and not just working, then I'd say go for an NPC-talking-bot with anti-cheat abilities.
P.S - I tried my best to explain everything, and if something lacks explanation, feel free to point it out
An example is
pawn Код:
public OnPlayerStateChange(playerid, newstate, oldstate)
{
new act = GetPlayerSpecialAction(playerid);
if(act == SPECIAL_ACTION_USEJETPACK && IsPlayerAdmin(playerid) != 1)
{
new rsn[80];
format(rsn, 80, "%d Jetpack_Hacks", playerid);
return cmd_ban(npcis, rsn);
}
return 1;
}