Advertisement
Guest User

Untitled

a guest
Aug 28th, 2016
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.78 KB | None | 0 0
  1. #include <a_samp>
  2. #include <foreach> // by Kar - http://forum.sa-mp.com/showthread.php?t=570868
  3. #include <izcmd> // by Yashas - http://forum.sa-mp.com/showthread.php?t=576114
  4.  
  5. #define MAX_DROPS (50)
  6. #define DIST (300.0)
  7.  
  8. // Config
  9. #define PLANE_TIME (7) // how many seconds does a plane need before flying (Default: 7)
  10. #define REQ_COOLDOWN (15) // how many minutes does someone need to wait for requesting a supply drop again (Default: 3)
  11. #define DROP_LIFE (5) // life time of a supply drop, in minutes (Default: 5)
  12. #define AMMO_PRICE (750) // price of ammo request (Default: 750)
  13. #define HEALTH_PRICE (500) // price of health kit request (Default: 500)
  14. #define ARMOR_PRICE (450) // price of body armor request (Default: 450)
  15. #define AMMO_AMOUNT (150) // how much ammo will be given with a weapon/ammo drop (Default: 150)
  16.  
  17. enum _:E_DROPTYPE
  18. {
  19. DROP_TYPE_WEAPON,
  20. DROP_TYPE_AMMO,
  21. DROP_TYPE_HEALTH,
  22. DROP_TYPE_ARMOR
  23. }
  24.  
  25. enum _:E_DROPDIALOG
  26. {
  27. DIALOG_DROP_MENU,
  28. DIALOG_DROP_WEAPONS,
  29. DIALOG_DROP_CONFIRM
  30. }
  31.  
  32. enum E_WEPDATA
  33. {
  34. weaponID,
  35. weaponPrice
  36. }
  37.  
  38. enum E_DROP
  39. {
  40. // objects
  41. planeObj,
  42. boxObj,
  43. paraObj,
  44. // pickup (created after drop is done)
  45. dropPickup,
  46. // label
  47. Text3D: dropLabel,
  48. // drop data
  49. dropType,
  50. dropData,
  51. // timer
  52. dropTimer,
  53. // other
  54. requestedBy
  55. }
  56.  
  57. new
  58. SupplyData[MAX_DROPS][E_DROP],
  59. Iterator: SupplyDrops<MAX_DROPS>;
  60.  
  61. new
  62. AvailableWeapons[][E_WEPDATA] = {
  63. // weapon id, price
  64. // you can get weapon ids from here: https://wiki.sa-mp.com/wiki/Weapons
  65. {WEAPON_SHOTGUN, 300},
  66. {WEAPON_SAWEDOFF, 130},
  67. {WEAPON_AK47, 500},
  68. {WEAPON_MINIGUN, 5000000}
  69. };
  70. stock Float: GetPointZPos(const Float: fX, const Float: fY, &Float: fZ = 0.0) {
  71. if(!((-3000.0 < fX < 3000.0) && (-3000.0 < fY < 3000.0))) {
  72. return 0.0;
  73. }
  74. static
  75. File: s_hMap
  76. ;
  77. if(!s_hMap) {
  78. s_hMap = fopen("SAfull.hmap", io_read);
  79.  
  80. if(!s_hMap) {
  81. return 0.0;
  82. }
  83. }
  84. new
  85. afZ[1]
  86. ;
  87. fseek(s_hMap, ((6000 * (-floatround(fY, floatround_tozero) + 3000) + (floatround(fX, floatround_tozero) + 3000)) << 1));
  88. fblockread(s_hMap, afZ);
  89.  
  90. return (fZ = ((afZ[0] >>> 16) * 0.01));
  91. }
  92.  
  93. formatInt(intVariable, iThousandSeparator = ',', iCurrencyChar = '$')
  94. {
  95. /*
  96. By Kar
  97. https://gist.github.com/Kar2k/bfb0eafb2caf71a1237b349684e091b9/8849dad7baa863afb1048f40badd103567c005a5#file-formatint-function
  98. */
  99. static
  100. s_szReturn[ 32 ],
  101. s_szThousandSeparator[ 2 ] = { ' ', EOS },
  102. s_szCurrencyChar[ 2 ] = { ' ', EOS },
  103. s_iVariableLen,
  104. s_iChar,
  105. s_iSepPos,
  106. bool:s_isNegative
  107. ;
  108.  
  109. format( s_szReturn, sizeof( s_szReturn ), "%d", intVariable );
  110.  
  111. if(s_szReturn[0] == '-')
  112. s_isNegative = true;
  113. else
  114. s_isNegative = false;
  115.  
  116. s_iVariableLen = strlen( s_szReturn );
  117.  
  118. if ( s_iVariableLen >= 4 && iThousandSeparator)
  119. {
  120. s_szThousandSeparator[ 0 ] = iThousandSeparator;
  121.  
  122. s_iChar = s_iVariableLen;
  123. s_iSepPos = 0;
  124.  
  125. while ( --s_iChar > _:s_isNegative )
  126. {
  127. if ( ++s_iSepPos == 3 )
  128. {
  129. strins( s_szReturn, s_szThousandSeparator, s_iChar );
  130.  
  131. s_iSepPos = 0;
  132. }
  133. }
  134. }
  135. if(iCurrencyChar) {
  136. s_szCurrencyChar[ 0 ] = iCurrencyChar;
  137. strins( s_szReturn, s_szCurrencyChar, _:s_isNegative );
  138. }
  139. return s_szReturn;
  140. }
  141.  
  142. ConvertToMinutes(time)
  143. {
  144. // http://forum.sa-mp.com/showpost.php?p=3223897&postcount=11
  145. new string[15];//-2000000000:00 could happen, so make the string 15 chars to avoid any errors
  146. format(string, sizeof(string), "%02d:%02d", time / 60, time % 60);
  147. return string;
  148. }
  149.  
  150. GetWeaponModel(weaponid)
  151. {
  152. switch(weaponid)
  153. {
  154. case 1: return 331;
  155. case 2..8: return weaponid+331;
  156. case 9: return 341;
  157. case 10..15: return weaponid+311;
  158. case 16..18: return weaponid+326;
  159. case 22..29: return weaponid+324;
  160. case 30,31: return weaponid+325;
  161. case 32: return 372;
  162. case 33..45: return weaponid+324;
  163. case 46: return 371;
  164. }
  165.  
  166. return 18631;
  167. }
  168.  
  169. ReturnDropPickupModel(id)
  170. {
  171. new model = 18631;
  172.  
  173. switch(SupplyData[id][dropType])
  174. {
  175. case DROP_TYPE_WEAPON: model = GetWeaponModel(SupplyData[id][dropData]);
  176. case DROP_TYPE_AMMO: model = 19832;
  177. case DROP_TYPE_HEALTH: model = 11738;
  178. case DROP_TYPE_ARMOR: model = 1242;
  179. }
  180.  
  181. return model;
  182. }
  183.  
  184. ShowDropMenu(playerid)
  185. {
  186. new string[128];
  187. format(string, sizeof(string), "Request Weapons\t\nRequest Ammo\t{2ECC71}%s\nRequest Health Kit\t{2ECC71}%s\nRequest Body Armor\t{2ECC71}%s", formatInt(AMMO_PRICE), formatInt(HEALTH_PRICE), formatInt(ARMOR_PRICE));
  188. ShowPlayerDialog(playerid, DIALOG_DROP_MENU, DIALOG_STYLE_TABLIST, "Supply Drop", string, "Request", "Close");
  189. return 1;
  190. }
  191.  
  192. ShowWeaponsMenu(playerid)
  193. {
  194. new string[512], wname[24];
  195. format(string, sizeof(string), "Weapon\tPrice\n");
  196.  
  197. for(new i; i < sizeof(AvailableWeapons); i++)
  198. {
  199. GetWeaponName(AvailableWeapons[i][weaponID], wname, sizeof(wname));
  200. format(string, sizeof(string), "%s%s\t{2ECC71}%s\n", string, wname, formatInt(AvailableWeapons[i][weaponPrice]));
  201. }
  202.  
  203. ShowPlayerDialog(playerid, DIALOG_DROP_WEAPONS, DIALOG_STYLE_TABLIST_HEADERS, "Supply Drop ยป {FFFFFF}Weapons", string, "Request", "Back");
  204. return 1;
  205. }
  206.  
  207. ShowConfirmDialog(playerid)
  208. {
  209. if(GetPVarInt(playerid, "supply_Price") > GetPlayerMoney(playerid)) return 1;
  210. new string[128];
  211.  
  212. switch(GetPVarInt(playerid, "supply_ReqType"))
  213. {
  214. case DROP_TYPE_WEAPON:
  215. {
  216. new wname[24];
  217. GetWeaponName(AvailableWeapons[ GetPVarInt(playerid, "supply_WepIndex") ][weaponID], wname, sizeof(wname));
  218. format(string, sizeof(string), "{FFFFFF}You're about to order a supply drop for {F1C40F}%s.\n\n{FFFFFF}Price: {2ECC71}%s", wname, formatInt(GetPVarInt(playerid, "supply_Price")));
  219. }
  220.  
  221. case DROP_TYPE_AMMO:
  222. {
  223. format(string, sizeof(string), "{FFFFFF}You're about to order a supply drop for {F1C40F}Ammo.\n\n{FFFFFF}Price: {2ECC71}%s", formatInt(GetPVarInt(playerid, "supply_Price")));
  224. }
  225.  
  226. case DROP_TYPE_HEALTH:
  227. {
  228. format(string, sizeof(string), "{FFFFFF}You're about to order a supply drop for {F1C40F}Health Kit.\n\n{FFFFFF}Price: {2ECC71}%s", formatInt(GetPVarInt(playerid, "supply_Price")));
  229. }
  230.  
  231. case DROP_TYPE_ARMOR:
  232. {
  233. format(string, sizeof(string), "{FFFFFF}You're about to order a supply drop for {F1C40F}Body Armor.\n\n{FFFFFF}Price: {2ECC71}%s", formatInt(GetPVarInt(playerid, "supply_Price")));
  234. }
  235. }
  236.  
  237. ShowPlayerDialog(playerid, DIALOG_DROP_CONFIRM, DIALOG_STYLE_MSGBOX, "Supply Drop ยป {FFFFFF}Confirmation", string, "Confirm", "Cancel");
  238. return 1;
  239. }
  240.  
  241. public OnFilterScriptInit()
  242. {
  243. for(new i; i < MAX_DROPS; i++)
  244. {
  245. SupplyData[i][planeObj] = SupplyData[i][boxObj] = SupplyData[i][paraObj] = SupplyData[i][dropPickup] = SupplyData[i][dropTimer] = SupplyData[i][requestedBy] = -1;
  246. SupplyData[i][dropLabel] = Text3D: -1;
  247. }
  248.  
  249. return 1;
  250. }
  251.  
  252. public OnFilterScriptExit()
  253. {
  254. foreach(new i : SupplyDrops)
  255. {
  256. if(IsValidObject(SupplyData[i][planeObj])) DestroyObject(SupplyData[i][planeObj]);
  257. if(IsValidObject(SupplyData[i][boxObj])) DestroyObject(SupplyData[i][boxObj]);
  258. if(IsValidObject(SupplyData[i][paraObj])) DestroyObject(SupplyData[i][paraObj]);
  259.  
  260. if(SupplyData[i][dropPickup] != -1) DestroyPickup(SupplyData[i][dropPickup]);
  261. if(SupplyData[i][dropTimer] != -1) KillTimer(SupplyData[i][dropTimer]);
  262. if(SupplyData[i][dropLabel] != Text3D: -1) Delete3DTextLabel(SupplyData[i][dropLabel]);
  263. }
  264.  
  265. return 1;
  266. }
  267.  
  268. public OnPlayerDisconnect(playerid, reason)
  269. {
  270. foreach(new i : SupplyDrops) if(SupplyData[i][requestedBy] == playerid) SupplyData[i][requestedBy] = -1;
  271. return 1;
  272. }
  273.  
  274. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
  275. {
  276. switch(dialogid)
  277. {
  278. case DIALOG_DROP_MENU:
  279. {
  280. if(!response) return 1;
  281. SetPVarInt(playerid, "supply_ReqType", listitem);
  282.  
  283. if(listitem == 0) {
  284. ShowWeaponsMenu(playerid);
  285. }else{
  286. new price;
  287. switch(listitem)
  288. {
  289. case DROP_TYPE_AMMO: price = AMMO_PRICE;
  290. case DROP_TYPE_HEALTH: price = HEALTH_PRICE;
  291. case DROP_TYPE_ARMOR: price = ARMOR_PRICE;
  292. }
  293.  
  294. if(price > GetPlayerMoney(playerid))
  295. {
  296. SendClientMessage(playerid, 0xE74C3CFF, "ERROR: {FFFFFF}You can't afford this request.");
  297. return ShowDropMenu(playerid);
  298. }
  299.  
  300. SetPVarInt(playerid, "supply_Price", price);
  301. ShowConfirmDialog(playerid);
  302. }
  303.  
  304. return 1;
  305. }
  306.  
  307. case DIALOG_DROP_WEAPONS:
  308. {
  309. if(!response) return ShowDropMenu(playerid);
  310. new price = AvailableWeapons[listitem][weaponPrice];
  311. if(price > GetPlayerMoney(playerid))
  312. {
  313. SendClientMessage(playerid, 0xE74C3CFF, "ERROR: {FFFFFF}You can't afford this weapon.");
  314. return ShowWeaponsMenu(playerid);
  315. }
  316.  
  317. SetPVarInt(playerid, "supply_WepIndex", listitem);
  318. SetPVarInt(playerid, "supply_Price", price);
  319. ShowConfirmDialog(playerid);
  320. return 1;
  321. }
  322.  
  323. case DIALOG_DROP_CONFIRM:
  324. {
  325. if(!response) return ShowDropMenu(playerid);
  326. new price = GetPVarInt(playerid, "supply_Price");
  327. if(price > GetPlayerMoney(playerid)) return SendClientMessage(playerid, 0xE74C3CFF, "ERROR: {FFFFFF}You can't afford this drop.");
  328. new cooldown = GetPVarInt(playerid, "supply_Cooldown");
  329. if(cooldown > gettime())
  330. {
  331. new string[72];
  332. format(string, sizeof(string), "ERROR: {FFFFFF}Please wait %s more to request a supply drop again.", ConvertToMinutes(cooldown - gettime()));
  333. return SendClientMessage(playerid, 0xE74C3CFF, string);
  334. }
  335.  
  336. new id = Iter_Free(SupplyDrops);
  337. if(id == -1) return SendClientMessage(playerid, 0xE74C3CFF, "ERROR: {FFFFFF}You can't request a supply drop right now.");
  338. GivePlayerMoney(playerid, -price);
  339.  
  340. new Float: x, Float: y, Float: z;
  341. GetPlayerPos(playerid, x, y, z);
  342. GetPointZPos(x, y, z);
  343.  
  344. SupplyData[id][requestedBy] = playerid;
  345. SupplyData[id][dropType] = GetPVarInt(playerid, "supply_ReqType");
  346. SupplyData[id][dropData] = AvailableWeapons[ GetPVarInt(playerid, "supply_WepIndex") ][weaponID];
  347. SupplyData[id][dropTimer] = SetTimerEx("FlyPlane", PLANE_TIME * 1000, false, "ifffi", id, x, y, z, random(360));
  348. Iter_Add(SupplyDrops, id);
  349.  
  350. SendClientMessage(playerid, 0x3498DBFF, "PILOT: {FFFFFF}Request received.");
  351. SetPVarInt(playerid, "supply_Cooldown", gettime() + REQ_COOLDOWN * 60);
  352. return 1;
  353. }
  354. }
  355.  
  356. return 0;
  357. }
  358.  
  359. public OnObjectMoved(objectid)
  360. {
  361. switch(GetObjectModel(objectid))
  362. {
  363. case 1681:
  364. {
  365. // it's a plane, validate it & remove
  366. foreach(new i : SupplyDrops)
  367. {
  368. if(SupplyData[i][planeObj] == objectid)
  369. {
  370. DestroyObject(SupplyData[i][planeObj]);
  371. SupplyData[i][planeObj] = -1;
  372. break;
  373. }
  374. }
  375. }
  376.  
  377. case 2975:
  378. {
  379. // it's a supply drop, validate it, create pickup then remove
  380. foreach(new i : SupplyDrops)
  381. {
  382. if(SupplyData[i][boxObj] == objectid)
  383. {
  384. new Float: x, Float: y, Float: z, string[48];
  385. switch(SupplyData[i][dropType])
  386. {
  387. case DROP_TYPE_WEAPON:
  388. {
  389. new weap_name[24];
  390. GetWeaponName(SupplyData[i][dropData], weap_name, sizeof(weap_name));
  391. format(string, sizeof(string), "Supply Drop\n\n{FFFFFF}%s", weap_name);
  392. }
  393.  
  394. case DROP_TYPE_AMMO: format(string, sizeof(string), "Supply Drop\n\n{FFFFFF}Ammo");
  395. case DROP_TYPE_HEALTH: format(string, sizeof(string), "Supply Drop\n\n{FFFFFF}Health");
  396. case DROP_TYPE_ARMOR: format(string, sizeof(string), "Supply Drop\n\n{FFFFFF}Body Armor");
  397. }
  398.  
  399. GetObjectPos(objectid, x, y, z);
  400. SupplyData[i][dropPickup] = CreatePickup(ReturnDropPickupModel(i), 1, x, y, z + 0.85);
  401. SupplyData[i][dropLabel] = Create3DTextLabel(string, 0xF1C40FFF, x, y, z + 1.65, 10.0, 0, 1);
  402.  
  403. DestroyObject(SupplyData[i][paraObj]);
  404. DestroyObject(SupplyData[i][boxObj]);
  405. SupplyData[i][boxObj] = SupplyData[i][paraObj] = -1;
  406. SupplyData[i][dropTimer] = SetTimerEx("RemoveDrop", DROP_LIFE * 60000, false, "i", i);
  407.  
  408. if(IsPlayerConnected(SupplyData[i][requestedBy])) SendClientMessage(SupplyData[i][requestedBy], 0x3498DBFF, "SUPPLY DROP: {FFFFFF}Drop complete.");
  409. break;
  410. }
  411. }
  412. }
  413. }
  414.  
  415. return 1;
  416. }
  417.  
  418. public OnPlayerPickUpPickup(playerid, pickupid)
  419. {
  420. foreach(new i : SupplyDrops)
  421. {
  422. if(pickupid == SupplyData[i][dropPickup])
  423. {
  424. switch(SupplyData[i][dropType])
  425. {
  426. case DROP_TYPE_WEAPON: GivePlayerWeapon(playerid, SupplyData[i][dropData], AMMO_AMOUNT);
  427.  
  428. case DROP_TYPE_AMMO:
  429. {
  430. new weapon, ammo;
  431. for(new x = 2; x <= 7; x++)
  432. {
  433. GetPlayerWeaponData(playerid, x, weapon, ammo);
  434. SetPlayerAmmo(playerid, weapon, ammo + AMMO_AMOUNT);
  435. }
  436. }
  437.  
  438. case DROP_TYPE_HEALTH: SetPlayerHealth(playerid, 100.0);
  439. case DROP_TYPE_ARMOR: SetPlayerArmour(playerid, 100.0);
  440. }
  441.  
  442. DestroyPickup(SupplyData[i][dropPickup]);
  443. Delete3DTextLabel(SupplyData[i][dropLabel]);
  444. KillTimer(SupplyData[i][dropTimer]);
  445.  
  446. SupplyData[i][dropPickup] = SupplyData[i][requestedBy] = SupplyData[i][dropTimer] = -1;
  447. SupplyData[i][dropLabel] = Text3D: -1;
  448.  
  449. new next;
  450. Iter_SafeRemove(SupplyDrops, i, next);
  451. break;
  452. }
  453. }
  454.  
  455. return 1;
  456. }
  457.  
  458. forward FlyPlane(id, Float: x, Float: y, Float: z, angle);
  459. public FlyPlane(id, Float: x, Float: y, Float: z, angle)
  460. {
  461. SupplyData[id][planeObj] = CreateObject(1681, x + (DIST * -floatsin(-angle, degrees)), y + (DIST * -floatcos(-angle, degrees)), z + 75.0, 0.0, 0.0, angle);
  462. new time = MoveObject(SupplyData[id][planeObj], x + (DIST * floatsin(-angle, degrees)), y + (DIST * floatcos(-angle, degrees)), z + 75.0, 60.0);
  463.  
  464. SupplyData[id][dropTimer] = SetTimerEx("MakeDrop", floatround(time / 2.5), false, "ifff", id, x, y, z);
  465.  
  466. if(IsPlayerConnected(SupplyData[id][requestedBy])) SendClientMessage(SupplyData[id][requestedBy], 0x3498DBFF, "PILOT: {FFFFFF}I'm getting close.");
  467. return 1;
  468. }
  469.  
  470. forward MakeDrop(id, Float: x, Float: y, Float: z);
  471. public MakeDrop(id, Float: x, Float: y, Float: z)
  472. {
  473. new Float: plx, Float: ply, Float: plz;
  474. GetObjectPos(SupplyData[id][planeObj], plx, ply, plz);
  475.  
  476. SupplyData[id][boxObj] = CreateObject(2975, plx, ply, plz - 15.0, 0.0, 0.0, 0.0);
  477. SupplyData[id][paraObj] = CreateObject(18849, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  478. SetObjectMaterial(SupplyData[id][paraObj], 2, 19478, "signsurf", "sign", 0xFFFFFFFF);
  479. AttachObjectToObject(SupplyData[id][paraObj], SupplyData[id][boxObj], 0.0, -0.05, 7.5, 0.0, 0.0, 0.0);
  480. MoveObject(SupplyData[id][boxObj], x, y, z, 8.0);
  481.  
  482. if(IsPlayerConnected(SupplyData[id][requestedBy])) SendClientMessage(SupplyData[id][requestedBy], 0x3498DBFF, "PILOT: {FFFFFF}Supplies dropped.");
  483. return 1;
  484. }
  485.  
  486. forward RemoveDrop(id);
  487. public RemoveDrop(id)
  488. {
  489. DestroyPickup(SupplyData[id][dropPickup]);
  490. Delete3DTextLabel(SupplyData[id][dropLabel]);
  491.  
  492. SupplyData[id][dropPickup] = SupplyData[id][requestedBy] = SupplyData[id][dropTimer] = -1;
  493. SupplyData[id][dropLabel] = Text3D: -1;
  494.  
  495. Iter_Remove(SupplyDrops, id);
  496. return 1;
  497. }
  498.  
  499. CMD:drop(playerid, params[])
  500. {
  501. if(IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, 0xE74C3CFF, "ERROR: {FFFFFF}You can't use this command in a vehicle.");
  502. new cooldown = GetPVarInt(playerid, "supply_Cooldown");
  503. if(cooldown > gettime())
  504. {
  505. new string[72];
  506. format(string, sizeof(string), "ERROR: {FFFFFF}Please wait %s more to request a supply drop again.", ConvertToMinutes(cooldown - gettime()));
  507. return SendClientMessage(playerid, 0xE74C3CFF, string);
  508. }
  509.  
  510. ShowDropMenu(playerid);
  511. return 1;
  512. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement