1 Vs. 1 Zones [What We Did & Why]
« on: March 04, 2008, 04:08:47 PM »
--------------------------------------------------------------------------------
I helped somebody out earlier, and outdid myself and made a giant tutorial for this. So here it is, from the original post. Also, this is meant for wL-based servers. I'll hurt myself later for doing that. But it can be very, very easily converted into a "RS2DV by varek" tutorial.
I'm pretty sure that boolean attack() or attackPlayer() or something similar handles all PKing features. Just find the spot where a player starts to attack another player, and then create a new variable for both players. So in the client class, declare a new lets say String object which will tell us if the player is already in a fight (and holds the other players name for purposes uncovered later), and intialize it.
public String inBattle;
Now that we can actually use something, go back to that attacking method and find the spot where a player attacks another. This time we'll do something similar to this...
When about to attack, simply:
server.playerHandler.players[playerID].inBattle = server.playerHandler.players[otherPlayerID].playerName;
server.playerHandler.players[otherPlayerID] = server.playerHandler.players[playerID].playerName;
otherPlayerID will be different for most of you. Just use the integer they already setup in that bulk of a method (something like AttackingOn.playerID?)
Now everytime an attack is launched against a player, its inBattle variable has to be set. Now we have to do the opposite of what we just did, and we have to check if the player is already in a battle before he attacks. So...
if(!inBattle.equals(null)) sendMessage("You just left a battle. Please wait 10 seconds before switching targets.");
else if((!server.playerHandler.players[otherPlayerID].inBattle.equals(null)) || inBattle.equals(server.playerHandler.players[otherPlayerID].inBattle))
{
//Original attacking part here
}
else sendMessage("You cannot attack a player who is already in combat.");
This will check if the player is in battle. If not, the attack continues. If so, the player is told he is already in a battle and cannot be attacked through the sendMessage(String) method.
From here its actaully pretty easy. We'll have to at some point change the value of inBattle to null again, indicating the player is out of battle. How? Well lets think for a bit. The only way easier way I can think of right now is to compare the time of attack and the current time. Lets go back to the player attacking, or PKing method, I mentioned earlier.
Here, after we set the inBattle variable, we have to set the time of which that happened. So, first, lets create an Integer value that can be used throughout the class.
private int lastAttack;
Now we can use it with any method we want, because it is not a local variable. So, back to the player attacking method again, we can set that time after we set the value of inBattle. To do this, we can simply do:
lastAttack = new GregorianCalendar().get(Calendar.SECOND);
The value will range from 0-59 at all times. Now, we'll have to constantly check the seconds between the current time and attack time to see how long it has been. We'll go with the RuneScape default: 10 seconds.
Go to boolean process(), and lets work things out here. We have to get the current time every half-second (thats how fast process() is called), and compare it to the attack time. We only need the seconds for each because of how I roll.
int currentSecond = new GregorianCalendar().get(Calendar.SECOND);
if(currentSecond < lastAttack)
if(((60-lastAttack) + currentSecond) == 10) inBattle = null;
else
if((currentSecond - lastAttack) == 10) inBattle = null;
Looks weird, doesn't it? Well, the way I have it setup is so it only compares seconds. I'm pretty sure this works, but I haven't tested it. If the currentSecond was 5 and the lastAttack was 55, then if I did 5-55 I would get a negative number. So I had to work around that. If the currentSecond is less than lastAttack, it will get the differential between 60 and lastAttack, which would be 5 in this case, and then add it to the currentSecond, resulting in 10 seconds. That's exactly what we need.
Hope I helped. This is all you really need, too.
Ah, see, 15 new lines of code, compared to the dozens in other cruddy tutorials for 1vs1 zones.
Also, you might have to add a few if statements here and there to check for your current position (at the player attacking part) if you want only some parts 1vs1. Because right now, this makes your whole server 1 vs. 1. You'll also need to import the correct packages (hmm.. java.util.GregorianCalendar).