| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720 |
- // This include file holds all functions for doing convoys
- forward Convoy_Timer(Convoy);
- // This function is called only once and is used to setup the textdraws and default data for convoys
- Convoys_Init()
- {
- for (new i; i < MAX_CONVOYS; i++)
- {
- AConvoys[i][ConvoyTextLeader] = TextDrawCreate(320.0, 1.0, " "); // Create the textdraw for the leader
- TextDrawSetShadow(AConvoys[i][ConvoyTextLeader], 1); // Reduce the shadow to 1
- TextDrawAlignment(AConvoys[i][ConvoyTextLeader], 2); // Align the convoy-infobar to the center for the leader
- TextDrawUseBox(AConvoys[i][ConvoyTextLeader], 1); // Set the missiontext to display inside a box
- TextDrawBoxColor(AConvoys[i][ConvoyTextLeader] ,0x00000066); // Set the box color of the missiontext
- AConvoys[i][ConvoyTextMember] = TextDrawCreate(320.0, 1.0, " "); // Create the textdraw for the members
- TextDrawSetShadow(AConvoys[i][ConvoyTextLeader], 1); // Reduce the shadow to 1
- TextDrawAlignment(AConvoys[i][ConvoyTextMember], 2); // Align the convoy-infobar to the center for the members
- TextDrawUseBox(AConvoys[i][ConvoyTextMember], 1); // Set the missiontext to display inside a box
- TextDrawBoxColor(AConvoys[i][ConvoyTextMember] ,0x00000066); // Set the box color of the missiontext
- }
- }
- // This function is used when a player selected an empty convoy-slot (the player will start the convoy and become the leader)
- Convoy_Create(playerid, Convoy)
- {
- // 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 convoy (he must be a trucker without a job and not part of a convoy yet)
- if (Convoy_PlayerAllowed(playerid))
- {
- // Set status of the convoy to "open"
- AConvoys[Convoy][Status] = CONVOY_OPEN;
- // Set the player as leader of the convoy
- AConvoys[Convoy][Members][0] = playerid;
- // Set the player as a member of a convoy
- APlayerData[playerid][InConvoy] = true;
- APlayerData[playerid][ConvoyID] = Convoy;
- // Set all other member-indices to "-1" (no player yet)
- for (new i = 1; i < CONVOY_MAX_MEMBERS; i++)
- AConvoys[Convoy][Members][i] = -1;
- // Start the convoy-timer (this timer updates and checks everything for the whole convoy), it runs every second
- AConvoys[Convoy][ConvoyTimer] = SetTimerEx("Convoy_Timer", 1000, true, "i", Convoy);
- // Let all players know that this player wants to start a convoy
- format(Msg, 128, TXT_PlayerStartsConvoy, Name);
- SendClientMessageToAll(0xFFFFFFFF, Msg);
- }
- }
- // This function is used to let another player join a convoy
- Convoy_Join(playerid, Convoy)
- {
- // 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 (Convoy_PlayerAllowed(playerid))
- {
- // Check if the convoy isn't full already
- if (Convoy_CountMembers(Convoy) < CONVOY_MAX_MEMBERS)
- {
- // Inform all the members of the convoy that this player joined the convoy
- format(Msg, 128, TXT_PlayerJoinedConvoy, Name);
- Convoy_SendMessage(Convoy, Msg);
- // Inform the player that he joined the convoy
- SendClientMessage(playerid, 0xFFFFFFFF, TXT_YouJoinedConvoy);
- // Set the player as member of the convoy (find a free spot for this player)
- for (new i; i < CONVOY_MAX_MEMBERS; i++)
- {
- if (AConvoys[Convoy][Members][i] == -1) // Check if this member-spot is empty
- {
- AConvoys[Convoy][Members][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][InConvoy] = true;
- APlayerData[playerid][ConvoyID] = Convoy;
- // Set the convoystatus as "Full" if all member-spots are occupied
- if (Convoy_CountMembers(Convoy) == CONVOY_MAX_MEMBERS)
- AConvoys[Convoy][Status] = CONVOY_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_ConvoyFull);
- }
- }
- // This function is used to let a player leave a convoy (when he disconnects, finishes the convoy, when he dies, ...)
- Convoy_Leave(playerid)
- {
- // Setup local variables
- new Convoy, NumMembers, MemberID;
- // First theck if the player is part of a convoy
- if (APlayerData[playerid][InConvoy] == false)
- return 1; // Exit the function if the player isn't part of a convoy
- // Get the convoy-id from the player
- Convoy = APlayerData[playerid][ConvoyID];
- // Get the number of members in the convoy
- NumMembers = Convoy_CountMembers(Convoy);
- // If there is only 1 member in the convoy (convoy will have no members if this one leaves), cancel the convoy
- if (NumMembers == 1)
- {
- // Cancel the convoy
- Convoy_Cancel(Convoy);
- // Exit the function
- return 1;
- }
- // Remove the player from the convoy
- APlayerData[playerid][InConvoy] = false;
- APlayerData[playerid][ConvoyID] = 0;
- // Hide both convoy-textdraws (for leader and members) as the member leaves the convoy
- TextDrawHideForPlayer(playerid, AConvoys[Convoy][ConvoyTextLeader]);
- TextDrawHideForPlayer(playerid, AConvoys[Convoy][ConvoyTextMember]);
- // 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], Trucker_NoJobText);
- // If the player is the leader
- if (AConvoys[Convoy][Members][0] == playerid)
- {
- // Set another player as leader
- for (new j = 1; j < CONVOY_MAX_MEMBERS; j++)
- {
- // Get the playerid of the member
- MemberID = AConvoys[Convoy][Members][j];
- if (MemberID != -1) // If a valid playerid is found
- {
- // Hide the member-textdraw as the member just became the leader
- TextDrawHideForPlayer(MemberID, AConvoys[Convoy][ConvoyTextMember]);
- // Set this member as leader
- AConvoys[Convoy][Members][0] = MemberID;
- // Clear this index, or the player would be twice in the same convoy
- AConvoys[Convoy][Members][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 < CONVOY_MAX_MEMBERS; i++)
- {
- // If the current player is this player
- if (AConvoys[Convoy][Members][i] == playerid)
- {
- // Reset the stored playerid in the convoy
- AConvoys[Convoy][Members][i] = -1;
- // Stop the job for this player (all data gets cleared, including the missiontext)
- Trucker_EndJob(playerid);
- return 1; // Exit the function
- }
- }
- }
- return 1;
- }
- // This function cancels the convoy, kicking every member in it
- Convoy_Cancel(Convoy)
- {
- // Setup local variables
- new MemberID;
- // Loop through all members
- for (new i; i < CONVOY_MAX_MEMBERS; i++)
- {
- // Get the member's playerid
- MemberID = AConvoys[Convoy][Members][i];
- // If a valid playerid is found
- if (MemberID != -1)
- {
- // Remove the player from the convoy
- APlayerData[MemberID][InConvoy] = false;
- APlayerData[MemberID][ConvoyID] = 0;
- // Hide both convoy-textdraws (for leader and members)
- TextDrawHideForPlayer(MemberID, AConvoys[Convoy][ConvoyTextLeader]);
- TextDrawHideForPlayer(MemberID, AConvoys[Convoy][ConvoyTextMember]);
- // Cancel the trucker-job
- Trucker_EndJob(MemberID);
- // Reset the stored playerid in the convoy
- AConvoys[Convoy][Members][i] = -1;
- // Send the member a message that the convoy was cancelled by the leader
- SendClientMessage(MemberID, 0xFFFFFFFF, TXT_LeaderCancelledConvoy);
- }
- }
- // Clear all the data of the convoy
- AConvoys[Convoy][LoadID] = 0;
- AConvoys[Convoy][Location1] = 0;
- AConvoys[Convoy][Location2] = 0;
- AConvoys[Convoy][Status] = CONVOY_EMPTY;
- AConvoys[Convoy][ConvoyStep] = 0;
- AConvoys[Convoy][TrailerModel] = 0;
- AConvoys[Convoy][LeaderInformedTrailers] = false;
- // Kill the convoy-timer
- KillTimer(AConvoys[Convoy][ConvoyTimer]);
- }
- // This function is called for every member when the leader of the convoy started a job (missiontext is updated, loading-checkpoint is created, ...
- Convoy_StartMemberJob(playerid, Convoy)
- {
- // Setup local variables
- new StartLoc[50], EndLoc[50], Load[50], RouteText[255], Float:x, Float:y, Float:z, LoadMsg[128];
- // Job has started
- APlayerData[playerid][JobStarted] = true;
- // Copy the convoy-data to this player
- APlayerData[playerid][LoadID] = AConvoys[Convoy][LoadID];
- APlayerData[playerid][JobLoc1] = AConvoys[Convoy][Location1];
- APlayerData[playerid][JobLoc2] = AConvoys[Convoy][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_MeetOtherConvoyMembers);
- }
- // This function is called when all convoy-members have loaded their cargo (it updates the missiontext and creates the unload-checkpoint)
- Convoy_UpdateMemberJob(playerid)
- {
- // Setup local variables
- new StartLoc[50], EndLoc[50], Load[50], RouteText[255], Float:x, 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 Convoy_Timer(Convoy)
- {
- // Setup local variables
- new LeaderID, MemberID;
- // Update the textdraws for all convoy members
- Convoy_UpdateTextDraws(Convoy);
- // Get the leader-id
- LeaderID = AConvoys[Convoy][Members][0];
- // Check the jobstep for the entire convoy
- switch (AConvoys[Convoy][ConvoyStep])
- {
- case 0: // Convoy 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
- AConvoys[Convoy][LoadID] = APlayerData[LeaderID][LoadID];
- AConvoys[Convoy][Location1] = APlayerData[LeaderID][JobLoc1];
- AConvoys[Convoy][Location2] = APlayerData[LeaderID][JobLoc2];
- // Set the trailer-model required by all members to the convoy
- AConvoys[Convoy][TrailerModel] = GetVehicleModel(GetVehicleTrailer(GetPlayerVehicleID(LeaderID)));
- // First check if the leader has a trailer attached or not
- if (AConvoys[Convoy][TrailerModel] != 0)
- {
- // First check if all players have the correct trailer (except for the leader)
- for (new i = 1; i < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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(GetPlayerVehicleID(MemberID))) != AConvoys[Convoy][TrailerModel])
- {
- // Inform the player that he hasn't got the correct trailer
- switch (AConvoys[Convoy][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 < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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 < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][i]; // Get the member-id from this member-spot
- if (MemberID != -1) // Check if the member-id is a valid playerid
- Convoy_StartMemberJob(MemberID, Convoy); // Start the job for the member
- }
- // Select the next step for the convoy (all members are now en-route to the loading-point)
- AConvoys[Convoy][ConvoyStep] = 1;
- // Also close the convoy so no more members can join
- AConvoys[Convoy][Status] = CONVOY_CLOSED;
- }
- else
- {
- // Check if the leader has been informed already that not all members have the same trailer
- if (AConvoys[Convoy][LeaderInformedTrailers] == false)
- {
- // Inform the leader that not every member has the same trailer, convoy cannot start yet
- SendClientMessage(LeaderID, 0xFFFFFFFF, TXT_AllMembersNotSameTrailer);
- AConvoys[Convoy][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 convoystep 2
- for (new i; i < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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 < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][i]; // Get the member-id from this member-spot
- if (MemberID != -1) // Check if the member-id is a valid playerid
- Convoy_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)
- AConvoys[Convoy][ConvoyStep] = 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 < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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)
- AConvoys[Convoy][ConvoyStep] = 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:x1, Float:y1, Float:x2, Float:y2, Float:Distance, Message[128], Payment, Bonus, NumMembers, Name[24], BonusMsg[128];
- // Count the number of members in the convoy
- NumMembers = Convoy_CountMembers(Convoy);
- // 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, "{00BBFF}Convoy with leader {FFBB00}%s{00BBFF} has finished the bonus mission", Name);
- SendClientMessageToAll(0xFFFFFFFF, BonusMsg);
- }
- }
- // Calculate convoy-bonus (standard payment of 100% and 25% extra for each convoy-member)
- Bonus = (NumMembers * 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 < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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][StatsConvoyJobs]++;
- // Also save the data (in case the server crashes, progress would be lost)
- PlayerFile_Save(MemberID);
- // End the member's job
- Trucker_EndJob(MemberID);
- // Send a message to let the player know he finished his mission and got paid
- format(Message, 128, TXT_FinishedConvoy, 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
- AConvoys[Convoy][LoadID] = 0; // Clear the load-id
- AConvoys[Convoy][Location1] = 0; // Clear the loadingpoint id
- AConvoys[Convoy][Location2] = 0; // Clear the unloading point id
- AConvoys[Convoy][Status] = CONVOY_OPEN; // Set status to "open" again, so new members can join
- AConvoys[Convoy][ConvoyStep] = 0; // Set convoystep to 0 (wait for a new job to be started by the leader)
- AConvoys[Convoy][TrailerModel] = 0; // Clear trailer model (the next job can be for another trailer)
- AConvoys[Convoy][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)
- Convoy_UpdateTextDraws(Convoy)
- {
- // Setup local variables
- new LeaderID, MemberID, LeaderName[24], NumMembers, TextLeader[128], TextMember[128], LastMember[24], LastMemberID, Float:Distance;
- // Get the leader-id
- LeaderID = AConvoys[Convoy][Members][0];
- // Get the name of the convoy-leader
- GetPlayerName(LeaderID, LeaderName, sizeof(LeaderName));
- // Get the number of members of the convoy
- NumMembers = Convoy_CountMembers(Convoy);
- // Check if there members besides the leader
- if (NumMembers > 1)
- {
- LastMemberID = Convoy_GetFurthestMember(Convoy); // 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_LeaderInfoBar, NumMembers, LastMember, Distance);
- TextDrawSetString(AConvoys[Convoy][ConvoyTextLeader], TextLeader);
- // Enable the convoy-textDraw for the leader
- TextDrawShowForPlayer(LeaderID, AConvoys[Convoy][ConvoyTextLeader]);
- // Update the convoy-textdraw for every member
- for (new i = 1; i < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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_MemberInfoBar, LeaderName, Distance, NumMembers);
- TextDrawSetString(AConvoys[Convoy][ConvoyTextMember], TextMember);
- TextDrawShowForPlayer(MemberID, AConvoys[Convoy][ConvoyTextMember]);
- }
- }
- }
- // This function counts the members in the convoy
- Convoy_CountMembers(Convoy)
- {
- // Setup local variables
- new NumMembers;
- // Loop through all members
- for (new i; i < CONVOY_MAX_MEMBERS; i++)
- {
- // Check if there is a valid member-id stored (playerid)
- if (AConvoys[Convoy][Members][i] != -1)
- NumMembers++; // Increase the number of members
- }
- // Return the number of members to the calling routine
- return NumMembers;
- }
- // This function checks the player and determines if he's a valid trucker who's able to create or join a convoy
- Convoy_PlayerAllowed(playerid)
- {
- // Make sure that the leader is a trucker
- if (APlayerData[playerid][PlayerClass] == ClassTruckDriver)
- {
- // Check if the player isn't a member of a convoy already
- if (APlayerData[playerid][InConvoy] == 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_ConvoyAllreadyJoined);
- }
- else
- SendClientMessage(playerid, 0xFFFFFFFF, TXT_ConvoyNeedsTruckerClass);
- // 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
- Convoy_SendMessage(Convoy, Message[])
- {
- // Setup local variables
- new MemberID;
- // Loop through all members
- for (new i; i < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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 Convoy_IsLeader(playerid, Convoy)
- {
- // Check if the player is part of a convoy
- if ((APlayerData[playerid][InConvoy] == true) && (AConvoys[Convoy][Members][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 Convoy_IsMember(playerid, Convoy)
- {
- // Loop through all members (excluding the leader)
- for (new i = 1; i < CONVOY_MAX_MEMBERS; i++)
- if (AConvoys[Convoy][Members][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
- Convoy_GetFurthestMember(Convoy)
- {
- // Setup local variables
- new Float:distance = 0.0, Float:distance2 = 0.0, LeaderID, MemberID, result = -1;
- // Get the leader-id
- LeaderID = AConvoys[Convoy][Members][0];
- // Loop through all members (excluding the leader)
- for(new i = 1; i < CONVOY_MAX_MEMBERS; i++)
- {
- MemberID = AConvoys[Convoy][Members][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;
- }
- // Get the distance between the two players
- PlayerToPlayer(player1, player2)
- {
- // Setup local variables
- new Float:pX, Float:pY, Float:pZ, Float:cX, Float:cY, Float:cZ, Float:distance;
- // Get the player1 position
- GetPlayerPos(player1, pX, pY, pZ);
- // Get the player2 position
- GetPlayerPos(player2, cX, cY, cZ);
- // Calculate the distance
- distance = floatsqroot(floatpower(floatabs(floatsub(cX, pX)), 2) + floatpower(floatabs(floatsub(cY, pY)), 2) + floatpower(floatabs(floatsub(cZ, pZ)), 2));
- // Return the distance to the calling routine
- return floatround(distance);
- }
|