// This include file holds all functions for doing convoys
forward Quadrilha_Timer(Quadrilha);
// This function is called only once and is used to setup the textdraws and default data for Quadrilhas
Quadrilhas_Init()
{
	for (new i; i < MAX_QUADRILHAS; i++)
	{
		AQuadrilhas[i][QuadrilhaTextLeader] = TextDrawCreate(320.0, 1.0, " "); // Create the textdraw for the leader
		TextDrawSetShadow(AQuadrilhas[i][QuadrilhaTextLeader], 1); // Reduce the shadow to 1
		TextDrawAlignment(AQuadrilhas[i][QuadrilhaTextLeader], 2); // Align the Quadrilha-infobar to the center for the leader
		AQuadrilhas[i][QuadrilhaTextMember] = TextDrawCreate(320.0, 1.0, " "); // Create the textdraw for the members
		TextDrawSetShadow(AQuadrilhas[i][QuadrilhaTextLeader], 1); // Reduce the shadow to 1
		TextDrawAlignment(AQuadrilhas[i][QuadrilhaTextMember], 2); // Align the Quadrilha-infobar to the center for the members
		TextDrawBackgroundColor(AQuadrilhas[i][QuadrilhaTextMember], 255);
		TextDrawFont(AQuadrilhas[i][QuadrilhaTextMember], 1);
		TextDrawLetterSize(AQuadrilhas[i][QuadrilhaTextMember], 0.390000, 1.300000);
		TextDrawSetOutline(AQuadrilhas[i][QuadrilhaTextMember], 1);
		TextDrawSetProportional(AQuadrilhas[i][QuadrilhaTextMember], 1);
		TextDrawBackgroundColor(AQuadrilhas[i][QuadrilhaTextLeader], 255);
		TextDrawFont(AQuadrilhas[i][QuadrilhaTextLeader], 1);
		TextDrawLetterSize(AQuadrilhas[i][QuadrilhaTextLeader], 0.390000, 1.300000);
		TextDrawSetOutline(AQuadrilhas[i][QuadrilhaTextLeader], 1);
		TextDrawSetProportional(AQuadrilhas[i][QuadrilhaTextLeader], 1);
	}
}
// This function is used when a player selected an empty Quadrilha-slot (the player will start the Quadrilha and become the leader)
Quadrilha_Create(playerid, Quadrilha)
{
	// Setup local variables
	new Name[24], Msg[128];
	// Get the name of the player
	GetPlayerName(playerid, Name, sizeof(Name));
	// Check if the player is allowed to create a Quadrilha (he must be a trucker without a job and not part of a Quadrilha yet)
	if (Quadrilha_PlayerAllowed(playerid))
	{
		// Set Status1 of the Quadrilha to "open"
		AQuadrilhas[Quadrilha][Status1] = QUADRILHA_OPEN;
		// Set the player as leader of the Quadrilha
		AQuadrilhas[Quadrilha][Memberss][0] = playerid;
		// Set the player as a member of a Quadrilha
		APlayerData[playerid][InQuadrilha] = true;
		APlayerData[playerid][QuadrilhaID] = Quadrilha;
		// Set all other member-indices to "-1" (no player yet)
		for (new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
		    AQuadrilhas[Quadrilha][Memberss][i] = -1;
		// Start the Quadrilha-timer (this timer updates and checks everything for the whole convoy), it runs every second
		AQuadrilhas[Quadrilha][QuadrilhaTimer] = SetTimerEx("Quadrilha_Timer", 1000, true, "i", Quadrilha);
		// Let all players know that this player wants to start a convoy
		format(Msg, 128, TXT_PlayerStartsQuadrilha, Name);
		SendClientMessageToAll(0xFFFFFFFF, Msg);
	}
}
// This function is used to let another player join a convoy
Quadrilha_Join(playerid, Quadrilha)
{
	// Setup local variables
	new Name[24], Msg[128];
	// Get the name of the player
	GetPlayerName(playerid, Name, sizeof(Name));
	// Check if the player is allowed to join the convoy (he must be a trucker without a job and not part of a convoy yet)
	if (Quadrilha_PlayerAllowed(playerid))
	{
	    // Check if the convoy isn't full already
		if (Quadrilha_CountMembers(Quadrilha) < QUADRILHA_MAX_MEMBERS)
		{
			// Inform all the members of the convoy that this player joined the convoy
			format(Msg, 128, TXT_PlayerJoinedQuadrilha, Name);
			Quadrilha_SendMessage(Quadrilha, Msg);
			// Inform the player that he joined the convoy
			SendClientMessage(playerid, 0xFFFFFFFF, TXT_YouJoinedQuadrilha);
			// Set the player as member of the convoy (find a free spot for this player)
			for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
			{
			    if (AQuadrilhas[Quadrilha][Memberss][i] == -1) // Check if this member-spot is empty
				{
					AQuadrilhas[Quadrilha][Memberss][i] = playerid; // Put the player in this member-spot
					break; // Stop the for-loop
				}
			}
			// Set the player as a member of a convoy
			APlayerData[playerid][InQuadrilha] = true;
			APlayerData[playerid][QuadrilhaID] = Quadrilha;
			// Set the QuadrilhaStatus1 as "Full" if all member-spots are occupied
			if (Quadrilha_CountMembers(Quadrilha) == QUADRILHA_MAX_MEMBERS)
			    AQuadrilhas[Quadrilha][Status1] = QUADRILHA_FULL;
			// Also update the player's missiontext to inform the player that he must wait for the leader to start a job
			TextDrawSetString(APlayerData[playerid][MissionText], TXT_WaitingLeaderJob);
		}
		else
		    SendClientMessage(playerid, 0xFFFFFFFF, TXT_QuadrilhaFull);
	}
}
// This function is used to let a player leave a convoy (when he disconnects, finishes the convoy, when he dies, ...)
Quadrilha_Leave(playerid)
{
	// Setup local variables
	new Quadrilha, NumMemberss, MemberID;
	// First theck if the player is part of a convoy
	if (APlayerData[playerid][InQuadrilha] == false)
	    return 1; // Exit the function if the player isn't part of a convoy
	// Get the convoy-id from the player
	Quadrilha = APlayerData[playerid][QuadrilhaID];
	// Get the number of members in the convoy
	NumMemberss = Quadrilha_CountMembers(Quadrilha);
	// If there is only 1 member in the convoy (convoy will have no members if this one leaves), cancel the convoy
	if (NumMemberss == 1)
	{
		// Cancel the convoy
		Quadrilha_Cancel(Quadrilha);
		// Exit the function
		return 1;
	}
	// Remove the player from the convoy
	APlayerData[playerid][InQuadrilha] = false;
	APlayerData[playerid][QuadrilhaID] = 0;
	// Hide both convoy-textdraws (for leader and members) as the member leaves the convoy
	TextDrawHideForPlayer(playerid, AQuadrilhas[Quadrilha][QuadrilhaTextLeader]);
	TextDrawHideForPlayer(playerid, AQuadrilhas[Quadrilha][QuadrilhaTextMember]);
	// Also update the player's missiontext to inform the player that he can start a job now (if there isn't a job started)
	if (APlayerData[playerid][JobStarted] == false)
		TextDrawSetString(APlayerData[playerid][MissionText], Mafia_NoJobText);
    // If the player is the leader
	if (AQuadrilhas[Quadrilha][Memberss][0] == playerid)
	{
		// Set another player as leader
		for (new j = 1; j < QUADRILHA_MAX_MEMBERS; j++)
		{
			// Get the playerid of the member
			MemberID = AQuadrilhas[Quadrilha][Memberss][j];
			if (MemberID != -1) // If a valid playerid is found
			{
				// Hide the member-textdraw as the member just became the leader
				TextDrawHideForPlayer(MemberID, AQuadrilhas[Quadrilha][QuadrilhaTextMember]);
                // Set this member as leader
				AQuadrilhas[Quadrilha][Memberss][0] = MemberID;
                // Clear this index, or the player would be twice in the same convoy
				AQuadrilhas[Quadrilha][Memberss][j] = -1;
                // Exit the function
				return 1;
			}
		}
	}
	else // The leaving player isn't the leader
	{
		// Find the player inside the convoy
		for (new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
		{
			// If the current player is this player
			if (AQuadrilhas[Quadrilha][Memberss][i] == playerid)
			{
			    // Reset the stored playerid in the convoy
			    AQuadrilhas[Quadrilha][Memberss][i] = -1;
				// Stop the job for this player (all data gets cleared, including the missiontext)
				Mafia_EndJob(playerid);
				return 1; // Exit the function
			}
		}
	}
	return 1;
}
// This function cancels the convoy, kicking every member in it
Quadrilha_Cancel(Quadrilha)
{
	// Setup local variables
	new MemberID;
	// Loop through all members
	for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
	{
		// Get the member's playerid
	    MemberID = AQuadrilhas[Quadrilha][Memberss][i];
		// If a valid playerid is found
		if (MemberID != -1)
		{
			// Remove the player from the convoy
			APlayerData[MemberID][InQuadrilha] = false;
			APlayerData[MemberID][QuadrilhaID] = 0;
			// Hide both convoy-textdraws (for leader and members)
   	        TextDrawHideForPlayer(MemberID, AQuadrilhas[Quadrilha][QuadrilhaTextLeader]);
   	        TextDrawHideForPlayer(MemberID, AQuadrilhas[Quadrilha][QuadrilhaTextMember]);
			// Cancel the trucker-job
			Mafia_EndJob(MemberID);
		    // Reset the stored playerid in the convoy
		    AQuadrilhas[Quadrilha][Memberss][i] = -1;
			// Send the member a message that the convoy was cancelled by the leader
			SendClientMessage(MemberID, 0xFFFFFFFF, TXT_LeaderCancelledQuadrilha);
		}
	}
	// Clear all the data of the convoy
	AQuadrilhas[Quadrilha][LoadID] = 0;
	AQuadrilhas[Quadrilha][Location1] = 0;
	AQuadrilhas[Quadrilha][Location2] = 0;
	AQuadrilhas[Quadrilha][Status1] = QUADRILHA_EMPTY;
	AQuadrilhas[Quadrilha][QuadrilhaStep] = 0;
	AQuadrilhas[Quadrilha][TrailerModel] = 0;
	AQuadrilhas[Quadrilha][LeaderInformedTrailers] = false;
	// Kill the convoy-timer
	KillTimer(AQuadrilhas[Quadrilha][QuadrilhaTimer]);
}
// This function is called for every member when the leader of the convoy started a job (missiontext is updated, loading-checkpoint is created, ...
Quadrilha_StartMemberJob(playerid, Quadrilha)
{
    // Setup local variables
	new StartLoc[50], EndLoc[50], Load[50], RouteText[255], Float

, Float:y, Float:z, LoadMsg[128];
	// Job has started
	APlayerData[playerid][JobStarted] = true;
	// Copy the convoy-data to this player
	APlayerData[playerid][LoadID] = AQuadrilhas[Quadrilha][LoadID];
	APlayerData[playerid][JobLoc1] = AQuadrilhas[Quadrilha][Location1];
	APlayerData[playerid][JobLoc2] = AQuadrilhas[Quadrilha][Location2];
	// Store the vehicleID (required to be able to check if the player left his vehicle)
	APlayerData[playerid][VehicleID] = GetPlayerVehicleID(playerid);
	// Store the trailerID (required to be able to check if the player lost his trailer)
	APlayerData[playerid][TrailerID] = GetVehicleTrailer(GetPlayerVehicleID(playerid));
	// Set jobstep to 1 (going to load the goods)
	APlayerData[playerid][JobStep] = 1;
	// Get the startlocation, endlocation and the load texts
	format(StartLoc, 50, ALocations[APlayerData[playerid][JobLoc1]][LocationName]);
	format(EndLoc, 50, ALocations[APlayerData[playerid][JobLoc2]][LocationName]);
	format(Load, 50, ALoads[APlayerData[playerid][LoadID]][LoadName]);
	// Combine it all into a string for the TextDraw (the player can see this all the time) to describe the mission
	format(RouteText, 255, TXT_HaulingCargoFromToPickup, Load, StartLoc, EndLoc);
	// Set the TextDraw so the player can see it
	TextDrawSetString(APlayerData[playerid][MissionText], RouteText);
	// Grab the x, y, z positions for the first location
	x = ALocations[APlayerData[playerid][JobLoc1]][LocX];
	y = ALocations[APlayerData[playerid][JobLoc1]][LocY];
	z = ALocations[APlayerData[playerid][JobLoc1]][LocZ];
	// Create a checkpoint where the player should load the goods
	SetPlayerCheckpoint(playerid, x, y, z, 7);
	// Set the job-fail-time for the global vehicle-timer
	APlayerData[playerid][VehicleTimerTime] = Job_TimeToFailMission;
	// Inform the player that he must load his goods
	format(LoadMsg, 128, TXT_PickupCargoAt, Load, StartLoc);
	SendClientMessage(playerid, 0xFFFFFFFF, LoadMsg);
	SendClientMessage(playerid, 0xFFFFFFFF, TXT_MeetOtherQuadrilhaMembers);
}
// This function is called when all convoy-members have loaded their cargo (it updates the missiontext and creates the unload-checkpoint)
Quadrilha_UpdateMemberJob(playerid)
{
    // Setup local variables
	new StartLoc[50], EndLoc[50], Load[50], RouteText[255], Float

, Float:y, Float:z, UnloadMsg[128];
	// Set the jobstep to 3 (going to unload the cargo at the destination)
	APlayerData[playerid][JobStep] = 3;
	// Get the startlocation, endlocation and the load texts
	format(StartLoc, 50, ALocations[APlayerData[playerid][JobLoc1]][LocationName]);
	format(EndLoc, 50, ALocations[APlayerData[playerid][JobLoc2]][LocationName]);
	format(Load, 50, ALoads[APlayerData[playerid][LoadID]][LoadName]);
	// Update the missiontext
	format(RouteText, 255, TXT_HaulingCargoFromToDeliver, Load, StartLoc, EndLoc);
	// Set the TextDraw so the player can see it
	TextDrawSetString(APlayerData[playerid][MissionText], RouteText);
	// Grab the x, y, z positions for the second location (to unload the goods)
	x = ALocations[APlayerData[playerid][JobLoc2]][LocX];
	y = ALocations[APlayerData[playerid][JobLoc2]][LocY];
	z = ALocations[APlayerData[playerid][JobLoc2]][LocZ];
	// Create a checkpoint where the player should unload the goods
	SetPlayerCheckpoint(playerid, x, y, z, 7);
	// Inform the player that he must unload his goods
	format(UnloadMsg, 128, TXT_DeliverCargoTo, Load, EndLoc);
	SendClientMessage(playerid, 0xFFFFFFFF, UnloadMsg);
}
// This is the timer used by every convoy (it updates and checks everything), is executed every 2.5 seconds
public Quadrilha_Timer(Quadrilha)
{
	// Setup local variables
	new LeaderID, MemberID;
	// Update the textdraws for all convoy members
    Quadrilha_UpdateTextDraws(Quadrilha);
	// Get the leader-id
	LeaderID = AQuadrilhas[Quadrilha][Memberss][0];
    // Check the jobstep for the entire convoy
	switch (AQuadrilhas[Quadrilha][QuadrilhaStep])
	{
		case 0: // Quadrilha has just been created, but a job hasn't started yet by the leader
		{
			new bool:AllSameTrailer = true;
			// Keep checking if the leader has started a job already
			if (APlayerData[LeaderID][JobStarted] == true)
			{
				// Copy the job-data from the leader to the convoy
				AQuadrilhas[Quadrilha][LoadID] = APlayerData[LeaderID][LoadID];
				AQuadrilhas[Quadrilha][Location1] = APlayerData[LeaderID][JobLoc1];
				AQuadrilhas[Quadrilha][Location2] = APlayerData[LeaderID][JobLoc2];
				// Set the trailer-model required by all members to the convoy
				AQuadrilhas[Quadrilha][TrailerModel] = GetVehicleModel(GetVehicleTrailer(GetPlayerVehicle  ID(LeaderID)));
				// First check if the leader has a trailer attached or not
				if (AQuadrilhas[Quadrilha][TrailerModel] != 0)
				{
					// First check if all players have the correct trailer (except for the leader)
					for (new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
					{
						MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the member-id from this member-spot
						if (MemberID != -1) // Check if the member-id is a valid playerid
						{
						    // Check if the player has the same trailer-model attached to his vehicle as the convoy requires
							if (GetVehicleModel(GetVehicleTrailer(GetPlayerVehicl  eID(MemberID))) != AQuadrilhas[Quadrilha][TrailerModel])
							{
							    // Inform the player that he hasn't got the correct trailer
							    switch (AQuadrilhas[Quadrilha][TrailerModel])
							    {
									case VehicleTrailerCargo, VehicleTrailerCargo2: TextDrawSetString(APlayerData[MemberID][MissionText], TXT_MemberNeedsCargoTrailer);
									case VehicleTrailerOre: TextDrawSetString(APlayerData[MemberID][MissionText], TXT_MemberNeedsOreTrailer);
									case VehicleTrailerFluids: TextDrawSetString(APlayerData[MemberID][MissionText], TXT_MemberNeedsFluidsTrailer);
								}
								// Not everyone has the same trailer
								AllSameTrailer = false;
							}
						}
					}
				}
				else // Leader has no trailer attached, so check for the vehiclemodel
				{
					// First check if all players have the correct trailer (except for the leader)
					for (new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
					{
						MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the member-id from this member-spot
						if (MemberID != -1) // Check if the member-id is a valid playerid
						{
						    // Get the vehiclemodel of the member
						    new vModel = GetVehicleModel(GetPlayerVehicleID(MemberID));
						    // Check if the member has a valid trucking vehicle (flatbed or DFT30)
							switch (vModel)
							{
								case VehicleFlatbed, VehicleDFT30: AllSameTrailer = true;
								default:
								{
									TextDrawSetString(APlayerData[MemberID][MissionText], "You need a Flatbed or DFT-30");
									AllSameTrailer = false;
								}
							}
						}
					}
				}
				// If all members have the same trailer
				if (AllSameTrailer == true)
				{
					// Inform the leader that everyone has the same trailer
					SendClientMessage(LeaderID, 0xFFFFFFFF, TXT_AllMembersSameTrailer);
					// Start the same job for every member if they all have the same trailer
					for (new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
					{
						MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the member-id from this member-spot
						if (MemberID != -1) // Check if the member-id is a valid playerid
							Quadrilha_StartMemberJob(MemberID, Quadrilha); // Start the job for the member
					}
					// Select the next step for the convoy (all members are now en-route to the loading-point)
	                AQuadrilhas[Quadrilha][QuadrilhaStep] = 1;
					// Also close the convoy so no more members can join
				    AQuadrilhas[Quadrilha][Status1] = QUADRILHA_CLOSED;
				}
				else
				{
				    // Check if the leader has been informed already that not all members have the same trailer
					if (AQuadrilhas[Quadrilha][LeaderInformedTrailers] == false)
					{
						// Inform the leader that not every member has the same trailer, convoy cannot start yet
						SendClientMessage(LeaderID, 0xFFFFFFFF, TXT_AllMembersNotSameTrailer);
						AQuadrilhas[Quadrilha][LeaderInformedTrailers] = true; // Leader is informed now
					}
				}
			}
		}
		case 1: // Everyone has received their job-data (but haven't loaded their cargo yet)
		{
			new bool:AllMembersLoaded = true;
			// Check if everyone has loaded their cargo before moving on to QuadrilhaStep 2
			for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
			{
				MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the playerid of the member
				if (MemberID != -1) // Check if the memberid is a valid id
					if (APlayerData[MemberID][JobStep] != 2) // Check if the player hasn't loaded his cargo yet
					    AllMembersLoaded = false; // Not all members have loaded their cargo yet
			}
			// Check if everyone has loaded their cargo
			if (AllMembersLoaded == true)
			{
				// Inform the leader that everyone has the same trailer
				SendClientMessage(LeaderID, 0xFFFFFFFF, TXT_AllMembersLoadedCargo);
				// Update the job for every member if they all have loaded their cargo
				for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
				{
					MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the member-id from this member-spot
					if (MemberID != -1) // Check if the member-id is a valid playerid
						Quadrilha_UpdateMemberJob(MemberID); // Start the job for the member
				}
				// Select the next step for the convoy (all members are now en-route to the unloading-point)
                AQuadrilhas[Quadrilha][QuadrilhaStep] = 2;
			}
		}
		case 2: // Everybody has loaded their cargo and all members have their job updated, all members are en-route to the destination
		{
			// Check if everyone is staying close to the leader and check if all members have unloaded their cargo
			new bool:AllMembersUnloaded = true;
			// Also check if all players have delivered their load
			for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
			{
				MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the playerid of the member
				if (MemberID != -1) // Check if the memberid is a valid id
					if (APlayerData[MemberID][JobStep] != 4) // Check if the player hasn't unloaded his cargo yet
					    AllMembersUnloaded = false; // Not all members have unloaded their cargo yet
			}
			if (AllMembersUnloaded == true) // Check if all members have unloaded their cargo (nobody cleared this variable)
				AQuadrilhas[Quadrilha][QuadrilhaStep] = 3; // Set the jobstep for the entire convoy to 3 (everybody unloaded their cargo, but jobs must still be payed out)
		}
		case 3: // Everybody has unloaded their cargo (now it's time to pay all members and finish the job)
		{
		    // Setup local variables
			new Float

1, Float:y1, Float

2, Float:y2, Float

istance, Message[128], Payment, Bonus, NumMemberss, Name[24], BonusMsg[128];
			// Count the number of members in the convoy
			NumMemberss = Quadrilha_CountMembers(Quadrilha);
			// Get the name of the convoy-leader
			GetPlayerName(LeaderID, Name, sizeof(Name));
			// Grab the x, y, z positions for the first location (to load the goods)
			x1 = ALocations[APlayerData[LeaderID][JobLoc1]][LocX];
			y1 = ALocations[APlayerData[LeaderID][JobLoc1]][LocY];
			// Grab the x, y, z positions for the second location (to unload the goods)
			x2 = ALocations[APlayerData[LeaderID][JobLoc2]][LocX];
			y2 = ALocations[APlayerData[LeaderID][JobLoc2]][LocY];
			// Calculate the distance between both points
			Distance = floatsqroot(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
			// Calculate the payment for the player
			Payment = floatround((Distance * ALoads[APlayerData[LeaderID][LoadID]][PayPerUnit]), floatround_floor);
			// Check if the convoy has done the bonus mission
			if (RandomBonusMission[MissionFinished] == false)
			{
				// Check all paramters (load, startlocation and end-location)
				if (RandomBonusMission[RandomLoad] == APlayerData[LeaderID][LoadID])
					if (RandomBonusMission[RandomStartLoc] == APlayerData[LeaderID][JobLoc1])
						if (RandomBonusMission[RandomEndLoc] == APlayerData[LeaderID][JobLoc2])
						{
						    Payment = Payment * 2; // Double the payment is the player was the first to do the bonus mission
                            RandomBonusMission[MissionFinished] = true; // Only one player/convoy can do the bonus mission, a new one is chosen next
							format(BonusMsg, 128, "{808080}O Comboio do Lider {FFFFFF}%s{808080} Completou a Missao Bonus", Name);
							SendClientMessageToAll(0xFFFFFFFF, BonusMsg);
						}
			}
		    // Calculate convoy-bonus (standard payment of 100% and 25% extra for each convoy-member)
		    Bonus = (NumMemberss * 25) + 100; // For every member, 25% bonus is added to the payment, on top of the standard payment
			// Calculate total payment for each member
			Payment = (Payment * Bonus) / 100;
			// Pay every member and finish their mission
			for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
			{
				MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the playerid of the member
				if (MemberID != -1) // Check if the memberid is a valid id
				{
					// Reward the player (give cash and points)
					RewardPlayer(MemberID, Payment, 5);
					// Increase the stats for completing a trucking job while in a convoy
					APlayerData[MemberID][StatsQuadrilhaJobs]++;
					// Also save the data (in case the server crashes, progress would be lost)
					PlayerFile_Save(MemberID);
					// End the member's job
					Mafia_EndJob(MemberID);
					// Send a message to let the player know he finished his mission and got paid
					format(Message, 128, TXT_FinishedQuadrilha, Payment);
					SendClientMessage(MemberID, 0xFFFFFFFF, Message);
					// Also update the player's missiontext to inform the player that he must wait for the leader to start a job
					if (i != 0) // Skip this if the current index is the leader (the leader doesn't have to wait for a new job)
						TextDrawSetString(APlayerData[MemberID][MissionText], TXT_WaitingLeaderJob);
				}
			}
			// Clear the data in the convoy
			AQuadrilhas[Quadrilha][LoadID] = 0; // Clear the load-id
			AQuadrilhas[Quadrilha][Location1] = 0; // Clear the loadingpoint id
			AQuadrilhas[Quadrilha][Location2] = 0; // Clear the unloading point id
			AQuadrilhas[Quadrilha][Status1] = QUADRILHA_OPEN; // Set Status1 to "open" again, so new members can join
			AQuadrilhas[Quadrilha][QuadrilhaStep] = 0; // Set QuadrilhaStep to 0 (wait for a new job to be started by the leader)
			AQuadrilhas[Quadrilha][TrailerModel] = 0; // Clear trailer model (the next job can be for another trailer)
			AQuadrilhas[Quadrilha][LeaderInformedTrailers] = false; // Allow the leader to be informed again if not all members have the correct trailer
		}
	}
	return 1;
}
// This function is used to update the textdraws for the leader and all members (used by the convoy-timer)
Quadrilha_UpdateTextDraws(Quadrilha)
{
	// Setup local variables
	new LeaderID, MemberID, LeaderName[24], NumMemberss, TextLeader[128], TextMember[128], LastMember[24], LastMemberID, Float

istance;
	// Get the leader-id
	LeaderID = AQuadrilhas[Quadrilha][Memberss][0];
	// Get the name of the convoy-leader
	GetPlayerName(LeaderID, LeaderName, sizeof(LeaderName));
	// Get the number of members of the convoy
	NumMemberss = Quadrilha_CountMembers(Quadrilha);
	// Check if there members besides the leader
	if (NumMemberss > 1)
	{
	    LastMemberID = Quadrilha_GetFurthestMember(Quadrilha); // Get the playerid of the member who is furthest away from the leader
		GetPlayerName(LastMemberID, LastMember, sizeof(LastMember)); // Get the name of the furthest member
		Distance = PlayerToPlayer(LeaderID, LastMemberID); // Get the distance to the last member
	}
	else // No other members are in the convoy yet
	{
		format(LastMember, 24, " - ");
		Distance = 0.0;
	}
	// Update the convoy-textdraw for the leader
	format(TextLeader, 128, TXT_LeaderQuadrilhaInfoBar, NumMemberss, LastMember, Distance);
	TextDrawSetString(AQuadrilhas[Quadrilha][QuadrilhaTextLeader], TextLeader);
	// Enable the convoy-textDraw for the leader
	TextDrawShowForPlayer(LeaderID, AQuadrilhas[Quadrilha][QuadrilhaTextLeader]);
	// Update the convoy-textdraw for every member
	for (new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
	{
		MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the playerid of the member
		if (MemberID != -1) // Check if the memberid is a valid id
		{
			// Calculate the distance to the leader
			Distance = PlayerToPlayer(LeaderID, MemberID);
			// Update the textdraw for the members
			format(TextMember, 128, TXT_MemberQuadrilhaInfoBar, LeaderName, Distance, NumMemberss);
			TextDrawSetString(AQuadrilhas[Quadrilha][QuadrilhaTextMember], TextMember);
			TextDrawShowForPlayer(MemberID, AQuadrilhas[Quadrilha][QuadrilhaTextMember]);
		}
	}
}
// This function counts the members in the convoy
Quadrilha_CountMembers(Quadrilha)
{
	// Setup local variables
	new NumMemberss;
	// Loop through all members
	for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
	{
		// Check if there is a valid member-id stored (playerid)
		if (AQuadrilhas[Quadrilha][Memberss][i] != -1)
		    NumMemberss++; // Increase the number of members
	}
	// Return the number of members to the calling routine
	return NumMemberss;
}
// This function checks the player and determines if he's a valid trucker who's able to create or join a convoy
Quadrilha_PlayerAllowed(playerid)
{
	// Make sure that the leader is a trucker
	if (APlayerData[playerid][PlayerClass] == ClassMafia)
	{
		// Check if the player isn't a member of a convoy already
		if (APlayerData[playerid][InQuadrilha] == false)
		{
			// Make sure that the player hasn't started a job
			if (APlayerData[playerid][JobStarted] == false)
				return true; // The player is allowed to create or join a convoy
			else
			    SendClientMessage(playerid, 0xFFFFFFFF, TXT_CannotJoinJobStarted);
		}
		else
		    SendClientMessage(playerid, 0xFFFFFFFF, TXT_QuadrilhaAllreadyJoined);
	}
	else
	    SendClientMessage(playerid, 0xFFFFFFFF, TXT_QuadrilhaNeedsMafiaClass);
	// If any condition wasn't true, the player isn't allowed to create or join a convoy
	return false;
}
// This function sends the given message to all members of the convoy
Quadrilha_SendMessage(Quadrilha, Message[])
{
	// Setup local variables
	new MemberID;
	// Loop through all members
	for (new i; i < QUADRILHA_MAX_MEMBERS; i++)
	{
	    MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the member-id on this index
	    if (MemberID != -1) // Check if this member has a valid playerid
		{
			SendClientMessage(MemberID, 0xFFFFFFFF, Message); // Send the given message to the member
		}
	}
}
// This function returns "true" is the given player is the leader of the convoy
stock Quadrilha_IsLeader(playerid, Quadrilha)
{
	// Check if the player is part of a convoy
	if ((APlayerData[playerid][InQuadrilha] == true) && (AQuadrilhas[Quadrilha][Memberss][0] = playerid))
	    return true; // Player is in a convoy AND he's the leader of it
	else
	    return false; // Player is a member of the convoy (or not in the same convoy)
}
// This function returns true if the player is a member of the given convoy
stock Quadrilha_IsMember(playerid, Quadrilha)
{
	// Loop through all members (excluding the leader)
	for (new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
	    if (AQuadrilhas[Quadrilha][Memberss][i] == playerid) // Check if this member is the given player
			return true; // Return true (the player is a member of the convoy)
	// If the given playerid wasn't found among the members, return false
	return false;
}
// A function that returns the member of a convoy that's the furthest away from the leader
Quadrilha_GetFurthestMember(Quadrilha)
{
	// Setup local variables
	new Float:distance = 0.0, Float:distance2 = 0.0, LeaderID, MemberID, result = -1;
	// Get the leader-id
	LeaderID = AQuadrilhas[Quadrilha][Memberss][0];
	// Loop through all members (excluding the leader)
	for(new i = 1; i < QUADRILHA_MAX_MEMBERS; i++)
	{
		MemberID = AQuadrilhas[Quadrilha][Memberss][i]; // Get the playerid of the member
		if (MemberID != -1) // Check if the memberid is a valid id
		{
			// Get the distance between leader and member
			distance2 = PlayerToPlayer(LeaderID, MemberID);
			// Check if the distance is bigger than the previous distance
			if(distance2 > distance)
			{
				// Store the distance
				distance = distance2;
				// Store the member-id
				result = MemberID;
			}
		}
	}
	// Return the vehicle-id of the closest vehicle
	return result;
}