19.08.2012, 17:28
Hi, I would like to write some pieces of script so that players can get in a vehicle as passengers ONLY IF that vehicle has a driver. I guess that the very first part is creating a custom function that checks if a vehicle has a driver:
And then calling this custom function in OnPlayerEnterVehicle:
Ok, this was the easy part, now comes the hard part: imagine that a vehicle has a driver and a passenger, so everything is ok. But now, the driver gets out of the vehicle, or he disconnects from the server, so the passenger is left alone in the vehicle. I need a piece of script that detects this and ejects that passenger, and only two ways have come to my mind:
pawn Код:
forward IsVehicleDriven(vehicleid);
public IsVehicleDriven(vehicleid)
{
for(new i = 0; i <= MAX_PLAYERS; i++)
{
if(GetPlayerState(i) == PLAYER_STATE_DRIVER)
{
if(GetPlayerVehicleID(i) == vehicleid)
{
return i;
}
}
}
return -1;
}
pawn Код:
public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
if(ispassenger == 1)
{
if(IsVehicleDriven(vehicleid) == -1)
{
SendClientMessage(playerid, 0xFFFFFFFF, "You can't enter that vehicle as passenger because it has no driver");
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
SetPlayerPos( playerid, x, y, (z + 1) );
}
}
return 1;
}
- Using OnPlayerUpdate:
The problem I see with this method is that IsVehicleDriven loops through all players, so if the server has to repeat that loop over and over again for every single update that players send while being passengers, the cpu might get overloaded. So here comes my other method:pawn Код:public OnPlayerUpdate(playerid)
{
if(GetPlayerState(playerid) == PLAYER_STATE_PASSENGER)
{
new vehicleid;
vehicleid = GetPlayerVehicleID(playerid);
if(IsVehicleDriven(vehicleid) == -1)
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
SetPlayerPos( playerid, x, y, (z + 1) );
SendClientMessage(playerid, 0xFFFFFFFF, "You were ejected from the vehicle because it doesn't have a driver any more");
}
}
return 1;
} - Creating a second custom function and calling it both in OnPlayerDisconnect and in OnPlayerStateChange:
This other method has the advantage of not making OnPlayerUpdate too heavy, because the custom function is called only when a player disconnects and when he stops being a driver. However, the function SearchForAlonePassengers first loops through all players, and in some cases it calls IsVehicleDriven, which also loops through all players, so it would be like having a loop inside another, and I don't know if also that might overload the server.pawn Код:forward SearchForAlonePassengers();
public SearchForAlonePassengers()
{
new vehicleid, Float:x, Float:y, Float:z;
for(new i = 0; i <= MAX_PLAYERS; i++)
{
if(GetPlayerState(i) == PLAYER_STATE_PASSENGER)
{
vehicleid = GetPlayerVehicleID(i);
if(IsVehicleDriven(vehicleid) == -1)
{
GetPlayerPos(i, x, y, z);
SetPlayerPos( i, x, y, (z + 1) );
SendClientMessage(i, 0xFFFFFFFF, "You were ejected from the vehicle because it doesn't have a driver any more");
}
}
}
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
SearchForAlonePassengers();
return 1;
}
public OnPlayerStateChange(playerid, newstate, oldstate)
{
if(oldstate == PLAYER_STATE_DRIVER)
{
SearchForAlonePassengers();
}
return 1;
}


