CameraMover.inc 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * Southclaw's Cinematic Camera Script
  3. *
  4. * Version 2.5
  5. *
  6. * Easy file loaded data
  7. * Easy to create cameras
  8. * Edit data without recompiling script!
  9. * Full editor support added (Editor is now an FS)
  10. * Shift data array functions
  11. * More controls
  12. * Project editor coming soon!
  13. */
  14. #include <sscanf2>
  15. // Generic Definitions
  16. #define YELLOW 0xFFFF00FF
  17. #define RED 0xAA3333AA
  18. #define Msg SendClientMessage // I'm not the only one this lazy right?
  19. #define MAX_CAMERAS 16 // Max cameras that can be loaded at once
  20. #define MAX_CAMNODE 16 // Max camera nodes that can be loaded for one camera
  21. #define MAX_CAMFILE_LEN 64 // Length for file names in loading and saving
  22. #define MAX_CAMDATA 9 // Amount data of cells in cam_Data
  23. #define CAMERA_FILE "Cameras/%s.cam"
  24. #define DEFAULT_MOVETIME 3000
  25. #define DEFAULT_WAITTIME 0
  26. #define DEFAULT_MOVETYPE CAMERA_MOVE
  27. enum ENUM_DATA_TYPES
  28. {
  29. p_CamID,
  30. p_Node
  31. }
  32. enum CAM_DATA_ENUM
  33. {
  34. Float:cam_cPosX, // Position coords
  35. Float:cam_cPosY,
  36. Float:cam_cPosZ,
  37. Float:cam_lPosX, // Lookat coords
  38. Float:cam_lPosY,
  39. Float:cam_lPosZ,
  40. cam_moveTime, // Time in MS to move between each node
  41. cam_waitTime, // Time in MS to wait before moving
  42. cam_moveType // Camera move type (Cut or Move)
  43. }
  44. new
  45. camData[MAX_CAMERAS][MAX_CAMNODE][CAM_DATA_ENUM],
  46. camFilename[MAX_CAMERAS][MAX_CAMFILE_LEN],
  47. camNodeTimer[MAX_CAMERAS], // For stopping the timer when the camera pauses
  48. camMaxNodes[MAX_CAMERAS], // Maximum nodes for this camera
  49. bool:camIdUsed[MAX_CAMERAS], // Determines whether the ID is used or not
  50. bool:camPaused[MAX_CAMERAS], // Determines whether the camera is paused
  51. bool:camMoving[MAX_CAMERAS], // True whem the camera moves from one node to another
  52. gPlayerCamData[MAX_PLAYERS][ENUM_DATA_TYPES],
  53. Float:camPausePos[MAX_CAMERAS][6];
  54. forward internal_OnCamMove(playerid, node, bool:cont);
  55. forward OnCameraReachNode(playerid, camera, node);
  56. forward UpdateFreeCam(playerid);
  57. stock LoadCameraMover(filename[])
  58. {
  59. new id;
  60. while(camIdUsed[id] && id<=MAX_CAMERAS)id++;
  61. if(id == MAX_CAMERAS)return print("ERROR: Camera ID limit reached");
  62. #define TMP_LOAD (0) // The cell that SSCANF loads into
  63. #define TMP_KEEP (1) // The cell that carries over to the next loop itteration
  64. #define TMP_DATA_COUNT (3) // Number of cells in 'tmpData'
  65. format(camFilename[id], MAX_CAMFILE_LEN, "Cameras/%s.cam", filename);
  66. if(!fexist(camFilename[id]))return printf("ERROR: Camera data file '%s' not found", camFilename[id]);
  67. new
  68. File:camFile,
  69. line[128],
  70. idx,
  71. tmpData[2][TMP_DATA_COUNT]; // optional data: cam_moveTime, cam_waitTime, cam_moveType
  72. // Default values in case no values are defined in the file
  73. tmpData[1][0] = 3000;
  74. tmpData[1][1] = 0;
  75. tmpData[1][2] = CAMERA_MOVE;
  76. camFile = fopen(camFilename[id], io_read);
  77. while(fread(camFile, line, 128))
  78. {
  79. if (idx == MAX_CAMNODE)
  80. {
  81. print("ERROR: Camera node limit reached");
  82. break;
  83. }
  84. if (!sscanf(line, "p<,>ffffffD(-1)D(-1)D(-1)", // Too much for one line
  85. camData[id][idx][cam_cPosX], camData[id][idx][cam_cPosY], camData[id][idx][cam_cPosZ],
  86. camData[id][idx][cam_lPosX], camData[id][idx][cam_lPosY], camData[id][idx][cam_lPosZ],
  87. tmpData[TMP_LOAD][0], tmpData[TMP_LOAD][1], tmpData[TMP_LOAD][2] ))
  88. {
  89. for(new c;c<TMP_DATA_COUNT;c++) // c = cell reference
  90. {
  91. if (tmpData[TMP_LOAD][c] == -1) tmpData[TMP_LOAD][c] = tmpData[TMP_KEEP][c]; // If it an optional param has -1 set it's detault value
  92. else tmpData[TMP_KEEP][c] = tmpData[TMP_LOAD][c]; // Otherwise set the default value to the value just read
  93. // This method means that you can define timings for a set of coordinates
  94. // simply by defining the top one as what you want and leaving the rest blank
  95. // These settings will be default until the next line is found with optional params
  96. }
  97. camData[id][idx][cam_moveTime] = tmpData[TMP_LOAD][0]; // Set the values to the global array cell of this camera
  98. camData[id][idx][cam_waitTime] = tmpData[TMP_LOAD][1];
  99. camData[id][idx][cam_moveType] = tmpData[TMP_LOAD][2];
  100. }
  101. idx++;
  102. }
  103. camMaxNodes[id] = idx - 1;
  104. camIdUsed[id] = true;
  105. fclose(camFile);
  106. return id;
  107. }
  108. stock ClearCameraID(id)
  109. {
  110. for(new n;n<=camMaxNodes[camera];n++)
  111. for(new e;e<sizeof(camData[id][n]);e++)
  112. camData[id][n][CAM_DATA_ENUM:e]=0;
  113. camNodeTimer[id] = -1;
  114. camMaxNodes[id] = 0;
  115. camIdUsed[id] = false;
  116. camPaused[id] = false;
  117. camMoving[id] = false;
  118. gPlayerCamData[id] = {0, ...}
  119. camPausePos[id] = {0.0, ...}
  120. }
  121. stock PlayCameraMover(playerid, camera, startnode=0)
  122. {
  123. gPlayerCamData[playerid][p_Node] = startnode;
  124. gPlayerCamData[playerid][p_CamID] = camera;
  125. TogglePlayerControllable(playerid, false);
  126. MoveCameraToNextNode(playerid);
  127. }
  128. stock PauseCameraMover(playerid)
  129. {
  130. new
  131. tmpCam = gPlayerCamData[playerid][p_CamID],
  132. Float:vX,
  133. Float:vY,
  134. Float:vZ;
  135. GetPlayerCameraPos(playerid, camPausePos[tmpCam][0], camPausePos[tmpCam][1], camPausePos[tmpCam][2]);
  136. GetPlayerCameraFrontVector(playerid, vX, vY, vZ);
  137. camPausePos[tmpCam][3]=camPausePos[tmpCam][0]+vX;
  138. camPausePos[tmpCam][4]=camPausePos[tmpCam][1]+vZ;
  139. camPausePos[tmpCam][5]=camPausePos[tmpCam][2]+vZ;
  140. SetPlayerCameraPos(playerid, camPausePos[tmpCam][0], camPausePos[tmpCam][1], camPausePos[tmpCam][2]);
  141. SetPlayerCameraLookAt(playerid, camPausePos[tmpCam][3], camPausePos[tmpCam][4], camPausePos[tmpCam][5]);
  142. if(camNodeTimer[tmpCam]!=-1)KillTimer(camNodeTimer[tmpCam]);
  143. camPaused[tmpCam]=true;
  144. }
  145. MoveCameraToNextNode(playerid, bool:editing = false)
  146. {
  147. new
  148. tmpCam = gPlayerCamData[playerid][p_CamID],
  149. tmpNode = gPlayerCamData[playerid][p_Node],
  150. nextNode = tmpNode+1;
  151. if(nextNode > camMaxNodes[tmpCam])return 1; // Player has reached the last node
  152. if(camPaused[tmpCam]) // Move the camera from the paused position
  153. {
  154. InterpolateCameraPos(playerid,
  155. camPausePos[tmpCam][0], camPausePos[tmpCam][1], camPausePos[tmpCam][2],
  156. camData[tmpCam][nextNode][cam_cPosX], camData[tmpCam][nextNode][cam_cPosY], camData[tmpCam][nextNode][cam_cPosZ],
  157. camData[tmpCam][tmpNode][cam_moveTime], camData[tmpCam][tmpNode][cam_moveType]);
  158. InterpolateCameraLookAt(playerid,
  159. camPausePos[tmpCam][3], camPausePos[tmpCam][4], camPausePos[tmpCam][5],
  160. camData[tmpCam][nextNode][cam_lPosX], camData[tmpCam][nextNode][cam_lPosY], camData[tmpCam][nextNode][cam_lPosZ],
  161. camData[tmpCam][tmpNode][cam_moveTime], camData[tmpCam][tmpNode][cam_moveType]);
  162. camPausePos[tmpCam][0]=0.0;
  163. camPausePos[tmpCam][1]=0.0;
  164. camPausePos[tmpCam][2]=0.0;
  165. camPausePos[tmpCam][3]=0.0;
  166. camPausePos[tmpCam][4]=0.0;
  167. camPausePos[tmpCam][5]=0.0;
  168. camPaused[tmpCam] = false;
  169. }
  170. else // Move the camera from the node
  171. {
  172. InterpolateCameraPos(playerid,
  173. camData[tmpCam][tmpNode][cam_cPosX], camData[tmpCam][tmpNode][cam_cPosY], camData[tmpCam][tmpNode][cam_cPosZ],
  174. camData[tmpCam][nextNode][cam_cPosX], camData[tmpCam][nextNode][cam_cPosY], camData[tmpCam][nextNode][cam_cPosZ],
  175. camData[tmpCam][tmpNode][cam_moveTime], camData[tmpCam][tmpNode][cam_moveType]);
  176. InterpolateCameraLookAt(playerid,
  177. camData[tmpCam][tmpNode][cam_lPosX], camData[tmpCam][tmpNode][cam_lPosY], camData[tmpCam][tmpNode][cam_lPosZ],
  178. camData[tmpCam][nextNode][cam_lPosX], camData[tmpCam][nextNode][cam_lPosY], camData[tmpCam][nextNode][cam_lPosZ],
  179. camData[tmpCam][tmpNode][cam_moveTime], camData[tmpCam][tmpNode][cam_moveType]);
  180. }
  181. TogglePlayerControllable(playerid, false);
  182. SetPlayerPos(playerid, camData[tmpCam][nextNode][cam_lPosX], camData[tmpCam][nextNode][cam_lPosY], camData[tmpCam][nextNode][cam_lPosZ]-50.0);
  183. CallLocalFunction("OnCameraLeaveNode", "ddd", playerid, tmpCam, tmpNode);
  184. if(!editing)camNodeTimer[tmpCam] = SetTimerEx("internal_OnCamMove", camData[tmpCam][tmpNode][cam_moveTime], false, "ddd", playerid, nextNode, true);
  185. else camNodeTimer[tmpCam] = SetTimerEx("editor_OnCamMove", camData[tmpCam][tmpNode][cam_moveTime], false, "ddd", playerid, nextNode, false);
  186. return 1;
  187. }
  188. public internal_OnCamMove(playerid, node, bool:cont)
  189. {
  190. new
  191. tmpCam = gPlayerCamData[playerid][p_CamID],
  192. externResult;
  193. externResult = CallLocalFunction("OnCameraReachNode", "ddd", playerid, tmpCam, node);
  194. gPlayerCamData[playerid][p_Node]++;
  195. if(externResult)cont = false;
  196. if(cont && node <= camMaxNodes[tmpCam])
  197. {
  198. MoveCameraToNextNode(playerid);
  199. }
  200. return 1;
  201. }
  202. // Returning data to be used externally
  203. /*
  204. cam_moveTime, // Time in MS to move between each node
  205. cam_waitTime, // Time in MS to wait before moving
  206. cam_moveType // Camera move type (Cut or Move)
  207. */
  208. stock GetCameraNodeMoveTime(camera, node)
  209. return camData[camera][node][cam_moveTime];
  210. stock GetCameraNodeWaitTime(camera, node)
  211. return camData[camera][node][cam_waitTime];
  212. stock GetCameraNodeMoveType(camera, node)
  213. return camData[camera][node][cam_moveType];
  214. stock SetCameraNodeMoveTime(camera, node, time)
  215. camData[camera][node][cam_moveTime] = time;
  216. stock SetCameraNodeWaitTime(camera, node, time)
  217. camData[camera][node][cam_waitTime] = time;
  218. stock SetCameraNodeMoveType(camera, node, type)
  219. camData[camera][node][cam_moveType] = type;
  220. stock GetCameraMaxNodes(camera)
  221. return camMaxNodes[camera];
  222. stock GetPlayerCameraID(playerid)
  223. return gPlayerCamData[playerid][p_CamID];
  224. stock GetPlayerCurrentNode(playerid)
  225. return gPlayerCamData[playerid][p_Node];
  226. stock IsCameraValid(camera)
  227. return camIdUsed[p_CamID];
  228. stock IsCameraPaused(camera)
  229. return camPaused[p_CamID];
  230. stock IsCameraMoving(camera)
  231. return camMoving[p_CamID];