Jump to content

  •  





Bounty Hunting PvP Script

Posted by GmOcean, in 2. Intermediate Scripts 26 November 2014 · 1205 views

Bounty Hunting PvP Script ( 2 Parts )
An intermediate level PvP script. This script is intended to help improve your scripting abilities, while also making you feel more comfortable about PvP scripts.

Part 1
Alright, before we begin I'm assuming you already completed the Basic PvP Script. If not, you will need to do so to follow along.

Otherwise let's continue, by first creating a floating npc, followed by the OnInit: label:
-    script    bounty_script    -1,{
OnInit:

Now that we got rid of the easy part, let's add some configurations to our script.
We'll start by setting up the following 2 variables:
    .bounty = 10000;
    .wanted_increments = 1000000;
    end;

Those will be used later when we determine what happens when a player is killed in PvP combat. So to continue on, we are going to be adding the OnPCKillEvent: label followed by a check to see if the person who died, is also the killer and if so, end the script.
To do that we'll need to use getcharid(3), as this will return the account id:
OnPCKillEvent:
    if (killedrid == getcharid(3)) {
        end;
    }

Now, this is a bit different than normal, because right now the script is attached to the killer. But we want to make changes to the killed person first, so let's attach the script to that person:
attachrid(killedrid);

Alright, now we need to set 2 variables. The first being .@zeny to the player's current bounty regardless of whether or not he had one.
To do this, we need to use the command: getcharid(0); as the element of an array.
It should look like this:
    .@zeny = .bounty[getcharid(0)];

Now we just need to set the player's bounty to 0 since he was killed. So let's do that:
    .bounty[getcharid(0)] = 0;

Now the last thing we are going to do with this player is save their name into a scope-string variable for later use, let's call it .@name$, and remember the command to get their name is: strcharinfo(<type>);
    .@name$ = strcharinfo(0);

Now that we are done making changes to the killed player, let's attach the script back to the killer:
attachrid(killerrid);

Here we are going to do 2 things. The first is, we are going to increase the killer's Zeny by the variable .@zeny which we got from the killed player. The second is, we are going to increase the killer's bounty by the variable .bounty.
So let's do that:
    Zeny += .@zeny;
    .bounty[getcharid(0)] += .bounty;

See, that wasn't too hard. Finally, we are going to announce that the player has killed the other player, as well as show what his bounty level is. This will be determined by dividing his bounty by the .wanted_increments variable we made earlier in the script. Also, we will be using a (? :) condition to properly announce whether or not the killer is male or female. Along with what the player's bounty is so others can hunt them down. And lastly, announce it to everyone, in blue.
Let's do it:
    announce "["+ strcharinfo(0) +"] has killed ["+ .@name$ +"]. "+ (Sex?"He":"She") +" has a bounty of: "+ .bounty[getcharid(0)] +"") +" zeny! [ WANTED LEVEL "+ ( .bounty[getcharid(0)] / .wanted_increments ) +" ]",bc_blue|bc_all;

Alright. That's it, when you're all done it should look something like this:
-	script	bounty_script	-1,{
OnInit:
    .bounty = 10000;
    .wanted_increments = 100000;
    end;

OnPCKillEvent:
    if (killedrid == getcharid(3)) {
	end;
    }
    attachrid(killedrid);
	.@zeny = .bounty[getcharid(0)];
	.bounty[getcharid(0)] = 0;
	.@name$ = strcharinfo(0);
		
    attachrid(killerrid);
	Zeny += .@zeny;
	.bounty[getcharid(0)] += .bounty;
	announce "["+ strcharinfo(0) +"] has killed ["+ .@name$ +"]. "+ (Sex?"He":"She") +" has a bounty of: "+ .bounty[getcharid(0)] +" zeny! [ WANTED LEVEL "+ ( .bounty[getcharid(0)] / .wanted_increments ) +" ]",bc_blue|bc_all;
    end;
}
And that's it for now. We'll make some more improvements, as well as add more features in part 2.

Part 2
Okay, let's just jump straight into this one.

