Hello guys,
In this tutorial I'll show you how to make a basic faction system which can be used for roleplay servers, or even RPG. In the process of writing the codes, I'll give standard explanations of what each of them mean.

Right, let's start with the includes.
Code:
#include <a_samp>
#include <zcmd>
#include <sscanf2>

- The "<a_samp>" include is a default include that can be found in every includes folder in your pawno directory.
- The "<zcmd>" include is a command processor(function created by Zeex).
- The "<sscanf2>" include is mainly used for processing various of functions in a code(author is Alex "Y_Less").

Moving on to the variables;
Code:
enum pInfo
{
pFac,
pLead
};
new PlayerInfo[MAX_PLAYERS][pInfo];

Basically, this variable would assist us to define the value of what I would refer as "stat".

Now comes the command part
Code:
CMD:leader(playerid, params[])
{
new string[256], targetid, faction, name[128];
if(sscanf(params, "ui", targetid, faction))
{
SendClientMessage(playerid, 0xFFFFFFAA, "Syntax: /leader [ID] [facID]");
SendClientMessage(playerid, 0xFFFFFFAA, "1-LSPD | 2-CIA | 3-NG");
return 1;
}

if(faction == 1) { name = "LSPD"; }
else if(faction == 2) { name = "CIA"; }
else if(faction == 3) { name = "NG"; }
else { return 1; }

PlayerInfo[targetid][pFac] = faction;
PlayerInfo[targetid][pLead] = faction;

new pname[256], tname[256];
GetPlayerName(playerid, pname, sizeof(pname));
GetPlayerName(targetid, tname, sizeof(tname));

format(string, sizeof(string), "You made %s leader of %s.", tname, name);
SendClientMessage(playerid, 0xFFFFFFAA, string);
format(string, sizeof(string), "%s has made you leader of %s.", pname, name);
SendClientMessage(targetid, 0xFFFFFFAA, string);
return 1;
}


Code:
new string[256], targetid, faction, name[128];
-This is the variable part, where I define the functions I'll be using(string for the messages at the end; targetid for the ID of the player you'd like to give the faction{s}; faction for the faction's ID; name for the name of the faction.

Code:
if(sscanf(params, "ui", targetid, faction))
{
SendClientMessage(playerid, 0xFFFFFFAA, "Syntax: /leader [ID] [facID]");
SendClientMessage(playerid, 0xFFFFFFAA, "1-LSPD | 2-CIA | 3-NG");
return 1;
}
-Using this code, if you send the command without putting both of the required strings in it, it'll automatically send you the two messages that show you how to use it, and the faction IDs.

Code:
if(faction == 1) { name = "LSPD"; }
else if(faction == 2) { name = "CIA"; }
else if(faction == 3) { name = "NG"; }
else { return 1; }
-These functions' purposes are to define the names of the factions(you can see how faction number one has been defined with the name of "LSPD").

Code:
PlayerInfo[targetid][pFac] = faction;
PlayerInfo[targetid][pLead] = faction;
-This function is the one to set the player as a member and leader of the faction.

Code:
new pname[256], tname[256];
GetPlayerName(playerid, pname, sizeof(pname));
GetPlayerName(targetid, tname, sizeof(tname));
-These 3 lines right here are to get the player names of both the user, and the targeted person.

Code:
format(string, sizeof(string), "You made %s leader of %s.", tname, name);
SendClientMessage(playerid, 0xFFFFFFAA, string);
format(string, sizeof(string), "%s has made you leader of %s.", pname, name);
SendClientMessage(targetid, 0xFFFFFFAA, string);
-The final part of the command is the part where the messages are sent to both the person who wrote the command, and the person who gets the faction leadership.

Since I explained the command above, I assume you might understand how things are going in the following command(to invite someone into the faction, and the one after that - to leave the faction you're in).

Code:
CMD:invite(playerid, params[])
{
if(PlayerInfo[playerid][pLead] >= 1)
{
new string[256], targetid;
if(sscanf(params, "u", targetid)) return SendClientMessage(playerid, 0xFFFFFFAA, "Syntax: /invite [ID]");

PlayerInfo[targetid][pFac] = PlayerInfo[playerid][pFac];

new pname[256], tname[256];
GetPlayerName(playerid, pname, sizeof(pname));
GetPlayerName(targetid, tname, sizeof(tname));
format(string, sizeof(string), "You have invited %s to your faction.", tname);
SendClientMessage(playerid, 0xFFFFFFAA, string);
format(string, sizeof(string), "%s has invited you to their faction.", pname);
SendClientMessage(targetid, 0xFFFFFFAA, string);
}
else
{
SendClientMessage(playerid, 0xFFFFFFAA, "You're not a faction leader!");
}
return 1;
}

Code:
CMD:terminate(playerid, params[])
{
if(PlayerInfo[playerid][pLead] >= 1)
{
new string[256], targetid;
if(sscanf(params, "u", targetid)) return SendClientMessage(playerid, 0xFFFFFFAA, "Syntax: /terminate [ID]");

if(PlayerInfo[targetid][pFac] == PlayerInfo[playerid][pFac])
{
new pname[256], tname[256];
GetPlayerName(playerid, pname, sizeof(pname));
GetPlayerName(targetid, tname, sizeof(tname));
format(string, sizeof(string), "You have removed %s from your faction.", tname);
SendClientMessage(playerid, 0xFFFFFFAA, string);
format(string, sizeof(string), "%s has removed you from their faction.", pname);
SendClientMessage(targetid, 0xFFFFFFAA, string);

PlayerInfo[targetid][pFac] = 0;
}
else
{
SendClientMessage(playerid, 0xFFFFFFAA, "The player you're trying to terminate is not from your faction!");
}
}
else
{
SendClientMessage(playerid, 0xFFFFFFAA, "You're not a faction leader!");
}
return 1;
}

Code:
CMD:leavefac(playerid, params[])
{
PlayerInfo[playerid][pFac] = 0;
PlayerInfo[playerid][pLead] = 0;
SendClientMessage(playerid, 0xFFFFFFAA, "You have left your current faction!");
return 1;
}

Now, as I stated in the beginning, this is a simple faction system, which means I haven't restricted the command for admins or staff players, but to do so, you'll have to mark all of the code(from "new string[256]" to the last "SendClientMessage" and then restrict it yourself, using the variable you'd like.

P.P: You'll have to edit the "/invite" command in order to customize it to your like, as I've made it as simple as possible.
__________________
SAMP Player since 2010, hardcore Roleplayer.