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.

265 lines
7.3 KiB

5 years ago
  1. //-------------------------------------------------
  2. //
  3. // This is an example of using the AttachCameraToObject function
  4. // to create a no-clip flying camera.
  5. //
  6. // h02 2012
  7. //
  8. // SA-MP 0.3e and above
  9. //
  10. //-------------------------------------------------
  11. #include <a_samp>
  12. // Players Move Speed
  13. #define MOVE_SPEED 100.0
  14. #define ACCEL_RATE 0.03
  15. // Players Mode
  16. #define CAMERA_MODE_NONE 0
  17. #define CAMERA_MODE_FLY 1
  18. // Key state definitions
  19. #define MOVE_FORWARD 1
  20. #define MOVE_BACK 2
  21. #define MOVE_LEFT 3
  22. #define MOVE_RIGHT 4
  23. #define MOVE_FORWARD_LEFT 5
  24. #define MOVE_FORWARD_RIGHT 6
  25. #define MOVE_BACK_LEFT 7
  26. #define MOVE_BACK_RIGHT 8
  27. // Enumeration for storing data about the player
  28. enum noclipenum
  29. {
  30. cameramode,
  31. flyobject,
  32. mode,
  33. lrold,
  34. udold,
  35. lastmove,
  36. Float:accelmul
  37. }
  38. new noclipdata[MAX_PLAYERS][noclipenum];
  39. //--------------------------------------------------
  40. public OnFilterScriptExit()
  41. {
  42. // If any players are still in edit mode, boot them out before the filterscript unloads
  43. for(new x; x<MAX_PLAYERS; x++)
  44. {
  45. if(noclipdata[x][cameramode] == CAMERA_MODE_FLY) CancelFlyMode(x);
  46. }
  47. return 1;
  48. }
  49. //--------------------------------------------------
  50. public OnPlayerConnect(playerid)
  51. {
  52. // Reset the data belonging to this player slot
  53. noclipdata[playerid][cameramode] = CAMERA_MODE_NONE;
  54. noclipdata[playerid][lrold] = 0;
  55. noclipdata[playerid][udold] = 0;
  56. noclipdata[playerid][mode] = 0;
  57. noclipdata[playerid][lastmove] = 0;
  58. noclipdata[playerid][accelmul] = 0.0;
  59. return 1;
  60. }
  61. //--------------------------------------------------
  62. public OnPlayerCommandText(playerid, cmdtext[])
  63. {
  64. if(!strcmp(cmdtext, "/flymode", true))
  65. {
  66. // Place the player in and out of edit mode
  67. if(GetPVarType(playerid, "FlyMode")) CancelFlyMode(playerid);
  68. else FlyMode(playerid);
  69. return 1;
  70. }
  71. return 0;
  72. }
  73. //--------------------------------------------------
  74. public OnPlayerUpdate(playerid)
  75. {
  76. if(noclipdata[playerid][cameramode] == CAMERA_MODE_FLY)
  77. {
  78. new keys,ud,lr;
  79. GetPlayerKeys(playerid,keys,ud,lr);
  80. if(noclipdata[playerid][mode] && (GetTickCount() - noclipdata[playerid][lastmove] > 100))
  81. {
  82. // If the last move was > 100ms ago, process moving the object the players camera is attached to
  83. MoveCamera(playerid);
  84. }
  85. // Is the players current key state different than their last keystate?
  86. if(noclipdata[playerid][udold] != ud || noclipdata[playerid][lrold] != lr)
  87. {
  88. if((noclipdata[playerid][udold] != 0 || noclipdata[playerid][lrold] != 0) && ud == 0 && lr == 0)
  89. { // All keys have been released, stop the object the camera is attached to and reset the acceleration multiplier
  90. StopPlayerObject(playerid, noclipdata[playerid][flyobject]);
  91. noclipdata[playerid][mode] = 0;
  92. noclipdata[playerid][accelmul] = 0.0;
  93. }
  94. else
  95. { // Indicates a new key has been pressed
  96. // Get the direction the player wants to move as indicated by the keys
  97. noclipdata[playerid][mode] = GetMoveDirectionFromKeys(ud, lr);
  98. // Process moving the object the players camera is attached to
  99. MoveCamera(playerid);
  100. }
  101. }
  102. noclipdata[playerid][udold] = ud; noclipdata[playerid][lrold] = lr; // Store current keys pressed for comparison next update
  103. return 0;
  104. }
  105. return 1;
  106. }
  107. //--------------------------------------------------
  108. stock GetMoveDirectionFromKeys(ud, lr)
  109. {
  110. new direction = 0;
  111. if(lr < 0)
  112. {
  113. if(ud < 0) direction = MOVE_FORWARD_LEFT; // Up & Left key pressed
  114. else if(ud > 0) direction = MOVE_BACK_LEFT; // Back & Left key pressed
  115. else direction = MOVE_LEFT; // Left key pressed
  116. }
  117. else if(lr > 0) // Right pressed
  118. {
  119. if(ud < 0) direction = MOVE_FORWARD_RIGHT; // Up & Right key pressed
  120. else if(ud > 0) direction = MOVE_BACK_RIGHT; // Back & Right key pressed
  121. else direction = MOVE_RIGHT; // Right key pressed
  122. }
  123. else if(ud < 0) direction = MOVE_FORWARD; // Up key pressed
  124. else if(ud > 0) direction = MOVE_BACK; // Down key pressed
  125. return direction;
  126. }
  127. //--------------------------------------------------
  128. stock MoveCamera(playerid)
  129. {
  130. new Float:FV[3], Float:CP[3];
  131. GetPlayerCameraPos(playerid, CP[0], CP[1], CP[2]); // Cameras position in space
  132. GetPlayerCameraFrontVector(playerid, FV[0], FV[1], FV[2]); // Where the camera is looking at
  133. // Increases the acceleration multiplier the longer the key is held
  134. if(noclipdata[playerid][accelmul] <= 1) noclipdata[playerid][accelmul] += ACCEL_RATE;
  135. // Determine the speed to move the camera based on the acceleration multiplier
  136. new Float:speed = MOVE_SPEED * noclipdata[playerid][accelmul];
  137. // Calculate the cameras next position based on their current position and the direction their camera is facing
  138. new Float:X, Float:Y, Float:Z;
  139. GetNextCameraPosition(noclipdata[playerid][mode], CP, FV, X, Y, Z);
  140. MovePlayerObject(playerid, noclipdata[playerid][flyobject], X, Y, Z, speed);
  141. // Store the last time the camera was moved as now
  142. noclipdata[playerid][lastmove] = GetTickCount();
  143. return 1;
  144. }
  145. //--------------------------------------------------
  146. stock GetNextCameraPosition(move_mode, Float:CP[3], Float:FV[3], &Float:X, &Float:Y, &Float:Z)
  147. {
  148. // Calculate the cameras next position based on their current position and the direction their camera is facing
  149. #define OFFSET_X (FV[0]*6000.0)
  150. #define OFFSET_Y (FV[1]*6000.0)
  151. #define OFFSET_Z (FV[2]*6000.0)
  152. switch(move_mode)
  153. {
  154. case MOVE_FORWARD:
  155. {
  156. X = CP[0]+OFFSET_X;
  157. Y = CP[1]+OFFSET_Y;
  158. Z = CP[2]+OFFSET_Z;
  159. }
  160. case MOVE_BACK:
  161. {
  162. X = CP[0]-OFFSET_X;
  163. Y = CP[1]-OFFSET_Y;
  164. Z = CP[2]-OFFSET_Z;
  165. }
  166. case MOVE_LEFT:
  167. {
  168. X = CP[0]-OFFSET_Y;
  169. Y = CP[1]+OFFSET_X;
  170. Z = CP[2];
  171. }
  172. case MOVE_RIGHT:
  173. {
  174. X = CP[0]+OFFSET_Y;
  175. Y = CP[1]-OFFSET_X;
  176. Z = CP[2];
  177. }
  178. case MOVE_BACK_LEFT:
  179. {
  180. X = CP[0]+(-OFFSET_X - OFFSET_Y);
  181. Y = CP[1]+(-OFFSET_Y + OFFSET_X);
  182. Z = CP[2]-OFFSET_Z;
  183. }
  184. case MOVE_BACK_RIGHT:
  185. {
  186. X = CP[0]+(-OFFSET_X + OFFSET_Y);
  187. Y = CP[1]+(-OFFSET_Y - OFFSET_X);
  188. Z = CP[2]-OFFSET_Z;
  189. }
  190. case MOVE_FORWARD_LEFT:
  191. {
  192. X = CP[0]+(OFFSET_X - OFFSET_Y);
  193. Y = CP[1]+(OFFSET_Y + OFFSET_X);
  194. Z = CP[2]+OFFSET_Z;
  195. }
  196. case MOVE_FORWARD_RIGHT:
  197. {
  198. X = CP[0]+(OFFSET_X + OFFSET_Y);
  199. Y = CP[1]+(OFFSET_Y - OFFSET_X);
  200. Z = CP[2]+OFFSET_Z;
  201. }
  202. }
  203. }
  204. //--------------------------------------------------
  205. stock CancelFlyMode(playerid)
  206. {
  207. DeletePVar(playerid, "FlyMode");
  208. CancelEdit(playerid);
  209. TogglePlayerSpectating(playerid, false);
  210. DestroyPlayerObject(playerid, noclipdata[playerid][flyobject]);
  211. noclipdata[playerid][cameramode] = CAMERA_MODE_NONE;
  212. return 1;
  213. }
  214. //--------------------------------------------------
  215. stock FlyMode(playerid)
  216. {
  217. // Create an invisible object for the players camera to be attached to
  218. new Float:X, Float:Y, Float:Z;
  219. GetPlayerPos(playerid, X, Y, Z);
  220. noclipdata[playerid][flyobject] = CreatePlayerObject(playerid, 19300, X, Y, Z, 0.0, 0.0, 0.0);
  221. // Place the player in spectating mode so objects will be streamed based on camera location
  222. TogglePlayerSpectating(playerid, true);
  223. // Attach the players camera to the created object
  224. AttachCameraToPlayerObject(playerid, noclipdata[playerid][flyobject]);
  225. SetPVarInt(playerid, "FlyMode", 1);
  226. noclipdata[playerid][cameramode] = CAMERA_MODE_FLY;
  227. return 1;
  228. }
  229. //--------------------------------------------------