SA-MP Forums Archive
[Tutorial] A basic hitman system (/contract) - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+---- Forum: Tutorials (https://sampforum.blast.hk/forumdisplay.php?fid=70)
+---- Thread: [Tutorial] A basic hitman system (/contract) (/showthread.php?tid=566799)



A basic hitman system (/contract) - Sellize - 08.03.2015

What will I learn in this tutorial?
You will be shown how to make a fairly basic hitman system. This script will cover: placing hits on players (/contract) and executing contracts (hitmen)

I am going to assume you have atleast basic knowledge of pawn and will not explain the basic things.
Do you need a newbie tutorial? Take a look at this tutorial.


Required: zcmd, sscanf

Let's start by creating a new blank script, or if you want to incorporate this into your current script, that's possible too!

With the help of ZCMD I'll go ahead and create two commands: /contract and /hits

/contract [id] [amount] - Players will be able to use this command to place hits on other players

/hits - Hitmen can use this command to see all current hits

Code:
COMMAND:contract(playerid, params[])
{

  	return 1;
}

COMMAND:hits(playerid, params[])
{
  	
  	return 1;
}
Let's also make two new variables: hit and isHitman

hit - This variable will store the hit amount on the player
isHitman - This variable is to declare if a player is a hitman or not 0 = no, 1 = yes.

Code:
new hit[MAX_PLAYERS];
new isHitman[MAX_PLAYERS];
(Make sure to put this somewhere on top of you script, like under the defines)

Let's work on the /contract command.
We first need to see if the player actually used the parameters correctly. We use sscanf to check these for us.
Code:
COMMAND:contract(playerid, params[])
{
	new id, amount;
    if(sscanf(params, "ui", id, amount)) return SendClientMessage(playerid, -1, "{A3A1A0}Usage: /contract [id] [amount]");
  	return 1;
}
We will also return a syntax message if the player gets the params wrong.
Next up we need to check if the specified player is actually connected. We can use the IsPlayerConnected function for that. If the player is not connected we will return an error message.

Code:
COMMAND:contract(playerid, params[])
{
	new id, amount;
    if(sscanf(params, "ui", id, amount)) return SendClientMessage(playerid, -1, "{A3A1A0}Usage: /contract [id] [amount]");
    if(!IsPlayerConnected(id)) return SendClientMessage(playerid, -1, "{A3A1A0}That player is not connected.");
  	return 1;
}
We also don't want hitmen placing contracts so we check if the player is a hitman, if he is then we will return an error message.

Code:
if(isHitman[playerid] == 1) return SendClientMessage(playerid, -1, "{A3A1A0}Hitmen can not place contracts.");
Now that we know that the player is connected, we can go ahead and first check if he is not a hitman, because we don't want people putting hits on hitmen. If he is a hitman, we will need to return a discrete error message to prevent people from knowing who is a hitman.

Code:
if(isHitman[id] == 1) return SendClientMessage(playerid, -1, "{A3A1A0}That player already has the maximum hit on him.");
We will just tell them the player has the maximum hit on him.

Now we will check if the player already has the maximum hit, which will be $150k.

Code:
if(hit[id] == 150000 || hit[id] > 150000) return SendClientMessage(playerid, -1, "{A3A1A0}That player already has the maximum hit on him.");
Next up, we need to check if the amount of the hit is not lower than 50k or higher than 150k. This is again easily done.

Code:
if(amount < 50000 || amount > 150000) return SendClientMessage(playerid, -1, "{A3A1A0}Hits range from $50,000 - $150,000.");
Now we will check if the amount of the hit + the players current hit is not more than 150k. I hope you can understand this, since it's quite hard to explain.

Code:
if(hit[id] + amount > 150000) return SendClientMessage(playerid, -1, "{A3A1A0}That hit is too high for this player, please lower it.");
Finally, we are now ready to actually place the hit on the player.
Go ahead and add the amount to the current hit of the player.

Code:
hit[id] = hit[id] + amount;
Next we want to send a message to the player to let him know the hit has been placed.
We will first make two strings, one for the finished message and one to store the targets name in.
Then we can format the finished string and finally send it to the player using SendClientMessage

Code:
new result[128];
    new tname[MAX_PLAYER_NAME];
    GetPlayerName(id, tname, sizeof(tname));
    format(result, sizeof(result), "You have placed a hit of $%i on %s.", amount, tname);
    SendClientMessage(playerid, -1, result);
Now let's send a message to all hitmen to let them know a new hit is available!
We will use a for loop for this. It will loop through all online players and check if they are a hitman, if they are, then we will send them the message!

Make sure to use 'i' instead of 'playerid' here!

Code:
new string[128];
    format(string, sizeof(string), "HITMAN: A new hit is available. Name: %s | Amount: $%i", tname, hit[id]);
    for(new i = 0; i < MAX_PLAYERS; i++)
	{
	    if(IsPlayerConnected(i))
	    {
	        if(isHitman[i])
	        {
				SendClientMessage(i, -1, string);
	        }
	    }
	}
This should be your final /contract command:

PHP Code:
COMMAND:contract(playeridparams[])
{
    new 
idamount;
    if(
sscanf(params"ui"idamount)) return SendClientMessage(playerid, -1"{A3A1A0}Usage: /contract [id] [amount]");
    if(!
IsPlayerConnected(id)) return SendClientMessage(playerid, -1"{A3A1A0}That player is not connected.");
    if(
isHitman[playerid] == 1) return SendClientMessage(playerid, -1"{A3A1A0}Hitmen can not place contracts.");
    if(
isHitman[id] == 1) return SendClientMessage(playerid, -1"{A3A1A0}That player already has the maximum hit on him.");
    if(
hit[id] == 150000 || hit[id] > 150000) return SendClientMessage(playerid, -1"{A3A1A0}That player already has the maximum hit on him.");
    if(
amount 50000 || amount 150000) return SendClientMessage(playerid, -1"{A3A1A0}Hits range from $50,000 - $150,000.");
    if(
hit[id] + amount 150000) return SendClientMessage(playerid, -1"{A3A1A0}That hit is too high for this player, please lower it.");
    
hit[id] = hit[id] + amount;
    
    new 
result[128];
    new 
tname[MAX_PLAYER_NAME];
    
GetPlayerName(idtnamesizeof(tname));
    
format(resultsizeof(result), "You have placed a hit of $%i on %s."amounttname);
    
SendClientMessage(playerid, -1result);
    
    new 
string[128];
    
format(stringsizeof(string), "HITMAN: A new hit is available. Name: %s | Amount: $%i"tnamehit[id]);
    for(new 
0MAX_PLAYERSi++)
    {
        if(
IsPlayerConnected(i))
        {
            if(
isHitman[i])
            {
                
SendClientMessage(i, -1string);
            }
        }
    }
      return 
1;

Now let's make the rewarding system for the hitmen when they kill a player with a hit!
Go to the OnPlayerDeath callback.
First we check if the killerid of the death exists using:

Code:
if(killerid != INVALID_PLAYER_ID)
    {
And inside that we want to check if the killer is a hitman

Code:
if(isHitman[killerid] == 1)
        {
        
        }
Now, we know the killer is a hitman and we'll check if the player who died had a hit on him.
If the player that died had a hit on him, we will give the hitman the amount of money of the hit and we will send him a message.
We will also clear the hit on the player.

This should be your final OnPlayerDeath callback

PHP Code:
public OnPlayerDeath(playeridkilleridreason)
{
    if(
killerid != INVALID_PLAYER_ID)
    {
        if(
isHitman[killerid] == 1)
        {
            if(
hit[playerid] > 0)
            {
                
GivePlayerMoney(killeridhit[playerid]);
                
                new 
result[128];
                new 
tname[MAX_PLAYER_NAME];
                
GetPlayerName(playeridtnamesizeof(tname));
                
format(resultsizeof(result), "HITMAN: You killed %s and collected the hit of $%i!"tnamehit[playerid]);
                
SendClientMessage(playerid, -1result);
                
hit[playerid] = 0;
            }
        }
    }
    return 
1;

Now for the /hits command you will first need to check if the player is a hitman, because we only want hitmen to be able to see the hits.
Then we will again use a for loop to loop through all players and check if their hit is higher that 0, if it is, we will send a message with their information. Again using format and strings.

This should be your final /hits command:

PHP Code:
COMMAND:hits(playeridparams[])
{
      if(
isHitman[playerid] == 1)
      {
          
SendClientMessage(playerid, -1"--- Current available contracts ---");
          
          new 
string[128];
          new 
tname[MAX_PLAYER_NAME];
          for(new 
0MAX_PLAYERSi++)
        {
            if(
IsPlayerConnected(i))
            {
                if(
hit[i] > 0)
                {
                    
format(stringsizeof(string), "Name: %s | Amount: %i"tnamehit[i]);
                    
SendClientMessage(playerid, -1string);
                }
            }
        }
      }
      return 
1;

Done! You now have a functional hitman system
There are things which I could not show in this tutorial, these things are your responsibility however.
Think about: saving hits, making people hitman etc.
This shouldn't be too hard to do!

You can download the .PWN file from the attachment or view the script on the pastebin link.


Re: A basic hitman system (/contract) - biker122 - 08.03.2015

"Did you know?" - You have to reset the player's hit and ishitman value to 0, once they quit.
Otherwise, an unknown player with that playerid will have an hit on him..


Re: A basic hitman system (/contract) - Sellize - 08.03.2015

Quote:
Originally Posted by biker122
View Post
"Did you know?" - You have to reset the player's hit and ishitman value to 0, once they quit.
Otherwise, an unknown player with that playerid will have an hit on him..
I guess so. But I leave that up to the player since I expect them to incorporate this into an existing script


Re: A basic hitman system (/contract) - LOCS - 08.03.2015

Nice one


Re: A basic hitman system (/contract) - sas10 - 08.03.2015

Nice But u not rememper this
/CancelHit
^_^ Made it dude


Re: A basic hitman system (/contract) - finelaq - 08.03.2015

Nice tutorial.

pawn Code:
format(result, sizeof(result), "HITMAN: You killed %s and collected the hit of $%i!", tname, hit[playerid]);    
SendClientMessage(killerid, -1, result);
This i guess should be killerid?


Re: A basic hitman system (/contract) - CalvinC - 09.03.2015

Shouldn't the IsPlayerConnected in your contract command be "id", not "playerid"?
pawn Code:
if(!IsPlayerConnected(playerid)) return SendClientMessage(playerid, -1, "{A3A1A0}That player is not connected.");



Re: A basic hitman system (/contract) - Sellize - 09.03.2015

Quote:
Originally Posted by finelaq
View Post
Nice tutorial.

pawn Code:
format(result, sizeof(result), "HITMAN: You killed %s and collected the hit of $%i!", tname, hit[playerid]);    
SendClientMessage(killerid, -1, result);
This i guess should be killerid?
Yes because we want to send that message to the killer, the hitman.

Quote:
Originally Posted by CalvinC
View Post
Shouldn't the IsPlayerConnected in your contract command be "id", not "playerid"?
pawn Code:
if(!IsPlayerConnected(playerid)) return SendClientMessage(playerid, -1, "{A3A1A0}That player is not connected.");
Correct, fixed, thanks!


Re: A basic hitman system (/contract) - finelaq - 10.03.2015

Quote:
Originally Posted by Sellize
View Post
Yes because we want to send that message to the killer, the hitman.
Fix it then


Re: A basic hitman system (/contract) - saffierr - 27.09.2015

Nice tutorial!