Let's open up the script from last time:
-	script	bounty_script	-1,{
OnInit:
    .bounty = 10000;
    .wanted_increments = 100000;
    end;

OnPCKillEvent:
    if (killedrid == getcharid(3)) {
	end;
    }
    attachrid(killedrid);
	.@zeny = .bounty[getcharid(0)];
	.bounty[getcharid(0)] = 0;
	.@name$ = strcharinfo(0);
		
    attachrid(killerrid);
	Zeny += .@zeny;
	.bounty[getcharid(0)] += .bounty;
	announce "["+ strcharinfo(0) +"] has killed ["+ .@name$ +"]. "+ (Sex?"He":"She") +" has a bounty of: "+ .bounty[getcharid(0)] +" zeny! [ WANTED LEVEL "+ ( .bounty[getcharid(0)] / .wanted_increments ) +" ]",bc_blue|bc_all;
    end;
}

Now, the additions we're going to put in here are peretty simple. We are going to add 3 things in:
1) A check so that this script only works on certain maps.
2) Whether or not to warp the player to their SavePoint upon death.
3) Whether or not player's lose zeny when they die.
So let's add those variables into OnInit:
.mapname$ = "pvp_y_2-1";
.warp_death = 1;
.zeny_loss = .bounty;

So above, we chose our map that it is enabled on, also said yes players get warped out upon dying and the .zeny_loss is set to the bounty players gain per kill. Seems easy enough, now the next step is to add a check to see if the killer is on the same map as what we specified.
So let's add the check directly under OnPCKillEvent: using strcharinfo(3):
if (strcharinfo(3) != .mapname$) {
    end;
}

Took care of that. And now it won't cause any problems down the line.
Alright, we're almost done. Just need to add a few more checks regarding the zeny_loss variable. Let's knock those out. We are going to check if .zeny_loss is enabled.
So let's do that:
if (.zeny_loss) {

Okay, now we need to add another check inside of that one. This time, we are going to check if the player has Zeny less-than how much we are going to take away. If they do, we are going to take away the remaining zeny from them. If they happen to have more, we'll take away just what we need to.
So let's do that:
    if (Zeny < .zeny_loss) {
        Zeny -= Zeny;
    } else {
        Zeny -= .zeny_loss;
    }
}

Alright, last thing we need to do is add the check to see if .warp_death is enabled, and if so, warp the dead player out. So we'll add that right before we end the script.
To do that, we need to use this command: warp "<map name>",<x>,<y>;
So let's add it in:
if (warp_death) {
    warp "SavePoint",0,0;
}

Now we are finished. Your script should look something like this:
-	script	bounty_script	-1,{
OnInit:
    .bounty = 10000;
    .wanted_increments = 100000;
    .mapname$ = "pvp_y_2-1";
    .warp_death = 1;
    .zeny_loss = .bounty;
    end;

OnPCKillEvent:
    if (strcharinfo(3) != .mapname$ && .mapname$ != "") {
        end;
    }
    if (killedrid == getcharid(3)) {
	end;
    }
    attachrid(killedrid);
	.@zeny = getd(".bounty"+ getcharid(0) +"");
	setd ".bounty"+ getcharid(0) +"", 0;
	.@name$ = strcharinfo(0);
	if (.zeny_loss) {
            if (Zeny < .zeny_loss) {
                Zeny -= Zeny;
            } else {
                Zeny -= .zeny_loss;
            }
        }
    attachrid(killerrid);
	Zeny += .@zeny;
	setd ".bounty"+ getcharid(0) +"", getd(".bounty"+ getcharid(0) +"") + .bounty;
	announce "["+ strcharinfo(0) +"] has killed ["+ .@name$ +"]. "+ (Sex?"He":"She") +" has a bounty of: "+ getd(".bounty"+ getcharid(0) +"") +" zeny! [ WANTED LEVEL "+ ( getd(".bounty"+ getcharid(0) +"") / .wanted_increments ) +" ]",bc_blue|bc_all;
    if (.warp_death) {
        warp "SavePoint",0,0;
    }    
    end;
}

And that's it. We just finished making a Bounty Hunting PvP script, that doesn't involve having to do anything but kill. This should inspire people to want to pvp now.