fork download
  1. //AutoPilot script by Gamer_Z v0.2
  2. #include <a_samp>//SA:MP Team
  3. #define FILTERSCRIPT
  4. #include <RouteConnector>//GPS Plugin
  5. #include <zcmd>//By Zeex
  6. ////////////////////////////////////////////////////////////////////////////////
  7. //#define USE_TIMERS
  8. #define USE_SMOOTH_TURNS // thanks to richardcor91 for the SetVehicleAngularVelocity help
  9. ////////////////////////////////////////////////////////////////////////////////
  10. new id[MAX_PLAYERS] = {-1,...};
  11. new CurrTarget[MAX_PLAYERS] = {0,...};
  12. new Timer[MAX_PLAYERS] = {-1,...};
  13. new Float:spd[MAX_PLAYERS] = {0.30,...};
  14. #if defined USE_TIMERS
  15. new interval[MAX_PLAYERS] = {250,...};
  16. #endif
  17. ////////////////////////////////////////////////////////////////////////////////
  18. enum location
  19. {
  20. name[16],
  21. Float:X,
  22. Float:Y,
  23. Float:Z
  24. }
  25.  
  26. #define PLACES (6)
  27. new places[PLACES][location] =
  28. {
  29. {"LV-c",2140.6675,993.1867,10.5248},//Las Venturas
  30. {"SF-c",-2261.2009,564.2894,34.7200},//San Frierro
  31. {"LS-c",2495.3755,-1669.4906,13.5163},//Los Santos
  32. {"LV-a",1686.3107,1609.5485,10.8203},//Las Venturas Airport
  33. {"SF-a",-1538.8635,-422.9142,5.8516},//San Frierro Airport
  34. {"LS-a",1953.5204,-2290.1130,13.5469}//Los Santos Airport
  35. };
  36. ////////////////////////////////////////////////////////////////////////////////
  37. CMD:autopilot(playerid,params[])
  38. {
  39. if(!IsPlayerInAnyVehicle(playerid))
  40. {
  41. SendClientMessage(playerid,-1,"AUTOPILOT YOU MUST BE IN A VEHICLE");
  42. return 1;
  43. }
  44. if(!strcmp(params,"stop",true))
  45. {
  46. if(Timer[playerid] != (-1))
  47. {
  48. #if defined USE_TIMERS
  49. KillTimer(Timer[playerid]);
  50. #endif
  51. Timer[playerid] = -1;
  52. DeleteArray(id[playerid]);
  53. id[playerid] = -1;
  54. CurrTarget[playerid] = 0;
  55. SendClientMessage(playerid,-1,"AUTOPILOT DISABLED");
  56. return 1;
  57. }
  58. SendClientMessage(playerid,-1,"AUTOPILOT COULDN'T BE DISABLED");
  59. return 1;
  60. }
  61. if(params[0] == 48 && params[1] == 46)
  62. {
  63. if(id[playerid] == -1)
  64. {
  65. new out[32];
  66. if(!isNumeric(params[2]))
  67. {
  68. SendClientMessage(playerid,-1,"AUTOPILOT SPEED MUST BE BETWEEN 0.01 and 0.80");
  69. return 1;
  70. }
  71. if(!isNumeric(params[3]))
  72. params[3] = 48;
  73. format(out,32,"%c%c",params[2],params[3]);
  74. new Float:tmpspd = floatdiv(strval(out),100.00);
  75. if(0.01 > tmpspd > 0.80)
  76. {
  77. SendClientMessage(playerid,-1,"AUTOPILOT SPEED MUST BE BETWEEN 0.01 and 0.80");
  78. return 1;
  79. }
  80. spd[playerid] = tmpspd;
  81. format(out,32,"AUTOPILOT SPEED SET TO: %.3f",spd[playerid]);
  82. SendClientMessage(playerid,-1,out);
  83. }
  84. else
  85. {
  86. SendClientMessage(playerid,-1,"AUTOPILOT CANNOT CHANGE SPEED WHILE DRIVING (bug prevention)");
  87. }
  88. return 1;
  89. }
  90.  
  91. if(id[playerid] == -1)
  92. {
  93. if (params[0] == 0 || (params[0] == 1 && params[1] == 0))
  94. {
  95. SendClientMessage(playerid,-1,"AUTOPILOT HAS NO TARGET");
  96. return 1;
  97. }
  98. new place = -1;
  99. for(new i = 0; i < PLACES; ++i)
  100. {
  101. if(!strcmp(places[i][name],params,true))
  102. {
  103. place = i;
  104. break;
  105. }
  106. }
  107. if(place == -1)
  108. {
  109. SendClientMessage(playerid,-1,"AUTOPILOT DOESN'T KNOW THAT PLACE");
  110. return 1;
  111. }
  112. new start = NearestPlayerNode(playerid,15.0);
  113. if(start == -1)
  114. {
  115. SendClientMessage(playerid,-1,"AUTOPILOT MALFUNCTION, PLEASE TRY AGAIN ON ANOTHER PLACE");
  116. return 1;
  117. }
  118. CalculatePath(start,NearestNodeFromPoint(places[place][X],places[place][Y],places[place][Z]),playerid);
  119. SendClientMessage(playerid,-1,"AUTOPILOT IS CALCULATING THE ROUTE FOR YOU..");
  120. return 1;
  121. }
  122. SendClientMessage(playerid,-1,"AUTOPILOT ALREADY TURNED ON");
  123. return 1;
  124. }
  125.  
  126. CMD:ap(playerid,params[])
  127. {
  128. return cmd_autopilot(playerid,params);
  129. }
  130.  
  131. stock isNumeric(const string[])
  132. {
  133. new length=strlen(string);
  134. if (length==0) return false;
  135. for (new i = 0; i < length; i++)
  136. {
  137. if (
  138. (string[i] > '9' || string[i] < '0' && string[i]!='-' && string[i]!='+') // Not a number,'+' or '-'
  139. || (string[i]=='-' && i!=0) // A '-' but not at first.
  140. || (string[i]=='+' && i!=0) // A '+' but not at first.
  141. ) return false;
  142. }
  143. if (length==1 && (string[0]=='-' || string[0]=='+')) return false;
  144. return true;
  145. }
  146.  
  147. #if defined USE_TIMERS
  148. CMD:interval(playerid,params[])
  149. {
  150. interval[playerid] = strval(params);
  151. format(string,128,"Interval: %d",interval);
  152. SendClientMessage(playerid,-1,string);
  153. return 1;
  154. }
  155. #endif
  156. ////////////////////////////////////////////////////////////////////////////////
  157. public GPS_WhenRouteIsCalculated(routeid,node_id_array[],amount_of_nodes,distance)
  158. {
  159. id[routeid] = StoreRouteArray(amount_of_nodes,node_id_array);
  160. #if defined USE_TIMERS
  161. Timer[routeid] = SetTimerEx("AutoPilot",interval[routeid],1,"i",routeid);
  162. #else
  163. Timer[routeid] = 1;
  164. #endif
  165. SendClientMessage(routeid,-1,".. AUTOPILOT WILL DRIVE YOU NOW TO YOUR DESTINATION");
  166. return 1;
  167. }
  168.  
  169. #if defined USE_TIMERS
  170.  
  171. #else
  172. public OnPlayerUpdate(playerid)
  173. {
  174. if(Timer[playerid] == 1)
  175. AutoPilot(playerid);
  176. return 1;
  177. }
  178. #endif
  179.  
  180. public OnPlayerConnect(playerid)
  181. {
  182. Timer[playerid] = -1;
  183. id[playerid] = -1;
  184. CurrTarget[playerid] = 0;
  185. #if defined USE_TIMERS
  186. interval[playerid] = 250;
  187. #endif
  188. return 1;
  189. }
  190.  
  191. public OnPlayerDisconnect(playerid,reason)
  192. {
  193. if(Timer[playerid] != (-1))
  194. {
  195. #if defined USE_TIMERS
  196. KillTimer(Timer[playerid]);
  197. #endif
  198. Timer[playerid] = -1;
  199. DeleteArray(id[playerid]);
  200. id[playerid] = -1;
  201. CurrTarget[playerid] = 0;
  202. }
  203. return 1;
  204. }
  205.  
  206. forward AutoPilot(playerid);
  207. public AutoPilot(playerid)
  208. {
  209. if(IsPlayerInAnyVehicle(playerid))
  210. {
  211. new Float:pos[2][3];
  212. new vehicleid = GetPlayerVehicleID(playerid);
  213. if(CurrTarget[playerid] == 0)
  214. {
  215. CurrTarget[playerid]++;
  216. GetNodePos(GetRouteAtPos(id[playerid],CurrTarget[playerid]),pos[0][0],pos[0][1],pos[0][2]);
  217. SetVehiclePos(vehicleid,pos[0][0],pos[0][1],pos[0][2]+2.0);
  218. return 1;
  219. }
  220. new amount;
  221. new nodeid = GetRouteAtPos(id[playerid],CurrTarget[playerid],amount);
  222. if((CurrTarget[playerid]+1) >= amount)
  223. {
  224. #if defined USE_TIMERS
  225. KillTimer(Timer[playerid]);
  226. #endif
  227. Timer[playerid] = -1;
  228. DeleteArray(id[playerid]);
  229. id[playerid] = -1;
  230. CurrTarget[playerid] = 0;
  231. SetVehicleVelocity(vehicleid,0.0,0.0,0.0);
  232. SendClientMessage(playerid,-1,"Destination reached, have a nice day.");
  233. return 1;
  234. }
  235. GetNodePos(nodeid,pos[1][0],pos[1][1],pos[1][2]);
  236. if(IsPlayerInRangeOfPoint(playerid,10.0,pos[1][0],pos[1][1],pos[1][2]))
  237. {
  238. CurrTarget[playerid]++;
  239. return 1;
  240. }
  241. PullVehicleIntoDirection(vehicleid,pos[1][0],pos[1][1],pos[1][2],spd[playerid]);
  242. }
  243. else
  244. {
  245. #if defined USE_TIMERS
  246. KillTimer(Timer[playerid]);
  247. #endif
  248. Timer[playerid] = -1;
  249. DeleteArray(id[playerid]);
  250. id[playerid] = -1;
  251. CurrTarget[playerid] = 0;
  252. }
  253. return 1;
  254. }
  255. //--------------------AUTO-PILOT-CORE-FUNCTIONS-------------------------------//
  256. #define DEPRECATE_Z
  257. stock PullVehicleIntoDirection(vehicleid, Float:x, Float:y, Float:z, Float:speed)//Thanks to Miguel for supplying me with this function, I have edited it a bit
  258. {
  259. new
  260. Float:distance,
  261. Float:vehicle_pos[3];
  262.  
  263. GetVehiclePos(vehicleid, vehicle_pos[0], vehicle_pos[1], vehicle_pos[2]);
  264. #if defined USE_SMOOTH_TURNS
  265. new Float: oz = atan2VehicleZ(vehicle_pos[0], vehicle_pos[1], x, y);
  266. new Float: vz;
  267. GetVehicleZAngle(vehicleid, vz);
  268. if(oz < vz-180) oz = oz+360;
  269. if(vz < oz-180) vz = vz+360;
  270. new Float: cz = floatabs(vz - oz);
  271. #else
  272. SetVehicleZAngle(vehicleid, atan2VehicleZ(vehicle_pos[0], vehicle_pos[1], x, y));
  273. #endif
  274. x -= vehicle_pos[0];
  275. y -= vehicle_pos[1];
  276. z -= vehicle_pos[2];
  277. #if defined DEPRECATE_Z
  278. distance = floatsqroot((x * x) + (y * y));
  279. x = (speed * x) / distance;
  280. y = (speed * y) / distance;
  281. GetVehicleVelocity(vehicleid, vehicle_pos[0], vehicle_pos[0], z);
  282. #else
  283. z+=0.11;
  284. distance = floatsqroot((x * x) + (y * y) + (z * z));
  285. x = (speed * x) / distance;
  286. y = (speed * y) / distance;
  287. z = (speed * z) / distance;
  288. #endif
  289. #if defined USE_SMOOTH_TURNS
  290. if(cz > 0)
  291. {
  292. new Float: fz = cz*0.0015;
  293. if(vz < oz) SetVehicleAngularVelocity(vehicleid, 0.0, 0.0, fz);
  294. if(vz > oz) SetVehicleAngularVelocity(vehicleid, 0.0, 0.0, -fz);
  295. }
  296. #endif
  297. SetVehicleVelocity(vehicleid, x, y, z);
  298. }
  299.  
  300. forward Float:atan2VehicleZ(Float:Xb,Float:Yb,Float:Xe,Float:Ye);// Dunno how to name it...
  301. stock Float:atan2VehicleZ(Float:Xb,Float:Yb,Float:Xe,Float:Ye)
  302. {
  303. new Float:a = floatabs(360.0 - atan2( Xe-Xb,Ye-Yb));
  304. if(360 > a > 180)return a;
  305. return a-360.0;
  306. }
  307. //----------------------------------------------------------------------------//
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty