SAMP Gitlab CI Test
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

743 lines
24 KiB

  1. // -----------------------------------------------------------------------------
  2. // -----------------------------------------------------------------------------
  3. // Example Filterscript for the new LS BeachSide Building with Elevator
  4. // --------------------------------------------------------------------
  5. // Original elevator code by Zamaroht in 2010
  6. //
  7. // Updated by Kye in 2011
  8. // * Added a sound effect for the elevator starting/stopping
  9. //
  10. // Edited by Matite in January 2015
  11. // * Adapted the elevator code so it works in this new building and removed the
  12. // light pole at the underground car park entrance
  13. //
  14. // Updated to v1.03 by Matite in April 2015
  15. // * Removed the code that removes the existing building map object and the lines
  16. // that create the new objects as the original building is now replaced with
  17. // the new one by SAMP instead (same as the LS Office building)
  18. //
  19. // Updated to v1.02 by Matite in February 2015
  20. // * Added code for the new car park object and edited the elevator to
  21. // include the car park
  22. //
  23. // This script creates the new LS BeachSide building object, removes the
  24. // existing GTASA building object, adds the new car park object and creates
  25. // an elevator that can be used to travel between all levels.
  26. //
  27. // You can un-comment the OnPlayerCommandText callback below to enable a simple
  28. // teleport command (/lsb) that teleports you to the LS BeachSide building.
  29. //
  30. // Warning...
  31. // This script uses a total of:
  32. // * 31 objects = 1 for the elevator, 2 for the elevator doors and 28 for the
  33. // elevator floor doors
  34. // * 15 3D Text Labels = 14 on the floors and 1 in the elevator
  35. // * 1 dialog (for the elevator - dialog ID 877)
  36. // -----------------------------------------------------------------------------
  37. // -----------------------------------------------------------------------------
  38. // -----------------------------------------------------------------------------
  39. // Includes
  40. // --------
  41. // SA-MP include
  42. #include <a_samp>
  43. // For PlaySoundForPlayersInRange()
  44. #include "../include/gl_common.inc"
  45. // -----------------------------------------------------------------------------
  46. // Defines
  47. // -------
  48. // Movement speed of the elevator
  49. #define ELEVATOR_SPEED (5.0)
  50. // Movement speed of the doors
  51. #define DOORS_SPEED (5.0)
  52. // Time in ms that the elevator will wait in each floor before continuing with the queue...
  53. // be sure to give enough time for doors to open
  54. #define ELEVATOR_WAIT_TIME (5000)
  55. // Dialog ID for the LS BeachSide elevator dialog
  56. #define DIALOG_ID (877)
  57. // Position defines
  58. #define X_DOOR_R_OPENED (289.542419)
  59. #define X_DOOR_L_OPENED (286.342407)
  60. #define Y_DOOR_R_OPENED (-1609.640991)
  61. #define Y_DOOR_L_OPENED (-1609.076049)
  62. #define X_FDOOR_R_OPENED (289.492431)
  63. #define X_FDOOR_L_OPENED (286.292419)
  64. #define Y_FDOOR_R_OPENED (-1609.870971)
  65. #define Y_FDOOR_L_OPENED (-1609.306030)
  66. #define GROUND_Z_COORD (18.755348) // (33.825077)
  67. #define X_ELEVATOR_POS (287.942413)
  68. #define Y_ELEVATOR_POS (-1609.341064)
  69. // Elevator state defines
  70. #define ELEVATOR_STATE_IDLE (0)
  71. #define ELEVATOR_STATE_WAITING (1)
  72. #define ELEVATOR_STATE_MOVING (2)
  73. // Invalid floor define
  74. #define INVALID_FLOOR (-1)
  75. // Used for chat text messages
  76. #define COLOR_MESSAGE_YELLOW 0xFFDD00AA
  77. // -----------------------------------------------------------------------------
  78. // Constants
  79. // ---------
  80. // Elevator floor names for the 3D text labels
  81. static FloorNames[14][] =
  82. {
  83. "Car Park",
  84. "Ground Floor",
  85. "First Floor",
  86. "Second Floor",
  87. "Third Floor",
  88. "Fourth Floor",
  89. "Fifth Floor",
  90. "Sixth Floor",
  91. "Seventh Floor",
  92. "Eighth Floor",
  93. "Ninth Floor",
  94. "Tenth Floor",
  95. "Eleventh Floor",
  96. "Twelfth Floor"
  97. };
  98. // Elevator floor Z heights
  99. static Float:FloorZOffsets[14] =
  100. {
  101. 0.0, // Car Park
  102. 15.069729, // Ground Floor
  103. 29.130733, // First Floor
  104. 33.630733, // Second Floor = 29.130733 + 4.5
  105. 38.130733, // Third Floor = 33.630733 + 4.5
  106. 42.630733, // Fourth Floor = 38.130733 + 4.5
  107. 47.130733, // Fifth Floor = 42.630733 + 4.5
  108. 51.630733, // Sixth Floor = 47.130733 + 4.5
  109. 56.130733, // Seventh Floor = 51.630733 + 4.5
  110. 60.630733, // Eighth Floor = 56.130733 + 4.5
  111. 65.130733, // Ninth Floor = 60.630733 + 4.5
  112. 69.630733, // Tenth Floor = 65.130733 + 4.5
  113. 74.130733, // Eleventh Floor = 69.630733 + 4.5
  114. 78.630733, // Twelfth Floor = 74.130733 + 4.5
  115. };
  116. // -----------------------------------------------------------------------------
  117. // Variables
  118. // ---------
  119. // Stores the created object numbers of the elevator, the elevator doors and
  120. // the elevator floor doors so they can be destroyed when the filterscript
  121. // is unloaded
  122. new Obj_Elevator, Obj_ElevatorDoors[2], Obj_FloorDoors[14][2];
  123. // Stores a reference to the 3D text labels used on each floor and inside the
  124. // elevator itself so they can be detroyed when the filterscript is unloaded
  125. new Text3D:Label_Elevator, Text3D:Label_Floors[14];
  126. // Stores the current state of the elevator (ie ELEVATOR_STATE_IDLE,
  127. // ELEVATOR_STATE_WAITING or ELEVATOR_STATE_MOVING)
  128. new ElevatorState;
  129. // Stores the current floor the elevator is on or heading to... if the value is
  130. // ELEVATOR_STATE_IDLE or ELEVATOR_STATE_WAITING this is the current floor. If
  131. // the value is ELEVATOR_STATE_MOVING then it is the floor it's moving to
  132. new ElevatorFloor;
  133. // Stores the elevator queue for each floor
  134. new ElevatorQueue[14];
  135. // Stores who requested the floor for the elevator queue...
  136. // FloorRequestedBy[floor_id] = playerid; (stores who requested which floor)
  137. new FloorRequestedBy[14];
  138. // Used for a timer that makes the elevator move faster after players start
  139. // surfing the object
  140. new ElevatorBoostTimer;
  141. // -----------------------------------------------------------------------------
  142. // Function Forwards
  143. // -----------------
  144. // Public:
  145. forward CallElevator(playerid, floorid); // You can use INVALID_PLAYER_ID too.
  146. forward ShowElevatorDialog(playerid);
  147. // Private:
  148. forward Elevator_Initialize();
  149. forward Elevator_Destroy();
  150. forward Elevator_OpenDoors();
  151. forward Elevator_CloseDoors();
  152. forward Floor_OpenDoors(floorid);
  153. forward Floor_CloseDoors(floorid);
  154. forward Elevator_MoveToFloor(floorid);
  155. forward Elevator_Boost(floorid); // Increases the elevator speed until it reaches 'floorid'.
  156. forward Elevator_TurnToIdle();
  157. forward ReadNextFloorInQueue();
  158. forward RemoveFirstQueueFloor();
  159. forward AddFloorToQueue(floorid);
  160. forward IsFloorInQueue(floorid);
  161. forward ResetElevatorQueue();
  162. forward DidPlayerRequestElevator(playerid);
  163. forward Float:GetElevatorZCoordForFloor(floorid);
  164. forward Float:GetDoorsZCoordForFloor(floorid);
  165. // -----------------------------------------------------------------------------
  166. // Callbacks
  167. // ---------
  168. // Un-comment the OnPlayerCommandText callback below (remove the "/*" and the "*/")
  169. // to enable a simple teleport command (/lsb) which teleports the player to
  170. // outside the LS BeachSide building.
  171. /*
  172. public OnPlayerCommandText(playerid, cmdtext[])
  173. {
  174. // Check command text
  175. if (strcmp("/lsb", cmdtext, true, 4) == 0)
  176. {
  177. // Set the interior
  178. SetPlayerInterior(playerid, 0);
  179. // Set player position and facing angle
  180. SetPlayerPos(playerid, 289.81 + random(2), -1630.65 + random(2), 34.32);
  181. SetPlayerFacingAngle(playerid, 10);
  182. // Fix camera position after teleporting
  183. SetCameraBehindPlayer(playerid);
  184. // Send a gametext message to the player
  185. GameTextForPlayer(playerid, "~b~~h~LS BeachSide!", 3000, 3);
  186. // Exit here
  187. return 1;
  188. }
  189. // Exit here (return 0 as the command was not handled in this filterscript)
  190. return 0;
  191. }
  192. */
  193. public OnFilterScriptInit()
  194. {
  195. // Display information in the Server Console
  196. print("\n");
  197. print(" |---------------------------------------------------");
  198. print(" |--- LS BeachSide Filterscript");
  199. print(" |-- Script v1.03");
  200. print(" |-- 19th April 2015");
  201. print(" |---------------------------------------------------");
  202. // Reset the elevator queue
  203. ResetElevatorQueue();
  204. // Create the elevator object, the elevator doors and the floor doors
  205. Elevator_Initialize();
  206. // Display information in the Server Console
  207. print(" |-- LS BeachSide Building Elevator created");
  208. print(" |---------------------------------------------------");
  209. // Loop
  210. for (new i = 0; i < MAX_PLAYERS; i++)
  211. {
  212. // Check if the player is connected and not a NPC
  213. if (IsPlayerConnected(i) && !IsPlayerNPC(i))
  214. {
  215. // Remove the lamp post at the underground car park entrance
  216. RemoveBuildingForPlayer(i, 1226, 265.481, -1581.1, 32.9311, 5.0);
  217. // Remove the night lights object (must be removed to also remove any
  218. // occulsion zones inside the building)
  219. RemoveBuildingForPlayer(i, 6518, 280.297, -1606.2, 72.3984, 250.0);
  220. }
  221. }
  222. // Exit here
  223. return 1;
  224. }
  225. public OnFilterScriptExit()
  226. {
  227. // Destroy the elevator, the elevator doors and the elevator floor doors
  228. Elevator_Destroy();
  229. // Display information in the Server Console
  230. print(" |-- LS BeachSide Building Elevator destroyed");
  231. print(" |---------------------------------------------------");
  232. // Exit here
  233. return 1;
  234. }
  235. public OnPlayerConnect(playerid)
  236. {
  237. // Remove the lamp post at the underground car park entrance
  238. RemoveBuildingForPlayer(playerid, 1226, 265.481, -1581.1, 32.9311, 5.0);
  239. // Remove the night lights object (must be removed to also remove any
  240. // occulsion zones inside the building)
  241. RemoveBuildingForPlayer(playerid, 6518, 280.297, -1606.2, 72.3984, 250.0);
  242. // Exit here (return 1 so this callback is processed in other scripts)
  243. return 1;
  244. }
  245. public OnObjectMoved(objectid)
  246. {
  247. // Create variables
  248. new Float:x, Float:y, Float:z;
  249. // Loop
  250. for(new i; i < sizeof(Obj_FloorDoors); i ++)
  251. {
  252. // Check if the object that moved was one of the elevator floor doors
  253. if(objectid == Obj_FloorDoors[i][0])
  254. {
  255. GetObjectPos(Obj_FloorDoors[i][0], x, y, z);
  256. // Some floor doors have shut, move the elevator to next floor in queue:
  257. if (y < Y_DOOR_L_OPENED - 0.5)
  258. {
  259. Elevator_MoveToFloor(ElevatorQueue[0]);
  260. RemoveFirstQueueFloor();
  261. }
  262. }
  263. }
  264. if(objectid == Obj_Elevator) // The elevator reached the specified floor.
  265. {
  266. KillTimer(ElevatorBoostTimer); // Kills the timer, in case the elevator reached the floor before boost.
  267. FloorRequestedBy[ElevatorFloor] = INVALID_PLAYER_ID;
  268. Elevator_OpenDoors();
  269. Floor_OpenDoors(ElevatorFloor);
  270. GetObjectPos(Obj_Elevator, x, y, z);
  271. Label_Elevator = Create3DTextLabel("{CCCCCC}Press '{FFFFFF}~k~~CONVERSATION_YES~{CCCCCC}' to use elevator", 0xCCCCCCAA, X_ELEVATOR_POS + 1.6, Y_ELEVATOR_POS - 1.85, z - 0.4, 4.0, 0, 1);
  272. ElevatorState = ELEVATOR_STATE_WAITING;
  273. SetTimer("Elevator_TurnToIdle", ELEVATOR_WAIT_TIME, 0);
  274. }
  275. return 1;
  276. }
  277. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
  278. {
  279. if(dialogid == DIALOG_ID)
  280. {
  281. if(!response)
  282. return 0;
  283. if(FloorRequestedBy[listitem] != INVALID_PLAYER_ID || IsFloorInQueue(listitem))
  284. GameTextForPlayer(playerid, "~r~The floor is already in the queue", 3500, 4);
  285. else if(DidPlayerRequestElevator(playerid))
  286. GameTextForPlayer(playerid, "~r~You already requested the elevator", 3500, 4);
  287. else
  288. CallElevator(playerid, listitem);
  289. return 1;
  290. }
  291. return 0;
  292. }
  293. public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
  294. {
  295. // Check if the player is not in a vehicle and pressed the conversation yes key (Y by default)
  296. if (!IsPlayerInAnyVehicle(playerid) && (newkeys & KEY_YES))
  297. {
  298. // Create variables and get the players current position
  299. new Float:pos[3];
  300. GetPlayerPos(playerid, pos[0], pos[1], pos[2]);
  301. // For debug
  302. //printf("X = %0.2f | Y = %0.2f | Z = %0.2f", pos[0], pos[1], pos[2]);
  303. // Check if the player is using the button inside the elevator
  304. if (pos[1] > (Y_ELEVATOR_POS - 1.8) && pos[1] < (Y_ELEVATOR_POS + 1.8) && pos[0] < (X_ELEVATOR_POS + 1.8) && pos[0] > (X_ELEVATOR_POS - 1.8))
  305. {
  306. // The player is using the button inside the elevator
  307. // --------------------------------------------------
  308. // Show the elevator dialog to the player
  309. ShowElevatorDialog(playerid);
  310. }
  311. else
  312. {
  313. // Check if the player is using the button on one of the floors
  314. if(pos[1] < (Y_ELEVATOR_POS - 1.81) && pos[1] > (Y_ELEVATOR_POS - 3.8) && pos[0] > (X_ELEVATOR_POS + 1.21) && pos[0] < (X_ELEVATOR_POS + 3.8))
  315. {
  316. // The player is most likely using an elevator floor button... check which floor
  317. // -----------------------------------------------------------------------------
  318. // Create variable with the number of floors to check (total floors minus 1)
  319. new i = 13;
  320. // Loop
  321. while(pos[2] < GetDoorsZCoordForFloor(i) + 3.5 && i > 0)
  322. i --;
  323. if(i == 0 && pos[2] < GetDoorsZCoordForFloor(0) + 2.0)
  324. i = -1;
  325. if (i <= 12)
  326. {
  327. // Check if the elevator is not moving (idle or waiting)
  328. if (ElevatorState != ELEVATOR_STATE_MOVING)
  329. {
  330. // Check if the elevator is already on the floor it was called from
  331. if (ElevatorFloor == i + 1)
  332. {
  333. // Display gametext message to the player
  334. GameTextForPlayer(playerid, "~n~~n~~n~~n~~n~~n~~n~~y~~h~LS BeachSide Elevator Is~n~~y~~h~Already On This Floor...~n~~w~Walk Inside It~n~~w~And Press '~k~~CONVERSATION_YES~'", 3500, 3);
  335. // Display chat text message to the player
  336. SendClientMessage(playerid, COLOR_MESSAGE_YELLOW, "* The LS BeachSide elevator is already on this floor... walk inside it and press '{FFFFFF}~k~~CONVERSATION_YES~{CCCCCC}'");
  337. // Exit here (return 1 so this callback is processed in other scripts)
  338. return 1;
  339. }
  340. }
  341. // Call function to call the elevator to the floor
  342. CallElevator(playerid, i + 1);
  343. // Display gametext message to the player
  344. GameTextForPlayer(playerid, "~n~~n~~n~~n~~n~~n~~n~~n~~g~~h~LS BeachSide Elevator~n~~g~~h~Has Been Called...~n~~w~Please Wait", 3000, 3);
  345. // Create variable for formatted message
  346. new strTempString[100];
  347. // Check if the elevator is moving
  348. if (ElevatorState == ELEVATOR_STATE_MOVING)
  349. {
  350. // Format chat text message
  351. format(strTempString, sizeof(strTempString), "* The LS BeachSide elevator has been called... it is currently moving towards the %s.", FloorNames[ElevatorFloor]);
  352. }
  353. else
  354. {
  355. // Check if the floor is the car park
  356. if (ElevatorFloor == 0)
  357. {
  358. // Format chat text message
  359. format(strTempString, sizeof(strTempString), "* The LS BeachSide elevator has been called... it is currently at the %s.", FloorNames[ElevatorFloor]);
  360. }
  361. else
  362. {
  363. // Format chat text message
  364. format(strTempString, sizeof(strTempString), "* The LS BeachSide elevator has been called... it is currently on the %s.", FloorNames[ElevatorFloor]);
  365. }
  366. }
  367. // Display formatted chat text message to the player
  368. SendClientMessage(playerid, COLOR_MESSAGE_YELLOW, strTempString);
  369. // Exit here (return 1 so this callback is processed in other scripts)
  370. return 1;
  371. }
  372. }
  373. }
  374. }
  375. // Exit here (return 1 so this callback is processed in other scripts)
  376. return 1;
  377. }
  378. // ------------------------ Functions ------------------------
  379. stock Elevator_Initialize()
  380. {
  381. // Create the elevator and elevator door objects
  382. Obj_Elevator = CreateObject(18755, X_ELEVATOR_POS, Y_ELEVATOR_POS, GROUND_Z_COORD, 0.000000, 0.000000, 80.000000);
  383. Obj_ElevatorDoors[0] = CreateObject(18757, X_ELEVATOR_POS, Y_ELEVATOR_POS, GROUND_Z_COORD, 0.000000, 0.000000, 80.000000);
  384. Obj_ElevatorDoors[1] = CreateObject(18756, X_ELEVATOR_POS, Y_ELEVATOR_POS, GROUND_Z_COORD, 0.000000, 0.000000, 80.000000);
  385. // Create the 3D text label for inside the elevator
  386. Label_Elevator = Create3DTextLabel("{CCCCCC}Press '{FFFFFF}~k~~CONVERSATION_YES~{CCCCCC}' to use elevator", 0xCCCCCCAA, X_ELEVATOR_POS + 1.6, Y_ELEVATOR_POS - 1.85, GROUND_Z_COORD - 0.4, 4.0, 0, 1);
  387. // Create variables
  388. new string[128], Float:z;
  389. // Loop
  390. for (new i; i < sizeof(Obj_FloorDoors); i ++)
  391. {
  392. // Create elevator floor door objects
  393. Obj_FloorDoors[i][0] = CreateObject(18757, X_ELEVATOR_POS, Y_ELEVATOR_POS - 0.245, GetDoorsZCoordForFloor(i) + 0.05, 0.000000, 0.000000, 80.000000);
  394. Obj_FloorDoors[i][1] = CreateObject(18756, X_ELEVATOR_POS, Y_ELEVATOR_POS - 0.245, GetDoorsZCoordForFloor(i) + 0.05, 0.000000, 0.000000, 80.000000);
  395. // Format string for the floor 3D text label
  396. format(string, sizeof(string), "{CCCCCC}[%s]\n{CCCCCC}Press '{FFFFFF}~k~~CONVERSATION_YES~{CCCCCC}' to call", FloorNames[i]);
  397. // Get label Z position
  398. z = GetDoorsZCoordForFloor(i);
  399. // Create floor label
  400. Label_Floors[i] = Create3DTextLabel(string, 0xCCCCCCAA, X_ELEVATOR_POS + 2, Y_ELEVATOR_POS -3, z - 0.2, 10.5, 0, 1);
  401. }
  402. // Open the car park floor doors and the elevator doors
  403. Floor_OpenDoors(0);
  404. Elevator_OpenDoors();
  405. // Exit here
  406. return 1;
  407. }
  408. stock Elevator_Destroy()
  409. {
  410. // Destroys the elevator.
  411. DestroyObject(Obj_Elevator);
  412. DestroyObject(Obj_ElevatorDoors[0]);
  413. DestroyObject(Obj_ElevatorDoors[1]);
  414. Delete3DTextLabel(Label_Elevator);
  415. for(new i; i < sizeof(Obj_FloorDoors); i ++)
  416. {
  417. DestroyObject(Obj_FloorDoors[i][0]);
  418. DestroyObject(Obj_FloorDoors[i][1]);
  419. Delete3DTextLabel(Label_Floors[i]);
  420. }
  421. return 1;
  422. }
  423. stock Elevator_OpenDoors()
  424. {
  425. // Opens the elevator's doors.
  426. new Float:x, Float:y, Float:z;
  427. GetObjectPos(Obj_ElevatorDoors[0], x, y, z);
  428. MoveObject(Obj_ElevatorDoors[0], X_DOOR_L_OPENED, Y_DOOR_L_OPENED, z, DOORS_SPEED);
  429. MoveObject(Obj_ElevatorDoors[1], X_DOOR_R_OPENED, Y_DOOR_R_OPENED, z, DOORS_SPEED);
  430. return 1;
  431. }
  432. stock Elevator_CloseDoors()
  433. {
  434. // Closes the elevator's doors.
  435. if(ElevatorState == ELEVATOR_STATE_MOVING)
  436. return 0;
  437. new Float:x, Float:y, Float:z;
  438. GetObjectPos(Obj_ElevatorDoors[0], x, y, z);
  439. MoveObject(Obj_ElevatorDoors[0], X_ELEVATOR_POS, Y_ELEVATOR_POS, z, DOORS_SPEED);
  440. MoveObject(Obj_ElevatorDoors[1], X_ELEVATOR_POS, Y_ELEVATOR_POS, z, DOORS_SPEED);
  441. return 1;
  442. }
  443. stock Floor_OpenDoors(floorid)
  444. {
  445. // Opens the doors at the specified floor.
  446. MoveObject(Obj_FloorDoors[floorid][0], X_FDOOR_L_OPENED, Y_FDOOR_L_OPENED, GetDoorsZCoordForFloor(floorid) + 0.05, DOORS_SPEED);
  447. MoveObject(Obj_FloorDoors[floorid][1], X_FDOOR_R_OPENED, Y_FDOOR_R_OPENED, GetDoorsZCoordForFloor(floorid) + 0.05, DOORS_SPEED);
  448. PlaySoundForPlayersInRange(6401, 50.0, X_ELEVATOR_POS, Y_ELEVATOR_POS, GetDoorsZCoordForFloor(floorid) + 5.0);
  449. return 1;
  450. }
  451. stock Floor_CloseDoors(floorid)
  452. {
  453. // Closes the doors at the specified floor.
  454. MoveObject(Obj_FloorDoors[floorid][0], X_ELEVATOR_POS, Y_ELEVATOR_POS - 0.245, GetDoorsZCoordForFloor(floorid) + 0.05, DOORS_SPEED);
  455. MoveObject(Obj_FloorDoors[floorid][1], X_ELEVATOR_POS, Y_ELEVATOR_POS - 0.245, GetDoorsZCoordForFloor(floorid) + 0.05, DOORS_SPEED);
  456. PlaySoundForPlayersInRange(6401, 50.0, X_ELEVATOR_POS, Y_ELEVATOR_POS, GetDoorsZCoordForFloor(floorid) + 5.0);
  457. return 1;
  458. }
  459. stock Elevator_MoveToFloor(floorid)
  460. {
  461. // Moves the elevator to specified floor (doors are meant to be already closed).
  462. ElevatorState = ELEVATOR_STATE_MOVING;
  463. ElevatorFloor = floorid;
  464. // Move the elevator slowly, to give time to clients to sync the object surfing. Then, boost it up:
  465. MoveObject(Obj_Elevator, X_ELEVATOR_POS, Y_ELEVATOR_POS, GetElevatorZCoordForFloor(floorid), 0.25);
  466. MoveObject(Obj_ElevatorDoors[0], X_ELEVATOR_POS, Y_ELEVATOR_POS, GetDoorsZCoordForFloor(floorid), 0.25);
  467. MoveObject(Obj_ElevatorDoors[1], X_ELEVATOR_POS, Y_ELEVATOR_POS, GetDoorsZCoordForFloor(floorid), 0.25);
  468. Delete3DTextLabel(Label_Elevator);
  469. ElevatorBoostTimer = SetTimerEx("Elevator_Boost", 2000, 0, "i", floorid);
  470. return 1;
  471. }
  472. public Elevator_Boost(floorid)
  473. {
  474. // Increases the elevator's speed until it reaches 'floorid'
  475. StopObject(Obj_Elevator);
  476. StopObject(Obj_ElevatorDoors[0]);
  477. StopObject(Obj_ElevatorDoors[1]);
  478. MoveObject(Obj_Elevator, X_ELEVATOR_POS, Y_ELEVATOR_POS, GetElevatorZCoordForFloor(floorid), ELEVATOR_SPEED);
  479. MoveObject(Obj_ElevatorDoors[0], X_ELEVATOR_POS, Y_ELEVATOR_POS, GetDoorsZCoordForFloor(floorid), ELEVATOR_SPEED);
  480. MoveObject(Obj_ElevatorDoors[1], X_ELEVATOR_POS, Y_ELEVATOR_POS, GetDoorsZCoordForFloor(floorid), ELEVATOR_SPEED);
  481. return 1;
  482. }
  483. public Elevator_TurnToIdle()
  484. {
  485. ElevatorState = ELEVATOR_STATE_IDLE;
  486. ReadNextFloorInQueue();
  487. return 1;
  488. }
  489. stock RemoveFirstQueueFloor()
  490. {
  491. // Removes the data in ElevatorQueue[0], and reorders the queue accordingly.
  492. for(new i; i < sizeof(ElevatorQueue) - 1; i ++)
  493. ElevatorQueue[i] = ElevatorQueue[i + 1];
  494. ElevatorQueue[sizeof(ElevatorQueue) - 1] = INVALID_FLOOR;
  495. return 1;
  496. }
  497. stock AddFloorToQueue(floorid)
  498. {
  499. // Adds 'floorid' at the end of the queue.
  500. // Scan for the first empty space:
  501. new slot = -1;
  502. for(new i; i < sizeof(ElevatorQueue); i ++)
  503. {
  504. if(ElevatorQueue[i] == INVALID_FLOOR)
  505. {
  506. slot = i;
  507. break;
  508. }
  509. }
  510. if(slot != -1)
  511. {
  512. ElevatorQueue[slot] = floorid;
  513. // If needed, move the elevator.
  514. if(ElevatorState == ELEVATOR_STATE_IDLE)
  515. ReadNextFloorInQueue();
  516. return 1;
  517. }
  518. return 0;
  519. }
  520. stock ResetElevatorQueue()
  521. {
  522. // Resets the queue.
  523. for(new i; i < sizeof(ElevatorQueue); i ++)
  524. {
  525. ElevatorQueue[i] = INVALID_FLOOR;
  526. FloorRequestedBy[i] = INVALID_PLAYER_ID;
  527. }
  528. return 1;
  529. }
  530. stock IsFloorInQueue(floorid)
  531. {
  532. // Checks if the specified floor is currently part of the queue.
  533. for(new i; i < sizeof(ElevatorQueue); i ++)
  534. if(ElevatorQueue[i] == floorid)
  535. return 1;
  536. return 0;
  537. }
  538. stock ReadNextFloorInQueue()
  539. {
  540. // Reads the next floor in the queue, closes doors, and goes to it.
  541. if(ElevatorState != ELEVATOR_STATE_IDLE || ElevatorQueue[0] == INVALID_FLOOR)
  542. return 0;
  543. Elevator_CloseDoors();
  544. Floor_CloseDoors(ElevatorFloor);
  545. return 1;
  546. }
  547. stock DidPlayerRequestElevator(playerid)
  548. {
  549. for(new i; i < sizeof(FloorRequestedBy); i ++)
  550. if(FloorRequestedBy[i] == playerid)
  551. return 1;
  552. return 0;
  553. }
  554. stock ShowElevatorDialog(playerid)
  555. {
  556. new string[512];
  557. for(new i; i < sizeof(ElevatorQueue); i ++)
  558. {
  559. if(FloorRequestedBy[i] != INVALID_PLAYER_ID)
  560. strcat(string, "{FF0000}");
  561. strcat(string, FloorNames[i]);
  562. strcat(string, "\n");
  563. }
  564. ShowPlayerDialog(playerid, DIALOG_ID, DIALOG_STYLE_LIST, "LS BeachSide Elevator...", string, "Accept", "Cancel");
  565. return 1;
  566. }
  567. stock CallElevator(playerid, floorid)
  568. {
  569. // Calls the elevator (also used with the elevator dialog).
  570. if(FloorRequestedBy[floorid] != INVALID_PLAYER_ID || IsFloorInQueue(floorid))
  571. return 0;
  572. FloorRequestedBy[floorid] = playerid;
  573. AddFloorToQueue(floorid);
  574. return 1;
  575. }
  576. stock Float:GetElevatorZCoordForFloor(floorid)
  577. {
  578. // Return Z height value
  579. return (GROUND_Z_COORD + FloorZOffsets[floorid]);
  580. }
  581. stock Float:GetDoorsZCoordForFloor(floorid)
  582. {
  583. // Return Z height value
  584. return (GROUND_Z_COORD + FloorZOffsets[floorid]);
  585. }