[Tutorial] How to make a simple contract system (Good for RP)
#1

I've made this simple contract system while I was learning how to script. It's not difficult, and in my opinion, it's pretty cool.

What you'll need

- sscanf
- ZCMD
- A basic saving system

Getting started

First, we want to create something that can store our contract (The price of the contract on somebody's head).
For this we'll just simply do this: (NOTE: I'm not going to explain how you need to make this, there's a tutorial here, I can't find the link atm, will upload later)

We also want it so only HITMANS can kill the player and get the money, not just regular players. So we'll also make pFaction
pawn Code:
enum pInfo
{
   pContract // This will store the price of the contract on somebody's head. If it's 0 then the system will just ignore it
   pFaction
}

new PlayerInfo[MAX_PLAYERS][pInfo];
Alright, after that's made we want to create a command so somebody can put a contract on somebody elses head. Therefore we'll need ZCMD & SSCANF.

Let's start with making our command.

Every command(in ZCMD) starts with this
pawn Code:
CMD:contract(playerid, params[])
Now, that isn't that hard. After that we'll include our sscanf. For that we'll need to make some new variables.

pawn Code:
CMD:contract(playerid, params[])
{
    new pID, bounty, message1[170], message2[170];
    if(sscanf(params,"ud", pID, bounty)) return SendClientMessage(playerid, COLOR_WHITE, "USAGE: /contract [playerid][amount]");
    {
Let me break that up for you.

pawn Code:
new pID, bounty, message1[170], message2[170];
This will make our new variables. pID will be the ID we want to put the contract on. Bounty will be the price you'll put on his head. We'll need the message variable to format our messages. More on that later.

pawn Code:
if(sscanf(params,"ud", pID, bounty)) return SendClientMessage(playerid, COLOR_WHITE, "USAGE: /contract [playerid][amount]");
This will scan if everything is correct. If you don't understand this part, please go to the tutorial of sscanf. (Once again, I don't know the link.)

We'll also make it so nobody can put a negative value on a players head, therefore we make:

pawn Code:
if(bounty <= 0) return SendClientMessage(playerid, -1, "You can't put negative values on a players head!");
After that, we want to put the bounty on the players head. Remember when we made the pContract? We'll need it now! Let's store the bounty in the players pContract.

pawn Code:
PlayerInfo[pID][pContract] = bounty;
This will add the bounty on the players head. We also want that the amount of cash will be fined of the player. We can do this very easily. There's something useful called GivePlayerMoney. We'll use that!

pawn Code:
GivePlayerMoney(playerid, -bounty);
As you can see I made it -bounty instead of just bounty. This is because we want to REDUCE the players money and not ADD the money.

We also want to make a message so the player knows he succesfully made a contract on the players head.
This can be done with SendClientMessage. But we also want to let the player know HOW MUCH he put a bounty on the players head. Therefore we'll need our good friend called format!

pawn Code:
format(message1,sizeof(message1), "You've put a contract on the players head for $%d", bounty);
As you can see I've used my variable message1. It's manditory that message1 is an array, or this won't work. I've also used %d and at the end I put ,bounty. We use %d when we want to call a number and %s when we want to call a string. In this command it'll call a number, the bounty we've put on the players head, therefore we use %d. After that we'll say to the server what %d needs to be. Here it needs to be our bounty, so we put that at the end! Alright, so we've formatted our message, but now we need to send it. Therefore we use SendClientMessage!

pawn Code:
format(message1,sizeof(message1), "You've put a contract on the players head for $%d", bounty);
SendClientMessage(playerid, -1, message1);
Not that hard I think. Here we are just sending our message1 to the player thats calling the command.

This is how your code should look like by now:

pawn Code:
CMD:contract(playerid, params[])
{
    new pID, bounty, message1[170], message2[170];
    if(sscanf(params,"ud", pID, bounty)) return SendClientMessage(playerid, COLOR_WHITE, "USAGE: /contract [playerid][amount]");
if(bounty <= 0) return SendClientMessage(playerid, -1, "You can't put negative values on a players head!");
    {
        GivePlayerMoney(playerid, -bounty);
        format(message1,sizeof(message1), "You've put a contract on the players head for $%d.", bounty);
        SendClientMessage(playerid, -1, message1);
        PlayerInfo[pID][pContract] = bounty;
}
Alright so, we've made the command. But we'll need to notice the hitmans that there is a new contract!
We'll use the for-loop. This will loop through all the players. We'll make it so everytime the server detects a hitman, it will send a message to him!

pawn Code:
for(new i = 0; i < MAX_PLAYERS; i++)
        {
            if(PlayerInfo[i][pFaction] == 3)
            {
                format(message2,sizeof(message2), "HQ: A player has put a contract on %s for $%d.", GetName(pID), bounty);
                SendClientMessage(i, -1, message2);
            }
        }
Let me explain this for you.

pawn Code:
if(PlayerInfo[i][pFaction] == 3)
This will check if the player is in the Hitman Faction, here number 3. If the player IS in the hitman faction, it will send a message.

pawn Code:
format(message2,sizeof(message2), "HQ: A player has put a contract on %s for $%d.", GetName(pID), bounty);
SendClientMessage(i, -1, message2);
(NOTE: GetName is probably not defined in your script, it's pretty easy and there are a lot of tutorials on it. Use the useful search function!)

This will send a message to everybody that is in Faction 3. It'll let them know on who a contract has been placed and for how much.

Alright, we just need to add return 1 at the end and our command is ready! It should look like this:

pawn Code:
CMD:contract(playerid, params[])
{
    new pID, bounty, message1[170], message2[170];
    if(sscanf(params,"ud", pID, bounty)) return SendClientMessage(playerid, COLOR_WHITE, "USAGE: /contract [playerid][amount]");
if(bounty <= 0) return SendClientMessage(playerid, -1, "You can't put negative values on a players head!");
    {
        GivePlayerMoney(playerid, -bounty);
        format(message1,sizeof(message1), "You've put a contract on the players head for $%d.", bounty);
        SendClientMessage(playerid, -1, message1);
        PlayerInfo[pID][pContract] = bounty;

        for(new i = 0; i < MAX_PLAYERS; i++)
        {
            if(PlayerInfo[i][pFaction] == 3)
            {
                format(message2,sizeof(message2), "HQ: A player has put a contract on %s for $%d.", GetName(pID), bounty);
                SendClientMessage(i, -1, message2);
            }
        }
    }
    return 1;
}
Compiled with no errors? Moving on then! Now we'll need to go to OnPlayerDeath. We want to check if when a player dies, if he has a contract on his head and if the killer is a hitman.

So now we want to check if our killerid is in the Hitman Faction, our Faction number 3 AND if the playerid has a contract on his head. So we'll add an if-statement.

pawn Code:
if(PlayerInfo[killerid][pFaction] == 3) // Checks if the killerid is a hitman
    {
        if(PlayerInfo[playerid][pContract] > 0) // Checks if the player has a contract on his head, if not, the server will do nothing.
        {
Not that hard. So now we want to say to the server what it needs to do if the playerid has a contract on his head and killerid is a hitman. We want it so that the playerid loses money and the killerid gains money!
We'll use our friend GivePlayerMoney and Format again.

pawn Code:
new message1[170];
            GivePlayerMoney(playerid, -PlayerInfo[playerid][pContract]);
            format(message1, sizeof(message1), "You've been critically injured by a Hitman and lost $%d.", PlayerInfo[playerid][pContract]);
            SendClientMessage(playerid, -1, message1);
            GivePlayerMoney(killerid, PlayerInfo[playerid][pContract]);
Let me explain this for you.

pawn Code:
GivePlayerMoney(playerid, -PlayerInfo[playerid][pContract]);
This will REDUCE (notice the - at the begining of PlayerInfo) the players money. The amount we want to reduce equals to the contract on his head.

pawn Code:
format(message1, sizeof(message1), "You've been critically injured by a Hitman and lost $%d.", PlayerInfo[playerid][pContract]);
SendClientMessage(playerid, -1, message1);
This is what we did in our command too, isn't that hard.

pawn Code:
GivePlayerMoney(killerid, PlayerInfo[playerid][pContract])
This will give our hitman the bounty that was on the playerids head. This will ADD money (Now notice that I don't use the -, because we want it to ADD).

Now we're almost there! We just want to inform the other hitmen that the contract has been succeeded! We'll use the for-loop again.

pawn Code:
for(new i = 0; i < MAX_PLAYERS; i++)
            {
                    if(PlayerInfo[i][pFaction] == 3)
                    {
                    new message2[170];
                    format(message2, sizeof(message2), "HQ: Hitman %s has succesfully assasinated %s for $%d", GetName(killerid), GetName(playerid), PlayerInfo[playerid][pContract]);
                    SendClientMessage(killerid, -1, message2);
                    }
            }
(Once again, GetName is probably NOT defined. Please use the search function!)

So here we loop again through all our players, and we send the message to all the hitmen that are online! The last thing we'll need to do is set the players contract again to 0.

pawn Code:
PlayerInfo[playerid][pContract] = 0;
Simple, isn't it? This will set the contract back to 0.

And we're done. This is how your command should look like:

pawn Code:
CMD:contract(playerid, params[])
{
    new pID, bounty, message1[170], message2[170];
    if(sscanf(params,"ud", pID, bounty)) return SendClientMessage(playerid, COLOR_WHITE, "USAGE: /contract [playerid][amount]");
if(bounty <= 0) return SendClientMessage(playerid, -1, "You can't put negative values on a players head!");
    {
        GivePlayerMoney(playerid, -bounty);
        format(message1,sizeof(message1), "You've put a contract on the players head for $%d.", bounty);
        SendClientMessage(playerid, -1, message1);
        PlayerInfo[pID][pContract] = bounty;

        for(new i = 0; i < MAX_PLAYERS; i++)
        {
            if(PlayerInfo[i][pFaction] == 3)
            {
                format(message2,sizeof(message2), "HQ: A player has put a contract on %s for $%d.", GetName(pID), bounty);
                SendClientMessage(i, -1, message2);
            }
        }
    }
    return 1;
}
And this under your OnPlayerDeath:

pawn Code:
public OnPlayerDeath(playerid, killerid, reason)
{
    if(PlayerInfo[killerid][pFaction] == 3)
    {
        if(PlayerInfo[playerid][pContract] > 0)
        {
            new message1[170];
            GivePlayerMoney(playerid, -PlayerInfo[playerid][pContract]);
            format(message1, sizeof(message1), "You've been critically injured by a Hitman and lost $%d.", PlayerInfo[playerid][pContract]);
            SendClientMessage(playerid, COLOR_YELLOW, message1);
            GivePlayerMoney(killerid, PlayerInfo[playerid][pContract]);
            for(new i = 0; i < MAX_PLAYERS; i++)
            {
                    if(PlayerInfo[i][pFaction] == 3)
                    {
                    new message2[170];
                    format(message2, sizeof(message2), "HQ: Hitman %s has succesfully assasinated %s for $%d", GetName(killerid), GetName(playerid), PlayerInfo[playerid][pContract]);
                    SendClientMessage(killerid, COLOR_YELLOW, message2);
                    }
            }
            PlayerInfo[playerid][pContract] = 0;
        }
    }
    return 1;
}
That's all. I know this is a long tutorial, but I hope I helped you! Feel free to PM me with any questions!
Reply
#2

Nicely done my friend,well explained,good job.
Reply
#3

Quote:
Originally Posted by DaRk_RaiN
View Post
Nicely done my friend,well explained,good job.
Thanks! I appreciate it
Reply
#4

Good job.
Reply
#5

Nice tutorial,

Add to your loops:
PHP Code:
if(IsPlayerConnected(i
Reply
#6

pawn Code:
enum pInfo
{
   pContract // This will store the price of the contract on somebody's head. If it's 0 then the system will just ignore it
   pFaction
}
You forgot to add this in it:
pawn Code:
new PlayerInfo[MAX_PLAYERS][pInfo];
Anyways, this is hard work and you get a well earned rep and thanks!
Reply
#7

Defenitly not good for RP, unless its 'light' RP.
Reply
#8

And honestly, you have mistakes in your script ... Let me give you an example:

Quote:
pawn Code:
CMD:contract(playerid, params[])
{
    new pID, bounty, message1[170], message2[170];
    if(sscanf(params,"ud", pID, bounty)) return SendClientMessage(playerid, COLOR_WHITE, "USAGE: /contract [playerid][amount]");
    {
        GivePlayerMoney(playerid, -bounty);
        format(message1,sizeof(message1), "You've put a contract on the players head for $%d.", bounty);
        SendClientMessage(playerid, -1, message1);
        PlayerInfo[pID][pContract] = bounty;

        for(new i = 0; i < MAX_PLAYERS; i++)
        {
            if(PlayerInfo[i][pFaction] == 3)
            {
                format(message2,sizeof(message2), "HQ: A player has put a contract on %s for $%d.", bounty);
                SendClientMessage(i, -1, message2);
            }
        }
    }
    return 1;
}
The mistake is at the format line:
pawn Code:
format(message2,sizeof(message2), "HQ: A player has put a contract on %s for $%d.", bounty);
Figure it out ...

How about if I do /contract X -2324324 ... That would give me 2324324$ in my hand. You need to check for negative values...

And that's just one, I noticed at a first glance over your tutorial. Overall, it's well explained but you need to be more careful.
Reply
#9

Quote:
Originally Posted by Rajat_Pawar
View Post
pawn Code:
enum pInfo
{
   pContract // This will store the price of the contract on somebody's head. If it's 0 then the system will just ignore it
   pFaction
}
You forgot to add this in it:
pawn Code:
new PlayerInfo[MAX_PLAYERS][pInfo];
Anyways, this is hard work and you get a well earned rep and thanks!
Thanks, I'll add it!

Quote:
Originally Posted by gtakillerIV
View Post
Good job.
Thanks!

Quote:
Originally Posted by antonio112
View Post
And honestly, you have mistakes in your script ... Let me give you an example:



The mistake is at the format line:
pawn Code:
format(message2,sizeof(message2), "HQ: A player has put a contract on %s for $%d.", bounty);
Figure it out ...

How about if I do /contract X -2324324 ... That would give me 2324324$ in my hand. You need to check for negative values...

And that's just one, I noticed at a first glance over your tutorial. Overall, it's well explained but you need to be more careful.
I see. I've taken out some things out of the OnPlayerDeath and the command to make it more simple, so it could be I forgot to erase some things. I'll update it right away. And thank you for noticing that you can use negative values. Didn't saw that one... thanks!
Reply
#10

Very nice tutorial, thank you!
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)