units.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. _ _ _ _ ____ _____ _
  3. | | | | (_) | | _ \ | __ \ | |
  4. | | | |_ __ _| |_ ___ | |_) |_ _ | | | | ___ ___ _ __ ___ ___ _ __ __| |
  5. | | | | '_ \| | __/ __| | _ <| | | | | | | |/ _ \/ __| '_ ` _ \ / _ \| '_ \ / _` |
  6. | |__| | | | | | |_\__ \ | |_) | |_| | | |__| | __/\__ \ | | | | | (_) | | | | (_| |
  7. \____/|_| |_|_|\__|___/ |____/ \__, | |_____/ \___||___/_| |_| |_|\___/|_| |_|\__,_|
  8. __/ |
  9. |___/
  10. */
  11. #define MAX_UNITS 40
  12. #define MAX_UNIT_MEMBERS 4
  13. #define MAX_UNITS_PER_FACTION 20
  14. #define DIALOG_UNITS_MAIN 16758
  15. #define DIALOG_UNITS_SHOW 16759
  16. #define DIALOG_UNITS_CREATE 16760
  17. #define DIALOG_UNITS_JOIN 16761
  18. #define DIALOG_UNITS_DISBAND 16762
  19. #define DIALOG_UNITS_FIND 16763
  20. enum unitinfo
  21. {
  22. bool:unitActive,
  23. unitCallSign[20],
  24. unitLeader,
  25. unitFaction
  26. };
  27. new Units[MAX_UNITS][unitinfo];
  28. new pdunits, fmdunits; // counter for how many units there are currently in each faction, maximum 20 per faction!
  29. new unitsmsg[200];
  30. new joiningunit[MAX_PLAYERS];
  31. new Text3D:UnitsCallSign[MAX_VEHICLES];
  32. new findingunit[MAX_PLAYERS];
  33. forward UnitSystemAccess(playerid);
  34. forward ShowPlayerUnits(playerid);
  35. forward ShowPlayerUnitInfo(playerid, unitid, join = 0);
  36. forward GetUnitMembers(unitid);
  37. forward GetUnitLeader(unitid);
  38. forward CreateUnit(playerid, name[]);
  39. forward DisbandUnit(unitid);
  40. public UnitSystemAccess(playerid)
  41. {
  42. if(PlayerInfo[playerid][pMember] == FACTION_SAPD || PlayerInfo[playerid][pMember] == FACTION_FMD) return 1;
  43. else if(PlayerInfo[playerid][pMember] == 11 && FakeFaction[playerid] == FACTION_SAPD) return 1;
  44. else if(PlayerInfo[playerid][pMember] == 11 && FakeFaction[playerid] == FACTION_FMD) return 1;
  45. else return 0;
  46. }
  47. public GetUnitLeader(unitid)
  48. {
  49. return Units[unitid][unitLeader];
  50. }
  51. public GetUnitMembers(unitid)
  52. {
  53. new counter = 0;
  54. foreach( new i: Player )
  55. {
  56. if(!UnitSystemAccess(i)) continue;
  57. if(PlayerInfo[i][pUnit] == unitid) counter++;
  58. }
  59. return counter;
  60. }
  61. public ShowPlayerUnits(playerid)
  62. {
  63. new facid = PlayerInfo[playerid][pMember];
  64. new unitsstr[1500], headers[] = "Callsign\tLeader\tMembers\n";
  65. new unitexists;
  66. for(new i = 0; i < MAX_UNITS; i++)
  67. {
  68. if(!Units[i][unitActive]) continue;
  69. if(Units[i][unitFaction] != facid && FakeFaction[playerid] != Units[i][unitFaction]) continue;
  70. format(unitsstr, sizeof(unitsstr), "%s%s\t%s\t%d\n", unitsstr, Units[i][unitCallSign], PlayerICName(Units[i][unitLeader]), GetUnitMembers(i));
  71. unitexists = 1;
  72. }
  73. format(unitsstr, sizeof(unitsstr), "%s%s", headers, unitsstr);
  74. if(unitexists == 1) ShowPlayerDialog(playerid, DIALOG_UNITS_SHOW, DIALOG_STYLE_TABLIST_HEADERS, "Available Units", unitsstr, "Select", "Cancel");
  75. return 1;
  76. }
  77. public CreateUnit(playerid, name[])
  78. {
  79. for(new i = 0; i < MAX_UNITS; i++)
  80. {
  81. if(Units[i][unitActive]) continue;
  82. if(PlayerInfo[playerid][pMember] == 11) Units[i][unitFaction] = FakeFaction[playerid];
  83. else Units[i][unitFaction] = PlayerInfo[playerid][pMember];
  84. Units[i][unitActive] = true;
  85. Units[i][unitLeader] = playerid;
  86. format(Units[i][unitCallSign], 20, "%s", name);
  87. PlayerInfo[playerid][pUnit] = i;
  88. break;
  89. }
  90. if(PlayerInfo[playerid][pMember] == FACTION_SAPD || FakeFaction[playerid] == FACTION_SAPD) pdunits++;
  91. else if(PlayerInfo[playerid][pMember] == FACTION_FMD || FakeFaction[playerid] == FACTION_FMD) fmdunits++;
  92. return 1;
  93. }
  94. public DisbandUnit(unitid)
  95. {
  96. foreach( new i: Player )
  97. {
  98. if(PlayerInfo[i][pMember] != Units[unitid][unitFaction] && FakeFaction[i] != Units[unitid][unitFaction]) continue;
  99. if(PlayerInfo[i][pUnit] != unitid) continue;
  100. PlayerInfo[i][pUnit] = -1;
  101. }
  102. format(unitsmsg, sizeof(unitsmsg), "HQ: Unit '%s' has been disbanded.", Units[unitid][unitCallSign]);
  103. SendRadioMessage(Units[unitid][unitFaction], GetFactionColour(Units[unitid][unitFaction]), unitsmsg);
  104. if(Units[unitid][unitFaction] == FACTION_SAPD) pdunits--;
  105. else if(Units[unitid][unitFaction] == FACTION_FMD) fmdunits--;
  106. Units[unitid][unitActive] = false;
  107. Units[unitid][unitFaction] = -1;
  108. Units[unitid][unitLeader] = -1;
  109. format(Units[unitid][unitCallSign], 20, "");
  110. return 1;
  111. }
  112. ShowPlayerUnitInfo(playerid, unitid, join = 0) // join is only 1 when the player is watching other units' stats and not his own.
  113. {
  114. new unitinfostr[400];
  115. format(unitinfostr, sizeof(unitinfostr), "Unit Callsign: %s\n\nMembers:\n", Units[unitid][unitCallSign]);
  116. foreach( new i: Player )
  117. {
  118. if(!UnitSystemAccess(i)) continue;
  119. if(PlayerInfo[i][pUnit] != unitid) continue;
  120. if(GetUnitLeader(unitid) == i) format(unitinfostr, sizeof(unitinfostr), "%s%s (LEADER)\n", unitinfostr, PlayerICName(i));
  121. else format(unitinfostr, sizeof(unitinfostr), "%s%s\n", unitinfostr, PlayerICName(i));
  122. }
  123. if(!join) ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "My Unit", unitinfostr, "Done", "");
  124. else
  125. {
  126. format(unitsmsg, sizeof(unitsmsg), "%s Unit", Units[unitid][unitCallSign]);
  127. ShowPlayerDialog(playerid, DIALOG_UNITS_JOIN, DIALOG_STYLE_MSGBOX, unitsmsg, unitinfostr, "Join", "Cancel");
  128. }
  129. return 1;
  130. }
  131. CMD:units(playerid, params[])
  132. {
  133. if(!UnitSystemAccess(playerid)) return AdmErrorMsg;
  134. if(PlayerInfo[playerid][pMember] == FACTION_SAPD || FakeFaction[playerid] == FACTION_SAPD) format(unitsmsg, sizeof(unitsmsg), "Units Database - SAPD Units %d/%d", pdunits, MAX_UNITS_PER_FACTION);
  135. else if(PlayerInfo[playerid][pMember] == FACTION_FMD || FakeFaction[playerid] == FACTION_FMD) format(unitsmsg, sizeof(unitsmsg), "Units Database - SAFMD Units %d/%d", fmdunits, MAX_UNITS_PER_FACTION);
  136. if(findingunit[playerid] == -1)
  137. {
  138. ShowPlayerDialog(playerid, DIALOG_UNITS_MAIN, DIALOG_STYLE_LIST, unitsmsg, "Show All Units\nCreate Unit\nDisband My Unit\nMy Unit\nCallsign\nDisband Unit (High Commands)\nLeave Unit\nFind Unit", "Select", "Cancel");
  139. }
  140. else
  141. {
  142. ShowPlayerDialog(playerid, DIALOG_UNITS_MAIN, DIALOG_STYLE_LIST, unitsmsg, "Show All Units\nCreate Unit\nDisband My Unit\nMy Unit\nCallsign\nDisband Unit (High Commands)\nLeave Unit\nStop Tracking", "Select", "Cancel");
  143. }
  144. return 1;
  145. }
  146. Hook:units_OnPlayerDisconnect(playerid, reason)
  147. {
  148. new unitid = PlayerInfo[playerid][pUnit];
  149. if(unitid != -1)
  150. {
  151. if(Units[unitid][unitLeader] == playerid) // if leader left, find new one
  152. {
  153. new newleader = -1;
  154. foreach( new i: Player )
  155. {
  156. if(PlayerInfo[i][pUnit] != unitid) continue;
  157. if(i == playerid) continue;
  158. newleader = i;
  159. }
  160. if(newleader == -1) DisbandUnit(unitid); // if no new leader was found, disband unit
  161. else Units[unitid][unitLeader] = newleader; // if new leader was found, make him the leader
  162. }
  163. }
  164. return 1;
  165. }
  166. Hook:units_OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
  167. {
  168. if(dialogid == DIALOG_UNITS_MAIN)
  169. {
  170. if(response)
  171. {
  172. switch(listitem)
  173. {
  174. case 0: ShowPlayerUnits(playerid); // show all units
  175. case 1: // show create dialog of a unit (ask him of the name/the callsign of the unit)
  176. {
  177. if(PlayerInfo[playerid][pUnit] != -1) return SendClientMessage(playerid, COLOR_GREY, "You are already in a unit.");
  178. if((PlayerInfo[playerid][pMember] == FACTION_SAPD || FakeFaction[playerid] == FACTION_SAPD) && pdunits == MAX_UNITS_PER_FACTION) return SendClientMessage(playerid, COLOR_GREY, "Your faction has reached the maximum units.");
  179. else if((PlayerInfo[playerid][pMember] == FACTION_FMD || FakeFaction[playerid] == FACTION_FMD) && fmdunits == MAX_UNITS_PER_FACTION) return SendClientMessage(playerid, COLOR_GREY, "Your faction has reached the maximum units.");
  180. ShowPlayerDialog(playerid, DIALOG_UNITS_CREATE, DIALOG_STYLE_INPUT, "Unit Creation - Callsign", "Please enter a name (callsign) for your unit", "Create", "Cancel");
  181. }
  182. case 2: // disband his own unit
  183. {
  184. if(PlayerInfo[playerid][pUnit] == -1) return SendClientMessage(playerid, COLOR_GREY, "You are not in a unit.");
  185. if(GetUnitLeader(PlayerInfo[playerid][pUnit]) != playerid) return SendClientMessage(playerid, COLOR_GREY, "You are not the leader of your unit.");
  186. DisbandUnit(PlayerInfo[playerid][pUnit]);
  187. }
  188. case 3: // display the player's unit info
  189. {
  190. if(PlayerInfo[playerid][pUnit] == -1) return SendClientMessage(playerid, COLOR_GREY, "You are not in a unit.");
  191. ShowPlayerUnitInfo(playerid, PlayerInfo[playerid][pUnit]);
  192. }
  193. case 4: // attach callsign
  194. {
  195. if(PlayerInfo[playerid][pUnit] == -1) SendClientMessage(playerid, COLOR_GREY, "You are not in a unit.");
  196. new vehicleid = GetPlayerVehicleID(playerid);
  197. new dynvehID = GetDynamicVehicleID(vehicleid);
  198. if( sVehicleInfo[dynvehID][v_faction] < 1 ) return SendClientMessage( playerid, COLOR_GREY, "This isn't a faction owned vehicle." );
  199. Delete3DTextLabel(UnitsCallSign[vehicleid]);
  200. UnitsCallSign[vehicleid] = Create3DTextLabel(Units[PlayerInfo[playerid][pUnit]][unitCallSign], 0x33CCFFFF, 0.0, 0.0, 0.0, 10.0, 0, 1 );
  201. Attach3DTextLabelToVehicle(UnitsCallSign[vehicleid], vehicleid, 0, -2.1, -0.3);
  202. SendClientMessage(playerid, COLOR_WHITE, "Callsign attached. Use /dcallsign to remove it. (( Any abusive words will result to OOC punishment. ))");
  203. }
  204. case 5: // disband a unit (only hcs, can choose any unit)
  205. {
  206. if(PlayerInfo[playerid][pRank] < 3 || PlayerInfo[playerid][pMember] == 11) return SendClientMessage(playerid, COLOR_GREY, "Only R3+ can use this."); // both pd and fmd rank restrictions is 3, so here we only check for the rank and not the faction. Added S9 as they can't be R3s and therefore this feature is disabled for them
  207. new facid = PlayerInfo[playerid][pMember];
  208. new unitsstr[1500], headers[] = "Callsign\tLeader\tMembers\n";
  209. new unitexists;
  210. for(new i = 0; i < MAX_UNITS; i++)
  211. {
  212. if(!Units[i][unitActive]) continue;
  213. if(Units[i][unitFaction] != facid && Units[i][unitFaction] != FakeFaction[playerid]) continue;
  214. format(unitsstr, sizeof(unitsstr), "%s%s\t%s\t%d\n", unitsstr, Units[i][unitCallSign], PlayerICName(Units[i][unitLeader]), GetUnitMembers(i));
  215. unitexists = 1;
  216. }
  217. format(unitsstr, sizeof(unitsstr), "%s%s", headers, unitsstr);
  218. if(unitexists == 1) ShowPlayerDialog(playerid, DIALOG_UNITS_DISBAND, DIALOG_STYLE_TABLIST_HEADERS, "Available Units", unitsstr, "Disband", "Cancel"); // make sure theres units
  219. }
  220. case 6: // leave unit
  221. {
  222. new unitid = PlayerInfo[playerid][pUnit];
  223. if(unitid == -1) return SendClientMessage(playerid, COLOR_GREY, "You are not in a unit.");
  224. format(unitsmsg, sizeof(unitsmsg), "You have left unit '%s'.", Units[unitid][unitCallSign]);
  225. SendClientMessage(playerid, COLOR_GREY, unitsmsg);
  226. if(Units[unitid][unitLeader] == playerid) // if leader left, find new one
  227. {
  228. new newleader = -1;
  229. foreach( new i: Player )
  230. {
  231. if(PlayerInfo[i][pUnit] != unitid) continue;
  232. if(i == playerid) continue;
  233. newleader = i;
  234. }
  235. if(newleader == -1) DisbandUnit(unitid); // if no new leader was found, disband unit
  236. else Units[unitid][unitLeader] = newleader; // if new leader was found, make him the leader
  237. }
  238. PlayerInfo[playerid][pUnit] = -1;
  239. }
  240. case 7: // find unit
  241. {
  242. if(findingunit[playerid] == -1)
  243. {
  244. new facid = PlayerInfo[playerid][pMember];
  245. new unitsstr[1500], headers[] = "Callsign\tLeader\tMembers\n";
  246. new unitexists;
  247. for(new i = 0; i < MAX_UNITS; i++)
  248. {
  249. if(!Units[i][unitActive]) continue;
  250. if(Units[i][unitFaction] != facid && Units[i][unitFaction] != FakeFaction[playerid]) continue;
  251. format(unitsstr, sizeof(unitsstr), "%s%s\t%s\t%d\n", unitsstr, Units[i][unitCallSign], PlayerICName(Units[i][unitLeader]), GetUnitMembers(i));
  252. unitexists = 1;
  253. }
  254. format(unitsstr, sizeof(unitsstr), "%s%s", headers, unitsstr);
  255. if(unitexists == 1) ShowPlayerDialog(playerid, DIALOG_UNITS_FIND, DIALOG_STYLE_TABLIST_HEADERS, "Available Units", unitsstr, "Find", "Cancel");
  256. }
  257. else
  258. {
  259. foreach( new i: Player )
  260. {
  261. if(PlayerInfo[i][pUnit] != findingunit[playerid]) continue;
  262. if(PlayerInfo[i][pMember] == FACTION_SAPD || FakeFaction[playerid] == FACTION_SAPD) SetPlayerMarkerForPlayer(playerid, i, TCOLOR_BLUE);
  263. else if(PlayerInfo[i][pMember] == FACTION_FMD || FakeFaction[playerid] == FACTION_FMD) SetPlayerMarkerForPlayer(playerid, i, TCOLOR_PARAMEDIC);
  264. SetPlayerToTeamColor(i);
  265. }
  266. format(unitsmsg, sizeof(unitsmsg), "You have stopped tracking unit '%s'.", Units[findingunit[playerid]][unitCallSign]);
  267. SendClientMessage(playerid, COLOR_GREY, unitsmsg);
  268. findingunit[playerid] = -1;
  269. }
  270. }
  271. }
  272. }
  273. }
  274. if(dialogid == DIALOG_UNITS_CREATE)
  275. {
  276. if(response)
  277. {
  278. if(strlen(inputtext) < 5 || strlen(inputtext) > 20)
  279. {
  280. SendClientMessage(playerid, COLOR_GREY, "The length of the name/callsign must be between 5 and 20 characters");
  281. ShowPlayerDialog(playerid, DIALOG_UNITS_CREATE, DIALOG_STYLE_INPUT, "Unit Creation - Callsign", "Please enter a name (callsign) for your unit", "Create", "Cancel");
  282. return 1;
  283. }
  284. else
  285. {
  286. new input[20];
  287. format(input, 20, "%s", inputtext);
  288. CreateUnit(playerid, input);
  289. format(unitsmsg, sizeof(unitsmsg), "You have successfully created the unit '%s'.", input);
  290. SendClientMessage(playerid, COLOR_LIGHTBLUE, unitsmsg);
  291. }
  292. }
  293. }
  294. if(dialogid == DIALOG_UNITS_SHOW)
  295. {
  296. if(response)
  297. {
  298. new counter, unitid;
  299. for(new i = 0; i < MAX_UNITS; i++)
  300. {
  301. if(!Units[i][unitActive]) continue;
  302. if(Units[i][unitFaction] != PlayerInfo[playerid][pMember] && Units[i][unitFaction] != FakeFaction[playerid]) continue;
  303. if(counter == listitem)
  304. {
  305. unitid = i;
  306. joiningunit[playerid] = unitid;
  307. break;
  308. }
  309. counter++;
  310. }
  311. ShowPlayerUnitInfo(playerid, unitid, 1);
  312. }
  313. }
  314. if(dialogid == DIALOG_UNITS_JOIN)
  315. {
  316. if(response)
  317. {
  318. new unitid = joiningunit[playerid];
  319. if(PlayerInfo[playerid][pUnit] != -1) return SendClientMessage(playerid, COLOR_GREY, "You are already in a unit.");
  320. if(GetUnitMembers(unitid) == 4) return SendClientMessage(playerid, COLOR_GREY, "This unit already reached the maximum members (4).");
  321. PlayerInfo[playerid][pUnit] = unitid;
  322. format(unitsmsg, sizeof(unitsmsg), "You have joined the unit '%s'.", Units[unitid][unitCallSign]);
  323. SendClientMessage(playerid, COLOR_LIGHTBLUE, unitsmsg);
  324. }
  325. }
  326. if(dialogid == DIALOG_UNITS_DISBAND)
  327. {
  328. if(response)
  329. {
  330. new counter, unitid;
  331. for(new i = 0; i < MAX_UNITS; i++)
  332. {
  333. if(!Units[i][unitActive]) continue;
  334. if(Units[i][unitFaction] != PlayerInfo[playerid][pMember] && Units[i][unitFaction] != FakeFaction[playerid]) continue;
  335. if(counter == listitem)
  336. {
  337. unitid = i;
  338. break;
  339. }
  340. counter++;
  341. }
  342. DisbandUnit(unitid);
  343. }
  344. }
  345. if(dialogid == DIALOG_UNITS_FIND)
  346. {
  347. if(response)
  348. {
  349. new counter, unitid;
  350. for(new i = 0; i < MAX_UNITS; i++)
  351. {
  352. if(!Units[i][unitActive]) continue;
  353. if(Units[i][unitFaction] != PlayerInfo[playerid][pMember] && Units[i][unitFaction] != FakeFaction[playerid]) continue;
  354. if(counter == listitem)
  355. {
  356. unitid = i;
  357. break;
  358. }
  359. counter++;
  360. }
  361. foreach( new i: Player )
  362. {
  363. if(PlayerInfo[i][pMember] != PlayerInfo[playerid][pMember] && PlayerInfo[i][pMember] != FakeFaction[playerid]) continue;
  364. if(PlayerInfo[i][pUnit] != unitid) continue;
  365. if(toggedRadio[i]) continue;
  366. if(PlayerInfo[i][pMember] == FACTION_SAPD || FakeFaction[i] == FACTION_SAPD) SetPlayerMarkerForPlayer(playerid, i, GPSCOLOR_SAPD);
  367. else if(PlayerInfo[i][pMember] == FACTION_FMD || FakeFaction[i] == FACTION_FMD) SetPlayerMarkerForPlayer(playerid, i, GPSCOLOR_LSFMD);
  368. }
  369. findingunit[playerid] = unitid;
  370. format(unitsmsg, sizeof(unitsmsg), "You are now tracking unit '%s'", Units[findingunit[playerid]][unitCallSign]);
  371. SendClientMessage(playerid, COLOR_GREY, unitsmsg);
  372. }
  373. }
  374. return 1;
  375. }