09.09.2013, 07:18
Hello I have been making a race system for my GM, and used this tutorial for it: https://sampforum.blast.hk/showthread.php?tid=401252
However I noticed it did not include a race position thing, and we all know that every single race on a decent server has a race position thing, no?
So I searched for tutorials and looked in other filterscripts (such as yRace and rRace).
But I couldn't find a way of doing it, so I tried to do it myself and succeeded.
So because there's no (good) tutorial of doing this I'm going to show you how I did it.
IMPORTANT: I use this function with the race system I made from the tutorial (see top), if your race system operates differently, chances are that this isn't going to work...
So how is this tutorial going to be?
Well I just made the following function:
which returns the player's position
And I'll just show you the stock code, and then explain every line.
| Step One |
Ok so step one, as always is adding a new array.
I'm only going to show you the array to store the position, not all other race arrays in the racing system...
Add this to your PlayerInfo enum (I guess you have one?)
This simply stores the player's position.
Now we for safety reasons I like to set this array to 0 in several callbacks, I don't think it's really necesairy, but I do it to make sure there's no bugs...
So add this:
under the following Callbacks:
| Step Two |
Ok now let's go to the function itself.
here's the code
Let's explain line by line:
This is a new 'index', we'll use it to store the amount of players that are infront of the player we track the position.
-> the player's position will eventually be index +1 , since it's all the players in front of him +1
But how do we count the amount of players in front of the tracked one?
here's how:
This just loops through all the players that could be online
-> i equals all the players that could be online
-> now i stands for everyone who is racing the/a race, because we filtered everyone who isn't in the race.
We just filtered ourself, since we cannot really see if 'you' are in front of 'you'...
Now I'm going to give some explanation:
This is the checkpoint the player has last entered, the progress of the player in the race. If a player has already done 2 checkpoints, this will be2.
I'm sure your racing system has something similar to track the player's progress, no?
This is the checkpoint all the other racers have last entered, the same story as the previous variable, but this is for every other racer.
So this:
Means if the tracked player has done less checkpoints than all the other racers.
Let's move on:
So, what's this?
Well we constantly do our first loop, and now we end up here, so everything that happens in here has passed all the "if's" hence, index will go ++ for everyone who is in front of the player, right?
Now whe have only checked for all the players that have done more checkpoints than the tracked player.
But what about all the players that have done the same amount of checkpoints as i, but is in front of me?
you can see it like this:
. represents a racer
0 represents me
| represents a checkpoint
So now index has only gone up for the first three racers, since they have done more checkpoints than me, but what about the 3 other racers that have done the same amount of checkpoints yet as me?
So this code:
This checks if all the other races have done the same amount of checkpoints as I -> they are in the same 'section'.
So now 'j' represents that.
This is just to make things shorter, PlayerCheckPoint is the last checkpoint the player has entered, ElseCheckPoint is the amount of checkpoints all the other racers (who are in the same section as me) have done.
Let's filter 'j' again, so now we calculate the distance the player is away from their next checkpoint ([PlayerCheckPoint] +1), and the distance in between every other racer and their next checkpoint.
So if the racer's distance is bigger than the others we continue:
So index goes up for every racer that has done the same amount of checkpoints than me, and is closer to the next one than me.
So there we go.
Last bits:
Now, index represents the amount of players in front of you
-> your position = index +1
I don't think you really need to make the PInfo[playerid][Pos] variable, you can also just return index +1, but I like to make a P variable.
So we returned the position, now when you use the function, it will output the player's position.
| Step Three |
Here's an example script:
This code works fine for me, but I have only tested it with 2 players yet, not with 3 or more...
So hopefully it will work aswell.
Hope it helped you.
Bye.
However I noticed it did not include a race position thing, and we all know that every single race on a decent server has a race position thing, no?
So I searched for tutorials and looked in other filterscripts (such as yRace and rRace).
But I couldn't find a way of doing it, so I tried to do it myself and succeeded.
So because there's no (good) tutorial of doing this I'm going to show you how I did it.
IMPORTANT: I use this function with the race system I made from the tutorial (see top), if your race system operates differently, chances are that this isn't going to work...
So how is this tutorial going to be?
Well I just made the following function:
pawn Код:
GetPlayerPosition(playerid, raceid)
And I'll just show you the stock code, and then explain every line.
| Step One |
Ok so step one, as always is adding a new array.
I'm only going to show you the array to store the position, not all other race arrays in the racing system...
Add this to your PlayerInfo enum (I guess you have one?)
pawn Код:
enum PlayerInfo
{
//blabla
Pos,
}
new PInfo[MAX_PLAYERS][PlayerInfo];
Now we for safety reasons I like to set this array to 0 in several callbacks, I don't think it's really necesairy, but I do it to make sure there's no bugs...
So add this:
pawn Код:
PInfo[playerid][PlayerInfo] = 0;
pawn Код:
public OnPlayerConnect(playerid)
stock LeaveRace(playerid, raceid) //Or whathever you use in your script when a player leaves a race
Ok now let's go to the function itself.
here's the code
pawn Код:
stock GetPlayerPosition(playerid, raceid)
{
new index = 0;
for(new j = 0; j < MAX_PLAYERS; j++)
{
if(PInfo[j][Racing] == raceid)
{
if(j != playerid)
{
if(PInfo[playerid][RaceCheckpoint] < PInfo[j][RaceCheckpoint])
{
index++; //for everyone who is in front of the player index goes ++
}
if(PInfo[playerid][RaceCheckpoint] == PInfo[j][RaceCheckpoint]) //who is in the same section as the player
{
new PlayerCheckPoint = PInfo[playerid][RaceCheckpoint];
new ElseCheckPoint = PInfo[j][RaceCheckpoint];
if(GetPlayerDistanceFromPoint(playerid, RaceInfo[raceid][checkpointx][PlayerCheckPoint]+1,RaceInfo[raceid][checkpointy][PlayerCheckPoint]+1, RaceInfo[raceid][checkpointz][PlayerCheckPoint]+1) > GetPlayerDistanceFromPoint(j, RaceInfo[raceid][checkpointx][ElseCheckPoint]+1, RaceInfo[raceid][checkpointy][ElseCheckPoint]+1, RaceInfo[raceid][checkpointz][ElseCheckPoint]+1))
{
index++;
}
}
}
}
}
PInfo[playerid][Pos] = index +1;
return PInfo[playerid][Pos];
}
pawn Код:
new index = 0;
-> the player's position will eventually be index +1 , since it's all the players in front of him +1
But how do we count the amount of players in front of the tracked one?
here's how:
pawn Код:
for(new j = 0; j < MAX_PLAYERS; j++) //everyone
{
-> i equals all the players that could be online
pawn Код:
if(PInfo[j][Racing] == raceid) //Use your own variable to define wether a player is racing or not
{
pawn Код:
if(j != playerid) // who is not the checked player
{
pawn Код:
if(PInfo[playerid][RaceCheckpoint] < PInfo[j][RaceCheckpoint]) //use your own variable to get the player's checkpoint
{
pawn Код:
PInfo[playerid][RaceCheckpoint]
I'm sure your racing system has something similar to track the player's progress, no?
pawn Код:
PInfo[j][RaceCheckpoint]
So this:
pawn Код:
if(PInfo[playerid][RaceCheckpoint] < PInfo[j][RaceCheckpoint])
Let's move on:
pawn Код:
index++; //for everyone who is in front of the player index goes ++
Well we constantly do our first loop, and now we end up here, so everything that happens in here has passed all the "if's" hence, index will go ++ for everyone who is in front of the player, right?
Now whe have only checked for all the players that have done more checkpoints than the tracked player.
But what about all the players that have done the same amount of checkpoints as i, but is in front of me?
you can see it like this:
Код:
. | . 0 .. | ... |
. represents a racer
0 represents me
| represents a checkpoint
So now index has only gone up for the first three racers, since they have done more checkpoints than me, but what about the 3 other racers that have done the same amount of checkpoints yet as me?
So this code:
pawn Код:
if(PInfo[playerid][RaceCheckpoint] == PInfo[j][RaceCheckpoint]) //who is in the same section as the player
{
So now 'j' represents that.
pawn Код:
new PlayerCheckPoint = PInfo[playerid][RaceCheckpoint];
new ElseCheckPoint = PInfo[j][RaceCheckpoint];
pawn Код:
if(GetPlayerDistanceFromPoint(playerid, RaceInfo[raceid][checkpointx][PlayerCheckPoint]+1,RaceInfo[raceid][checkpointy][PlayerCheckPoint]+1, RaceInfo[raceid][checkpointz][PlayerCheckPoint]+1) > GetPlayerDistanceFromPoint(j, RaceInfo[raceid][checkpointx][ElseCheckPoint]+1, RaceInfo[raceid][checkpointy][ElseCheckPoint]+1, RaceInfo[raceid][checkpointz][ElseCheckPoint]+1))
{
So if the racer's distance is bigger than the others we continue:
pawn Код:
index++;
So there we go.
Last bits:
pawn Код:
}
}
}
}
}
PInfo[playerid][Pos] = index +1;
return PInfo[playerid][Pos];
}
-> your position = index +1
I don't think you really need to make the PInfo[playerid][Pos] variable, you can also just return index +1, but I like to make a P variable.
So we returned the position, now when you use the function, it will output the player's position.
| Step Three |
Here's an example script:
pawn Код:
public RaceTimeS(raceid) //Called every second when a race has started
{
for(new i; i<MAX_PLAYERS; i++)
{
if( !IsPlayerConnected( i ) ) continue;
printf( "if(PInfo[i][Racing] == raceid)::if(%d == %d)", PInfo[i][Racing], raceid );
if(PInfo[i][Racing] == raceid)
{
print( "PInfo[i][racetimeS] ++;" );
RaceInfo[raceid][racetimeS] ++;
printf( "PInfo[i][racetimeS] = %d", RaceInfo[raceid][racetimeS] );
print( "TD: Time Taken will be called.." );
new string[56];
format (string, sizeof string, "%s Time Taken" , ReturnSToM(RaceInfo[raceid][racetimeS]));
TextDrawSetString(TD_TIME[i], string);
print( "TD: Time Taken has been called.." );
print( "TD: Position will be called.." );
new Position[26];
format(Position, sizeof Position, "%d/%d Position",GetPlayerPosition(i, raceid), RaceInfo[raceid][originalcount]);
TextDrawSetString(TD_POS[i], Position);
print( "TD: Position has been called.." );
}
}
return 1;
}
So hopefully it will work aswell.
Hope it helped you.
Bye.