lselevator.pwn 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. /*
  2. /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$$
  3. | $$$ | $$ /$$__ $$ | $$__ $$| $$__ $$
  4. | $$$$| $$| $$ \__/ | $$ \ $$| $$ \ $$
  5. | $$ $$ $$| $$ /$$$$ /$$$$$$| $$$$$$$/| $$$$$$$/
  6. | $$ $$$$| $$|_ $$|______/| $$__ $$| $$____/
  7. | $$\ $$$| $$ \ $$ | $$ \ $$| $$
  8. | $$ \ $$| $$$$$$/ | $$ | $$| $$
  9. |__/ \__/ \______/ |__/ |__/|__/
  10. LS Elevator
  11. Next Generation Gaming, LLC
  12. (created by Next Generation Gaming Development Team)
  13. * Copyright (c) 2016, Next Generation Gaming, LLC
  14. *
  15. * All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without modification,
  18. * are not permitted in any case.
  19. *
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  25. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. //Leave this here
  34. new Float:FloorZOffsets[21] =
  35. {
  36. 0.0, // 0.0,
  37. 8.5479, // 8.5479,
  38. 13.99945, // 8.5479 + (5.45155 * 1.0),
  39. 19.45100, // 8.5479 + (5.45155 * 2.0),
  40. 24.90255, // 8.5479 + (5.45155 * 3.0),
  41. 30.35410, // 8.5479 + (5.45155 * 4.0),
  42. 35.80565, // 8.5479 + (5.45155 * 5.0),
  43. 41.25720, // 8.5479 + (5.45155 * 6.0),
  44. 46.70875, // 8.5479 + (5.45155 * 7.0),
  45. 52.16030, // 8.5479 + (5.45155 * 8.0),
  46. 57.61185, // 8.5479 + (5.45155 * 9.0),
  47. 63.06340, // 8.5479 + (5.45155 * 10.0),
  48. 68.51495, // 8.5479 + (5.45155 * 11.0),
  49. 73.96650, // 8.5479 + (5.45155 * 12.0),
  50. 79.41805, // 8.5479 + (5.45155 * 13.0),
  51. 84.86960, // 8.5479 + (5.45155 * 14.0),
  52. 90.32115, // 8.5479 + (5.45155 * 15.0),
  53. 95.77270, // 8.5479 + (5.45155 * 16.0),
  54. 101.22425, // 8.5479 + (5.45155 * 17.0),
  55. 106.67580, // 8.5479 + (5.45155 * 18.0),
  56. 112.12735 // 8.5479 + (5.45155 * 19.0)
  57. };
  58. stock LoadElevatorStuff() {
  59. if(!fexist("elevator.ini")) return 1;
  60. new
  61. szFileStr[64],
  62. iIndex,
  63. File: iFileHandle = fopen("elevator.ini", io_read);
  64. while(iIndex < 20 && fread(iFileHandle, szFileStr)) {
  65. sscanf(szFileStr, "p<|>s[24]s[24]", LAElevatorFloorData[0][iIndex], LAElevatorFloorData[1][iIndex]);
  66. StripNL(LAElevatorFloorData[1][iIndex]);
  67. iIndex++;
  68. }
  69. printf("[LoadElevatorStuff] %i floors loaded.", iIndex);
  70. return fclose(iFileHandle);
  71. }
  72. stock SaveElevatorStuff() {
  73. new
  74. File: iFileHandle = fopen("elevator.ini", io_write);
  75. for(new iIndex; iIndex < 20; ++iIndex) {
  76. fwrite(iFileHandle, LAElevatorFloorData[0][iIndex]);
  77. fputchar(iFileHandle, '|', false);
  78. fwrite(iFileHandle, LAElevatorFloorData[1][iIndex]);
  79. fwrite(iFileHandle, "\r\n");
  80. }
  81. return fclose(iFileHandle);
  82. }
  83. stock Float:GetElevatorZCoordForFloor(floorid)
  84. {
  85. return (GROUND_Z_COORD + FloorZOffsets[floorid] + ELEVATOR_OFFSET); // A small offset for the elevator object itself.
  86. }
  87. stock Float:GetDoorsZCoordForFloor(floorid)
  88. {
  89. return (GROUND_Z_COORD + FloorZOffsets[floorid]);
  90. }
  91. forward Elevator_Boost(floorid);
  92. public Elevator_Boost(floorid)
  93. {
  94. // Increases the elevator's speed until it reaches 'floorid'
  95. MoveDynamicObject(Obj_Elevator, 1786.678100, -1303.459472, GetElevatorZCoordForFloor(floorid), ELEVATOR_SPEED);
  96. MoveDynamicObject(Obj_ElevatorDoors[0], X_DOOR_CLOSED, -1303.459472, GetDoorsZCoordForFloor(floorid), ELEVATOR_SPEED);
  97. MoveDynamicObject(Obj_ElevatorDoors[1], X_DOOR_CLOSED, -1303.459472, GetDoorsZCoordForFloor(floorid), ELEVATOR_SPEED);
  98. }
  99. forward Elevator_TurnToIdle();
  100. public Elevator_TurnToIdle()
  101. {
  102. ElevatorState = ELEVATOR_STATE_IDLE;
  103. ReadNextFloorInQueue();
  104. }
  105. stock Elevator_Initialize()
  106. {
  107. // Initializes the elevator.
  108. Obj_Elevator = CreateDynamicObject(18755, 1786.678100, -1303.459472, GROUND_Z_COORD + ELEVATOR_OFFSET, 0.000000, 0.000000, 270.000000);
  109. Obj_ElevatorDoors[0] = CreateDynamicObject(18757, X_DOOR_CLOSED, -1303.459472, GROUND_Z_COORD, 0.000000, 0.000000, 270.000000);
  110. Obj_ElevatorDoors[1] = CreateDynamicObject(18756, X_DOOR_CLOSED, -1303.459472, GROUND_Z_COORD, 0.000000, 0.000000, 270.000000);
  111. Label_Elevator = CreateDynamic3DTextLabel("Press '~k~~GROUP_CONTROL_BWD~' to use elevator", COLOR_YELLOW, 1784.9822, -1302.0426, 13.6491, 4.0);
  112. new string[128],
  113. Float:z;
  114. for(new i; i < sizeof(Obj_FloorDoors); i ++)
  115. {
  116. Obj_FloorDoors[i][0] = CreateDynamicObject(18757, X_DOOR_CLOSED, -1303.171142, GetDoorsZCoordForFloor(i), 0.000000, 0.000000, 270.000000);
  117. Obj_FloorDoors[i][1] = CreateDynamicObject(18756, X_DOOR_CLOSED, -1303.171142, GetDoorsZCoordForFloor(i), 0.000000, 0.000000, 270.000000);
  118. format(string, sizeof(string), "%s\nPress '~k~~GROUP_CONTROL_BWD~' to call", LAElevatorFloorData[0][i]);
  119. if(i == 0)
  120. z = 13.4713;
  121. else
  122. z = 13.4713 + 8.7396 + ((i-1) * 5.45155);
  123. Label_Floors[i] = CreateDynamic3DTextLabel(string, COLOR_YELLOW, 1783.9799, -1300.7660, z, 10.5);
  124. // Label_Elevator, Text3D:Label_Floors[21];
  125. }
  126. // Open ground floor doors:
  127. Floor_OpenDoors(0);
  128. Elevator_OpenDoors();
  129. }
  130. stock Elevator_OpenDoors()
  131. {
  132. // Opens the elevator's doors.
  133. new Float:x, Float:y, Float:z;
  134. GetDynamicObjectPos(Obj_ElevatorDoors[0], x, y, z);
  135. MoveDynamicObject(Obj_ElevatorDoors[0], X_DOOR_L_OPENED, y, z, DOORS_SPEED);
  136. MoveDynamicObject(Obj_ElevatorDoors[1], X_DOOR_R_OPENED, y, z, DOORS_SPEED);
  137. }
  138. stock Elevator_CloseDoors()
  139. {
  140. // Closes the elevator's doors.
  141. if(ElevatorState == ELEVATOR_STATE_MOVING)
  142. return 0;
  143. new Float:x, Float:y, Float:z;
  144. GetDynamicObjectPos(Obj_ElevatorDoors[0], x, y, z);
  145. MoveDynamicObject(Obj_ElevatorDoors[0], X_DOOR_CLOSED, y, z, DOORS_SPEED);
  146. MoveDynamicObject(Obj_ElevatorDoors[1], X_DOOR_CLOSED, y, z, DOORS_SPEED);
  147. return 1;
  148. }
  149. stock Floor_OpenDoors(floorid)
  150. {
  151. // Opens the doors at the specified floor.
  152. MoveDynamicObject(Obj_FloorDoors[floorid][0], X_DOOR_L_OPENED, -1303.171142, GetDoorsZCoordForFloor(floorid), DOORS_SPEED);
  153. MoveDynamicObject(Obj_FloorDoors[floorid][1], X_DOOR_R_OPENED, -1303.171142, GetDoorsZCoordForFloor(floorid), DOORS_SPEED);
  154. }
  155. stock Floor_CloseDoors(floorid)
  156. {
  157. // Closes the doors at the specified floor.
  158. MoveDynamicObject(Obj_FloorDoors[floorid][0], X_DOOR_CLOSED, -1303.171142, GetDoorsZCoordForFloor(floorid), DOORS_SPEED);
  159. MoveDynamicObject(Obj_FloorDoors[floorid][1], X_DOOR_CLOSED, -1303.171142, GetDoorsZCoordForFloor(floorid), DOORS_SPEED);
  160. }
  161. stock Elevator_MoveToFloor(floorid)
  162. {
  163. // Moves the elevator to specified floor (doors are meant to be already closed).
  164. ElevatorState = ELEVATOR_STATE_MOVING;
  165. ElevatorFloor = floorid;
  166. // Move the elevator slowly, to give time to clients to sync the object surfing. Then, boost it up:
  167. MoveDynamicObject(Obj_Elevator, 1786.678100, -1303.459472, GetElevatorZCoordForFloor(floorid), 0.25);
  168. MoveDynamicObject(Obj_ElevatorDoors[0], X_DOOR_CLOSED, -1303.459472, GetDoorsZCoordForFloor(floorid), 0.25);
  169. MoveDynamicObject(Obj_ElevatorDoors[1], X_DOOR_CLOSED, -1303.459472, GetDoorsZCoordForFloor(floorid), 0.25);
  170. DestroyDynamic3DTextLabel(Label_Elevator);
  171. ElevatorBoostTimer = SetTimerEx("Elevator_Boost", 2000, 0, "i", floorid);
  172. }
  173. stock RemoveFirstQueueFloor()
  174. {
  175. // Removes the data in ElevatorQueue[0], and reorders the queue accordingly.
  176. for(new i; i < sizeof(ElevatorQueue) - 1; i ++)
  177. ElevatorQueue[i] = ElevatorQueue[i + 1];
  178. ElevatorQueue[sizeof(ElevatorQueue) - 1] = INVALID_FLOOR;
  179. }
  180. stock AddFloorToQueue(floorid)
  181. {
  182. // Adds 'floorid' at the end of the queue.
  183. // Scan for the first empty space:
  184. new slot = -1;
  185. for(new i; i < sizeof(ElevatorQueue); i ++)
  186. {
  187. if(ElevatorQueue[i] == INVALID_FLOOR)
  188. {
  189. slot = i;
  190. break;
  191. }
  192. }
  193. if(slot != -1)
  194. {
  195. ElevatorQueue[slot] = floorid;
  196. // If needed, move the elevator.
  197. if(ElevatorState == ELEVATOR_STATE_IDLE)
  198. ReadNextFloorInQueue();
  199. return 1;
  200. }
  201. return 0;
  202. }
  203. stock ResetElevatorQueue()
  204. {
  205. // Resets the queue.
  206. for(new i; i < sizeof(ElevatorQueue); i ++)
  207. {
  208. ElevatorQueue[i] = INVALID_FLOOR;
  209. FloorRequestedBy[i] = INVALID_PLAYER_ID;
  210. }
  211. }
  212. stock IsFloorInQueue(floorid)
  213. {
  214. // Checks if the specified floor is currently part of the queue.
  215. for(new i; i < sizeof(ElevatorQueue); i ++)
  216. if(ElevatorQueue[i] == floorid)
  217. return 1;
  218. return 0;
  219. }
  220. stock ReadNextFloorInQueue()
  221. {
  222. // Reads the next floor in the queue, closes doors, and goes to it.
  223. if(ElevatorState != ELEVATOR_STATE_IDLE || ElevatorQueue[0] == INVALID_FLOOR)
  224. return 0;
  225. Elevator_CloseDoors();
  226. Floor_CloseDoors(ElevatorFloor);
  227. return 1;
  228. }
  229. stock DidPlayerRequestElevator(playerid)
  230. {
  231. for(new i; i < sizeof(FloorRequestedBy); i ++)
  232. if(FloorRequestedBy[i] == playerid)
  233. return 1;
  234. return 0;
  235. }
  236. stock ShowElevatorDialog(playerid, elev)
  237. {
  238. new string[512], maxfloors;
  239. switch(elev)
  240. {
  241. case 1: maxfloors = 20;
  242. case 2: maxfloors = 8;
  243. }
  244. for(new x; x < maxfloors; x++)
  245. {
  246. format(string, sizeof(string), "%s%d - %s\n", string, (x+1), LAElevatorFloorData[0][x]);
  247. }
  248. ShowPlayerDialogEx(playerid, LAELEVATOR, DIALOG_STYLE_LIST, "Elevator", string, "Select", "Cancel");
  249. }
  250. stock CallElevator(playerid, floorid)
  251. {
  252. // Calls the elevator (also used with the elevator dialog).
  253. if(FloorRequestedBy[floorid] != INVALID_PLAYER_ID || IsFloorInQueue(floorid))
  254. return 0;
  255. FloorRequestedBy[floorid] = playerid;
  256. AddFloorToQueue(floorid);
  257. return 1;
  258. }
  259. hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
  260. {
  261. if(!IsPlayerInAnyVehicle(playerid) && newkeys & KEY_CTRL_BACK)
  262. {
  263. new Float:pos[3];
  264. GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
  265. if(pos[1] < -1301.4 && pos[1] > -1303.2417 && pos[0] < 1786.2131 && pos[0] > 1784.1555)
  266. { // He is using the elevator button
  267. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  268. ApplyAnimation(playerid, "HEIST9", "Use_SwipeCard", 10.0, 0, 0, 0, 0, 0);
  269. ShowElevatorDialog(playerid, 1);
  270. }
  271. else // Is he in a floor button?
  272. {
  273. if(pos[1] > -1301.4 && pos[1] < -1299.1447 && pos[0] < 1785.6147 && pos[0] > 1781.9902)
  274. {
  275. // He is most likely using it, check floor:
  276. new i=20;
  277. while(pos[2] < GetDoorsZCoordForFloor(i) + 3.5 && i > 0)
  278. i --;
  279. if(i == 0 && pos[2] < GetDoorsZCoordForFloor(0) + 2.0)
  280. i = -1;
  281. if(i <= 19)
  282. {
  283. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  284. ApplyAnimation(playerid, "HEIST9", "Use_SwipeCard", 10.0, 0, 0, 0, 0, 0);
  285. CallElevator(playerid, i + 1);
  286. GameTextForPlayer(playerid, "~r~Elevator called", 3500, 4);
  287. }
  288. }
  289. }
  290. }
  291. return 1;
  292. }
  293. CMD:floorpass(playerid, params[])
  294. {
  295. if(PlayerInfo[playerid][pAdmin] < 4 && PlayerInfo[playerid][pASM] < 1)
  296. {
  297. SendClientMessageEx(playerid, COLOR_GRAD2, "You are not authorized to use that command.");
  298. return 1;
  299. }
  300. new floor, tmp[24];
  301. if(sscanf(params, "is[24]", floor, tmp))
  302. {
  303. SendClientMessageEx(playerid, COLOR_GREY, "USAGE: /floorpass [floor] [pass]");
  304. return 1;
  305. }
  306. new string[128];
  307. format(LAElevatorFloorData[1][floor-1],24, "%s", tmp);
  308. format(string, sizeof(string), "Floor %d pass set to %s", floor, LAElevatorFloorData[1][floor-1]);
  309. SendClientMessageEx(playerid, COLOR_WHITE, string);
  310. SaveElevatorStuff();
  311. return 1;
  312. }
  313. CMD:floorpassr(playerid, params[])
  314. {
  315. if(PlayerInfo[playerid][pAdmin] < 4 && PlayerInfo[playerid][pASM] < 1)
  316. {
  317. SendClientMessageEx(playerid, COLOR_GRAD2, "You are not authorized to use that command.");
  318. return 1;
  319. }
  320. new floor;
  321. if(sscanf(params, "i", floor))
  322. {
  323. SendClientMessageEx(playerid, COLOR_GREY, "USAGE: /floorpassr [floor]");
  324. return 1;
  325. }
  326. new string[128];
  327. floor = floor - 1;
  328. format(LAElevatorFloorData[1][floor-1],24, "");
  329. format(string, sizeof(string), "Floor %d pass removed", floor);
  330. SendClientMessageEx(playerid, COLOR_WHITE, string);
  331. SaveElevatorStuff();
  332. new Float:z;
  333. for(new i; i < sizeof(Obj_FloorDoors); i ++)
  334. {
  335. format(string, sizeof(string), "%s\nPress '~k~~GROUP_CONTROL_BWD~' to call", LAElevatorFloorData[0][i]);
  336. if(i == 0)
  337. z = 13.4713;
  338. else
  339. z = 13.4713 + 8.7396 + ((i-1) * 5.45155);
  340. DestroyDynamic3DTextLabel(Label_Floors[i]);
  341. Label_Floors[i] = CreateDynamic3DTextLabel(string, COLOR_YELLOW, 1783.9799, -1300.7660, z, 10.5);
  342. }
  343. return 1;
  344. }
  345. CMD:floornamer(playerid, params[])
  346. {
  347. if(PlayerInfo[playerid][pAdmin] < 4 && PlayerInfo[playerid][pASM] < 1)
  348. {
  349. SendClientMessageEx(playerid, COLOR_GRAD2, "You are not authorized to use that command.");
  350. return 1;
  351. }
  352. new floor;
  353. if(sscanf(params, "i", floor))
  354. {
  355. SendClientMessageEx(playerid, COLOR_GREY, "USAGE: /floornamer [floor]");
  356. return 1;
  357. }
  358. new string[128];
  359. format(LAElevatorFloorData[0][floor-1],24, "");
  360. format(string, sizeof(string), "Floor %d name removed", floor);
  361. SendClientMessageEx(playerid, COLOR_WHITE, string);
  362. SaveElevatorStuff();
  363. new Float:z;
  364. for(new i; i < sizeof(Obj_FloorDoors); i ++)
  365. {
  366. format(string, sizeof(string), "%s\nPress '~k~~GROUP_CONTROL_BWD~' to call", LAElevatorFloorData[0][i]);
  367. if(i == 0)
  368. z = 13.4713;
  369. else
  370. z = 13.4713 + 8.7396 + ((i-1) * 5.45155);
  371. DestroyDynamic3DTextLabel(Label_Floors[i]);
  372. Label_Floors[i] = CreateDynamic3DTextLabel(string, COLOR_YELLOW, 1783.9799, -1300.7660, z, 10.5);
  373. }
  374. return 1;
  375. }
  376. CMD:floorname(playerid, params[])
  377. {
  378. if(PlayerInfo[playerid][pAdmin] < 4 && PlayerInfo[playerid][pASM] < 1)
  379. {
  380. SendClientMessageEx(playerid, COLOR_GRAD2, "You are not authorized to use that command.");
  381. return 1;
  382. }
  383. new floor, tmp[24];
  384. if(sscanf(params, "is[24]", floor, tmp))
  385. {
  386. SendClientMessageEx(playerid, COLOR_GREY, "USAGE: /floorname [floor] [name]");
  387. return 1;
  388. }
  389. new string[128];
  390. format(LAElevatorFloorData[0][floor-1],24, "%s", tmp);
  391. format(string, sizeof(string), "Renamed Floor %d to %s", floor, LAElevatorFloorData[0][floor-1]);
  392. SendClientMessageEx(playerid, COLOR_WHITE, string);
  393. SaveElevatorStuff();
  394. new Float:z;
  395. for(new i; i < sizeof(Obj_FloorDoors); i ++)
  396. {
  397. format(string, sizeof(string), "%s\nPress '~k~~GROUP_CONTROL_BWD~' to call", LAElevatorFloorData[0][i]);
  398. if(i == 0)
  399. z = 13.4713;
  400. else
  401. z = 13.4713 + 8.7396 + ((i-1) * 5.45155);
  402. DestroyDynamic3DTextLabel(Label_Floors[i]);
  403. Label_Floors[i] = CreateDynamic3DTextLabel(string, COLOR_YELLOW, 1783.9799, -1300.7660, z, 10.5);
  404. }
  405. return 1;
  406. }