CheckpointManager.inc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // Checkpoint Manager
  2. // (c) João Pedro Lopes, All right's reserved
  3. //
  4. // Feel free to change any line above, as long as you post the 'fix' / 'patch' at the forum
  5. // and send a copy to jplopes@live.com.pt
  6. /* natives
  7. native CreateCheckpoint(ownerid, chpid, Float:posX, Float:posY, Float:posZ); // Creates a checkpoint
  8. native SetCheckpointInterior(chpid, interiorid); // Changes the checkpoint interior
  9. native SetCheckpointVirtualWorld(chpid, VirtualWorldID); // Changes the Checkpoint vWorld
  10. native ToggleCheckpointActive(chpid, bool:active); // Deactivates / Activates the checkpoint
  11. native ChangeCheckpointOwner(chpid, owner); // Change the checkpoint owner
  12. native RemoveCheckpoint(chpid); // Removes the specified checkpoint
  13. native StartCheckpointSeeking(); // Starts seeking for each individual
  14. native StopCheckpointSeeking(); // Stops the system
  15. native VerifyCheckpoint(playerid); // Place this at OnPlayerEnterCheckpoint
  16. */
  17. // Function Forwards
  18. forward public OnCheckpointEnter(playerid, checkpointid);
  19. #if defined _CHECKPOINT_MANAGER_INCLUDED
  20. #endinput
  21. #endif
  22. #define _CHECKPOINT_MANAGER_INCLUDED
  23. #pragma library CheckpointManager
  24. #include <a_samp>
  25. #define MAX_CHECKPOINTS 200
  26. #define CHECKPOINT_SEEKER_DELAY 300
  27. #define GLOBAL_OWNER_ID -1
  28. // CHECKPOINT ENUMERATION
  29. enum _checkpointEnum{
  30. _chp_populated, // Is this slot of the memory populated?
  31. _chp_id, // The ID of the checkpoint
  32. _chp_owner, // The ID of the player who this checkpoint is visible too
  33. Float:_chp_posX, // The X position of this checkpoint
  34. Float:_chp_posY, // The Y position of this checkpoint
  35. Float:_chp_posZ, // The Z position of this checkpoint
  36. Float:_chp_size, // The checkpoint size
  37. Float:_chp_viewDistance, // The checkpoint view distance
  38. bool:_chp_active, // Is this checkpoint active?
  39. _chp_interior_id, // The interior id of this checkpoint
  40. _chp_world_id // The world id of this checkpoint
  41. };
  42. // DATA ARRAYS
  43. new _checkpoints[MAX_CHECKPOINTS][_checkpointEnum];
  44. new _p_VisibleCheckpoint[MAX_PLAYERS];
  45. new _chp_manager_timer_id;
  46. // DATA VARIABLES
  47. new _totalCheckpoints;
  48. // --------------------------------------------------------------------------------------------------------
  49. // Creates a new checkpoint with some initial data
  50. stock CreateCheckpoint(__ownerid, __chpid, Float:__posX, Float:__posY, Float:__posZ){
  51. // Max checkpoint reached?
  52. if(_totalCheckpoints == MAX_CHECKPOINTS) return 0;
  53. // First checkpoint? Setting everything to unpopulated
  54. if(!_totalCheckpoints){
  55. for(new i; i < MAX_PLAYERS; i++) _p_VisibleCheckpoint[i] = -1;
  56. for(new i; i < MAX_CHECKPOINTS; i++){
  57. _checkpoints[i][_chp_populated] = false;
  58. }
  59. // Sending the Initialization Info
  60. printf("[Checkpoint Manager : Version 0.1.1b] System Initialized...", __chpid);
  61. }
  62. // Getting the first open slot
  63. new _slot;
  64. for(new i = 0; i < MAX_CHECKPOINTS; i++){
  65. if(!_checkpoints[i][_chp_populated]){
  66. _slot = i;
  67. break;
  68. }
  69. }
  70. // Adding the new checkpoint
  71. _checkpoints[_slot][_chp_populated] = true;
  72. _checkpoints[_slot][_chp_id] = __chpid;
  73. _checkpoints[_slot][_chp_owner] = __ownerid;
  74. _checkpoints[_slot][_chp_posX] = __posX;
  75. _checkpoints[_slot][_chp_posY] = __posY;
  76. _checkpoints[_slot][_chp_posZ] = __posZ;
  77. _checkpoints[_slot][_chp_size] = 5.0;
  78. _checkpoints[_slot][_chp_viewDistance] = 20.0;
  79. _checkpoints[_slot][_chp_active] = true;
  80. _checkpoints[_slot][_chp_interior_id] = 0;
  81. _checkpoints[_slot][_chp_world_id] = 0;
  82. printf("[Checkpoint Manager] Checkpoint created (%d) at slot %d", __chpid, _slot);
  83. printf("Checkpoint Position: { %f, %f, %f }", _checkpoints[_slot][_chp_posX], _checkpoints[_slot][_chp_posY], _checkpoints[_slot][_chp_posZ]);
  84. _totalCheckpoints++;
  85. return 1;
  86. }
  87. //---------------------------------------------------------------------------------------------
  88. stock SetCheckpointInterior(__chpid, __interiorid){
  89. new _slot = __ChpSlotByID(__chpid);
  90. if(_slot > -1){
  91. // Valid slot?
  92. _checkpoints[_slot][_chp_interior_id] = __interiorid;
  93. return 1;
  94. }
  95. return 0;
  96. }
  97. //---------------------------------------------------------------------------------------------
  98. stock SetCheckpointVirtualWorld(__chpid, __virtual_world_id){
  99. new _slot = __ChpSlotByID(__chpid);
  100. if(_slot > -1){
  101. _checkpoints[_slot][_chp_world_id] = __virtual_world_id;
  102. return 1;
  103. }
  104. return 0;
  105. }
  106. stock ToggleCheckpointActive(__chpid, bool:__active){
  107. new _slot = __ChpSlotByID(__chpid);
  108. if(_slot > -1){
  109. _checkpoints[_slot][_chp_active] = __active;
  110. return 1;
  111. }
  112. return 0;
  113. }
  114. stock ChangeCheckpointOwner(__chpid, __owner){
  115. new _slot = __ChpSlotByID(__chpid);
  116. if(_slot > -1){
  117. _checkpoints[_slot][_chp_owner] = __owner;
  118. return 1;
  119. }
  120. return 0;
  121. }
  122. stock RemoveCheckpoint(__chpid){
  123. new _slot = __ChpSlotByID(__chpid);
  124. if(_slot > -1){
  125. // Deleting the checkpoint
  126. _checkpoints[_slot][_chp_populated] = false;
  127. _checkpoints[_slot][_chp_id] = -1;
  128. _checkpoints[_slot][_chp_owner] = 255;
  129. _checkpoints[_slot][_chp_posX] = -1;
  130. _checkpoints[_slot][_chp_posY] = -1;
  131. _checkpoints[_slot][_chp_posZ] = -1;
  132. _checkpoints[_slot][_chp_size] = -1;
  133. _checkpoints[_slot][_chp_viewDistance] = -1;
  134. _checkpoints[_slot][_chp_active] = false;
  135. _checkpoints[_slot][_chp_interior_id] = -1;
  136. _checkpoints[_slot][_chp_world_id] = -1;
  137. _totalCheckpoints--;
  138. printf("\n[Checkpoint Manager] Checkpoint removed (ID: %d)", __chpid);
  139. return 1;
  140. }
  141. return 0;
  142. }
  143. //---------------------------------------------------------------------------------------------
  144. // Gets the checkpoint slot by id
  145. stock __ChpSlotByID(__chpid){
  146. for(new i; i < MAX_CHECKPOINTS; i++){
  147. if(_checkpoints[i][_chp_id] == __chpid) return i;
  148. }
  149. return -1;
  150. }
  151. forward CheckpointSeeker();
  152. stock StartCheckpointSeeking(){
  153. _chp_manager_timer_id = SetTimer("CheckpointSeeker", CHECKPOINT_SEEKER_DELAY, 1);
  154. return 1;
  155. }
  156. stock StopCheckpointSeeking(){
  157. KillTimer(_chp_manager_timer_id);
  158. return 1;
  159. }
  160. public CheckpointSeeker(){
  161. new Float:__posX, Float:__posY, Float:__posZ;
  162. new __interior;
  163. new __virtualWorld;
  164. for(new i; i < MAX_PLAYERS; i++)
  165. {
  166. if(!IsPlayerConnected(i)) continue;
  167. GetPlayerPos(i, Float:__posX, Float:__posY, Float:__posZ);
  168. // Is the player near a checkpoint?
  169. if(_p_VisibleCheckpoint[i] > -1)
  170. {
  171. // If the player is no longer near that point
  172. if(__posX < (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posX] - _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])
  173. || __posX > (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posX] + _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])
  174. || __posY < (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posY] - _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])
  175. || __posY > (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posY] + _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])){
  176. DisablePlayerCheckpoint(i);
  177. _p_VisibleCheckpoint[i] = -1;
  178. }
  179. }
  180. else
  181. {
  182. // Getting the player Interior and virtual world
  183. __interior = GetPlayerInterior(i);
  184. __virtualWorld = GetPlayerVirtualWorld(i);
  185. // Looking for a new checkpoint
  186. for(new j = 0; j < MAX_CHECKPOINTS; j++){
  187. if(!_checkpoints[j][_chp_populated]) continue;
  188. if((_checkpoints[j][_chp_owner] != i) && (_checkpoints[j][_chp_owner] != -1)) continue;
  189. if(_checkpoints[j][_chp_interior_id] != __interior) continue;
  190. if(_checkpoints[j][_chp_world_id] != __virtualWorld) continue;
  191. if(__posX > (_checkpoints[j][_chp_posX] - _checkpoints[j][_chp_viewDistance])
  192. && __posX < (_checkpoints[j][_chp_posX] + _checkpoints[j][_chp_viewDistance])
  193. && __posY > (_checkpoints[j][_chp_posY] - _checkpoints[j][_chp_viewDistance])
  194. && __posY < (_checkpoints[j][_chp_posY] + _checkpoints[j][_chp_viewDistance])){
  195. SetPlayerCheckpoint(i, _checkpoints[j][_chp_posX], _checkpoints[j][_chp_posY], _checkpoints[j][_chp_posZ], _checkpoints[j][_chp_size]);
  196. _p_VisibleCheckpoint[i] = j;
  197. break;
  198. }
  199. }
  200. }
  201. }
  202. return 1;
  203. }
  204. stock VerifyCheckpoint(__playerid){
  205. if(_p_VisibleCheckpoint[__playerid] >= 0){
  206. OnCheckpointEnter(__playerid, _checkpoints[_p_VisibleCheckpoint[__playerid]][_chp_id]);
  207. return 1;
  208. }
  209. return 0;
  210. }