1
0

rnpc.inc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /**
  2. * RNPC - Recordfile NPCs
  3. * Version 0.4.1
  4. * made by Mauzen
  5. */
  6. #define RNPC_VERSION "0.4.1"
  7. #define RNPC_BUILD 14
  8. #define RNPC_DATE "03.12.2014"
  9. #define RNPC_VERSION_DLPAGE "www.mauzen.org/rnpc"
  10. #define RNPC_VERSION_STARTURL "www.mauzen.org/rnpc/rnpc_start.php"
  11. #define RNPC_VERSION_UPDATEURL "www.mauzen.org/rnpc/rnpc_update.php"
  12. // Identify messages as RNPC commands
  13. // (alternative communication protocol for future versions)
  14. #define RNPC_COMM_ID 520
  15. #define PLAYER_RECORDING_TYPE_NONE 0
  16. #define PLAYER_RECORDING_TYPE_DRIVER 1
  17. #define PLAYER_RECORDING_TYPE_ONFOOT 2
  18. #define RNPC_SPEED_SPRINT (0.0095)
  19. #define RNPC_SPEED_RUN (0.0057)
  20. #define RNPC_SPEED_WALK (0.0015)
  21. #define MAP_ANDREAS_MODE_NONE 0
  22. #define MAP_ANDREAS_MODE_MINIMAL 1
  23. #define MAP_ANDREAS_MODE_MEDIUM 2 // currently unused
  24. #define MAP_ANDREAS_MODE_FULL 3
  25. #define MAP_ANDREAS_MODE_NOBUFFER 4
  26. // RNPC_PEND_ACTION defines (Connection relevant states)
  27. #define RNPC_ACTION_READY (-1)
  28. #define RNPC_NOT_EXISTING (0)
  29. #define RNPC_CONNECTION_PENDING (1)
  30. #define RNPC_CONNECTED (2)
  31. #define RNPC_STOPPING (4) // Stop-playback performed
  32. // Adjustable stuff
  33. #define RNPC_VEHICLE_DMG_MOD (160.0) // velocity * this value = vehicle hit damage
  34. // AddPause compatibility mode
  35. #if defined RNPC_PAUSE_REALTIME
  36. #define RNPC_PAUSE_COMP 0
  37. #else
  38. #define RNPC_PAUSE_COMP 1
  39. #endif
  40. // @since 0.2
  41. native RNPC_CreateBuild(npcid, type, slot=0);
  42. native RNPC_FinishBuild(clear=1);
  43. native RNPC_AddMovement(Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, Float:speed=RNPC_SPEED_RUN, use_zmap=0);
  44. native RNPC_ConcatMovement(Float:x, Float:y, Float:z, Float:speed=RNPC_SPEED_RUN, use_zmap=0);
  45. native RNPC_AddPause(time, comp=RNPC_PAUSE_COMP);
  46. native RNPC_SetUpdateRate(rate);
  47. native RNPC_SetLRKeys(lr);
  48. native RNPC_SetUDKeys(ud);
  49. native RNPC_SetKeys(keys);
  50. native RNPC_SetQuat1(Float:w);
  51. native RNPC_SetQuat2(Float:x);
  52. native RNPC_SetQuat3(Float:y);
  53. native RNPC_SetQuat4(Float:z);
  54. native RNPC_SetHealth(hp);
  55. native RNPC_SetArmour(arm);
  56. native RNPC_SetSpecialAction(sp);
  57. native RNPC_SetWeaponID(weaponid);
  58. native RNPC_SetAnimID(anim);
  59. native RNPC_SetAnimParams(params);
  60. native RNPC_SetAngleQuats(Float:a, Float:h, Float:b);
  61. native MapAndreas_Init(mode, name[]="", len=sizeof(name));
  62. native MapAndreas_FindZ_For2DCoord(Float:X, Float:Y, &Float:Z);
  63. native MapAndreas_FindAverageZ(Float:X, Float:Y, &Float:Z);
  64. native MapAndreas_Unload();
  65. native MapAndreas_SetZ_For2DCoord(Float:X, Float:Y, Float:Z);
  66. native MapAndreas_SaveCurrentHMap(name[]);
  67. // @since 0.2.1
  68. native RNPC_GetBuildLength();
  69. // @since 0.3
  70. native RNPC_SetSirenState(siren);
  71. native RNPC_SetDriverHealth(health);
  72. native RNPC_SetInternalPos(Float:x, Float:y, Float:z);
  73. native RNPC_SetAcceleration(Float:acc);
  74. native RNPC_SetDeceleration(Float:dec); // Unused yet
  75. native RNPC_AddMovementAlt(Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, Float:speed=RNPC_SPEED_RUN, bool:lock=true);
  76. // @since 0.3.4
  77. native RNPC_CreateCustomBuild(type, name[]);
  78. // fake-functions
  79. #define RNPC_SetAutorepeat(%1,%2) new rtxt[10]; format(rtxt, 10, "RNPC:%d", 110 + %2); SendClientMessage(%1, -1, rtxt)
  80. #define RNPC_PauseRecordingPlayback(%1) SendClientMessage(%1, -1, "RNPC:103")
  81. #define RNPC_ResumeRecordingPlayback(%1) SendClientMessage(%1, -1, "RNPC:104")
  82. #define RNPC_ToggleVehicleCollisionCheck(%1,%2) new rtxt[10]; format(rtxt, 10, "RNPC:%d", 115 - %2); SendClientMessage(%1, -1, rtxt)
  83. #define RNPC_StopPlayback(%1) SendClientMessage(%1, -1, "RNPC:102")
  84. #define RNPC_SetShootable(%1,%2) rnpcData[%1][RNPC_SHOOTABLE] = %2
  85. #define GetRNPCHealth(%1) rnpcData[%1][RNPC_HEALTH]
  86. #define IsPlayerRNPC(%1) (IsPlayerNPC(%1) && (rnpcPend{%1} != RNPC_NOT_EXISTING))
  87. // Redirecting SendClientMessage when debugmode is enabled
  88. #if defined RNPC_DEBUG
  89. stock RNPC_TEMP_SendClientMessage(playerid, color, text[], len=sizeof(text)) {
  90. #pragma unused len
  91. // if (IsPlayerRNPC(playerid))
  92. // not needed here as this include doesnt communicate with real players anyways
  93. printf("RNPC %d <-- [CMD] %s", playerid, text);
  94. SendClientMessage(playerid, color, text);
  95. }
  96. #define SendClientMessage RNPC_TEMP_SendClientMessage
  97. #endif
  98. // --------------------------------------------------------
  99. // Custom callbacks
  100. forward OnRNPCPlaybackFinished(npcid);
  101. forward OnRNPCPlaybackStopped(npcid);
  102. forward OnRNPCDeath(npcid, killerid, reason);
  103. forward OnRNPCVehicleHit(npcid, driverid, vehicleid, times);
  104. // To store pending connections and actions
  105. new rnpcPend[MAX_PLAYERS char];
  106. // Currently played record slot
  107. new rnpcCurSlot[MAX_PLAYERS char];
  108. /**
  109. * Connects a new RNPC, returning his predicted ID.
  110. * @since V0.1
  111. */
  112. stock ConnectRNPC(name[])
  113. {
  114. // Find the first free playerslot
  115. new slot = -1;
  116. for (new i = 0; i < MAX_PLAYERS; i++) {
  117. // Make sure theres no NPC connecting to that slot yet
  118. if (!IsPlayerConnected(i) && rnpcPend{i} == RNPC_NOT_EXISTING) {
  119. slot = i;
  120. rnpcPend{i} = RNPC_CONNECTION_PENDING;
  121. break;
  122. }
  123. }
  124. ConnectNPC(name, "RNPC");
  125. return slot;
  126. }
  127. /**
  128. * Moves a RNPC to the given position.
  129. * @since V0.1
  130. */
  131. stock MoveRNPC(npcid, Float:x, Float:y, Float:z, Float:speed, use_zmap=0)
  132. {
  133. if (!IsPlayerRNPC(npcid)) return false;
  134. new Float:nx, Float:ny, Float:nz;
  135. new slot;
  136. if (IsPlayerInAnyVehicle(npcid)) {
  137. GetVehiclePos(GetPlayerVehicleID(npcid), nx, ny, nz);
  138. slot = RNPC_CreateBuild_s(npcid, PLAYER_RECORDING_TYPE_DRIVER, 95);
  139. RNPC_AddMovement(nx, ny, nz, x, y, z, speed, use_zmap);
  140. RNPC_FinishBuild();
  141. } else {
  142. GetPlayerPos(npcid, nx, ny, nz);
  143. slot = RNPC_CreateBuild_s(npcid, PLAYER_RECORDING_TYPE_ONFOOT, 95);
  144. RNPC_AddMovement(nx, ny, nz, x, y, z, speed, use_zmap);
  145. RNPC_FinishBuild();
  146. }
  147. RNPC_StartBuildPlayback(npcid, slot);
  148. return true;
  149. }
  150. /**
  151. * Prevents writing to currently active files.
  152. * IMPORTANT: consider the returned slot to be sure to play the correct one afterwards.
  153. */
  154. stock RNPC_CreateBuild_s(npcid, type, slot=0) {
  155. if (rnpcCurSlot{npcid} == slot) {
  156. slot = (slot + 1) % 100;
  157. }
  158. RNPC_CreateBuild(npcid, type, slot);
  159. return slot;
  160. }
  161. /**
  162. * Tells the NPC to start playback of any rec file
  163. * @since V0.1.1
  164. */
  165. stock RNPC_StartPlayback(npcid, rec[])
  166. {
  167. if (!IsPlayerRNPC(npcid)) return false;
  168. new form[40];
  169. format(form, 40, "RNPC:109:%s", rec);
  170. SendClientMessage(npcid, -1, form);
  171. return true;
  172. }
  173. /**
  174. * Tells the NPC to start playback of a RNPC build
  175. * @since V0.2
  176. */
  177. stock RNPC_StartBuildPlayback(npcid, slot=0, vehicleid=0)
  178. {
  179. // If enabled, wait a bit till the NPC actually entered the vehicle
  180. if (vehicleid) {
  181. PutPlayerInVehicle(npcid, vehicleid, 0);
  182. SetTimerEx("DelayStart", 100, 0, "iii", npcid, vehicleid, slot);
  183. }
  184. rnpcCurSlot{npcid} = slot;
  185. new cmd[16];
  186. format(cmd, 16, "RNPC:101:%d", slot);
  187. SendClientMessage(npcid, -1, cmd);
  188. }
  189. /**
  190. * Delayed second start to fix vehicle playback problems
  191. * @since V0.3
  192. */
  193. forward DelayStart(npcid, vehicleid, slot);
  194. public DelayStart(npcid, vehicleid, slot)
  195. {
  196. PutPlayerInVehicle(npcid, vehicleid, 0);
  197. new cmd[16];
  198. format(cmd, 16, "RNPC:101:%d", slot);
  199. SendClientMessage(npcid, -1, cmd);
  200. }
  201. /**
  202. *
  203. * @since V0.3
  204. */
  205. //stock RNPC_StopPlayback(npcid)
  206. //{
  207. // Moved to fake functions
  208. //}
  209. // Damage management ---------------------------------------------
  210. enum RNPC_DATA_ENUM {
  211. Float: RNPC_HEALTH, // Stores a healthvalue for the NPC
  212. RNPC_DEAD, // Determines if the NPC is dead
  213. RNPC_LAST_DAMAGER, // Last guy who attacked the NPC
  214. RNPC_LAST_REASON, // Last damage reason
  215. RNPC_SHOOTABLE, // If true, the NPC will get default GTA damage from guns
  216. RNPC_VEHICLEHIT,
  217. RNPC_VEHICLEHIT_RESETTIMER // Timer to reset the vehiclehit status and resume playback
  218. };
  219. new rnpcData[MAX_PLAYERS][RNPC_DATA_ENUM];
  220. stock SetRNPCHealth(npcid, Float:health, issuer=INVALID_PLAYER_ID, reason=53) {
  221. rnpcData[npcid][RNPC_HEALTH] = health;
  222. rnpcData[npcid][RNPC_LAST_DAMAGER] = issuer;
  223. rnpcData[npcid][RNPC_LAST_REASON] = reason;
  224. if (rnpcData[npcid][RNPC_HEALTH] <= 0.0) {
  225. // Kill the NPC if hes not already dead
  226. if (!rnpcData[npcid][RNPC_DEAD]) {
  227. // Stop playback
  228. RNPC_StopPlayback(npcid);
  229. }
  230. // --> When stopped, apply death animation
  231. }
  232. }
  233. // Exact runover check, called after proximity alert by a NPC
  234. // TODO: Move that calculation to the plugin for better speed
  235. stock IsVehicleOnPlayer(playerid, vehicleid) {
  236. static Float:ro_xs, Float:ro_ys, Float:ro_zs;
  237. static Float:ro_xn, Float:ro_yn, Float:ro_zn;
  238. static Float:ro_xv, Float:ro_yv, Float:ro_zv, Float:ro_av;
  239. static Float:ro_tx, Float:ro_ty;
  240. // Gather position and size data
  241. GetVehicleModelInfo(GetVehicleModel(vehicleid), VEHICLE_MODEL_INFO_SIZE, ro_xs, ro_ys, ro_zs);
  242. GetPlayerPos(playerid, ro_xn, ro_yn, ro_zn);
  243. GetVehiclePos(vehicleid, ro_xv, ro_yv, ro_zv);
  244. GetVehicleZAngle(vehicleid, ro_av);
  245. //ro_av = 360 - ro_av;
  246. // Transform coordinate system
  247. ro_tx = floatabs((ro_xn - ro_xv) * floatcos(ro_av,degrees) + (ro_yn - ro_yv) * floatsin(ro_av,degrees));
  248. ro_ty = floatabs(-(ro_xn - ro_xv) * floatsin(ro_av,degrees) + (ro_yn - ro_yv) * floatcos(ro_av,degrees));
  249. return ((ro_zn - ro_zv) < 0.5) && (ro_tx < ro_xs / 2 && ro_ty < ro_ys / 2);
  250. }
  251. // Used for timed respawn
  252. forward RespawnRNPC(npcid);
  253. public RespawnRNPC(npcid) {
  254. SpawnPlayer(npcid);
  255. }
  256. forward ResetVehicleHit(npcid);
  257. public ResetVehicleHit(npcid) {
  258. // Reset hitstate and continue playbck
  259. rnpcData[npcid][RNPC_VEHICLEHIT] = 0;
  260. rnpcData[npcid][RNPC_VEHICLEHIT_RESETTIMER] = -1;
  261. RNPC_ResumeRecordingPlayback(npcid);
  262. }
  263. // Hooked callbacks ---------------------------------------------------
  264. /**
  265. * Serverside interface for RNPC communication
  266. */
  267. // Support for ZCMD, modified version of Lorenc_'s experimental update
  268. #if defined _zcmd_included
  269. #define OPCT_HOOKNAME "RNPC_OnPlayerCommandReceived"
  270. public OnPlayerCommandReceived(playerid, cmdtext[])
  271. #else
  272. #define OPCT_HOOKNAME "RNPC_OnPlayerCommandText"
  273. public OnPlayerCommandText(playerid, cmdtext[])
  274. #endif
  275. {
  276. if (!IsPlayerRNPC(playerid)) return CallLocalFunction(OPCT_HOOKNAME, "is", playerid, cmdtext);
  277. #if defined RNPC_DEBUG
  278. printf("RNPC %d --> [CMD] %s", playerid, cmdtext);
  279. #endif
  280. // NPC finished playback
  281. if (!strcmp("RNPC:002", cmdtext, true, 8)) {
  282. // Reset current slot for RNPC_CreateBuild_s
  283. rnpcCurSlot{playerid} = -1;
  284. if (rnpcPend{playerid} == RNPC_STOPPING) {
  285. // Call OnRNPCPlaybackStopped instead and reset state
  286. rnpcPend{playerid} = RNPC_CONNECTED;
  287. // Check if it was a stop caused by NPC death
  288. if (rnpcData[playerid][RNPC_HEALTH] <= 0.0 && !rnpcData[playerid][RNPC_DEAD]) {
  289. // Mark as finally dead in include
  290. rnpcData[playerid][RNPC_DEAD] = true;
  291. // Tell NPC hes dead so he wont execute playbacks anymore
  292. SendClientMessage(playerid, -1, "RNPC:112");
  293. if (CallLocalFunction("OnRNPCDeath", "iii", playerid, rnpcData[playerid][RNPC_LAST_DAMAGER], rnpcData[playerid][RNPC_LAST_REASON]) == 0) {
  294. // Default behaviour
  295. SetTimerEx("RespawnRNPC", 4000, 0, "i", playerid);
  296. if (rnpcData[playerid][RNPC_LAST_REASON] != 49) {
  297. // If killed by vehicle, animation is already played
  298. switch(random(4)) {
  299. case 0: ApplyAnimation(playerid, "PED", "KO_skid_back", 4.1, 0, 1, 1, 1, 0, 1);
  300. case 1: ApplyAnimation(playerid, "PED", "KO_skid_front", 4.1, 0, 1, 1, 1, 0, 1);
  301. case 2: ApplyAnimation(playerid, "PED", "KO_spin_L", 4.1, 0, 1, 1, 1, 0, 1);
  302. case 3: ApplyAnimation(playerid, "PED", "KO_spin_R", 4.1, 0, 1, 1, 1, 0, 1);
  303. }
  304. }
  305. CallLocalFunction("OnPlayerDeath", "iii", playerid, rnpcData[playerid][RNPC_LAST_DAMAGER], rnpcData[playerid][RNPC_LAST_REASON]);
  306. }
  307. } else {
  308. // Dont call this for death-stops
  309. CallLocalFunction("OnRNPCPlaybackStopped", "i", playerid);
  310. }
  311. } else CallLocalFunction("OnRNPCPlaybackFinished", "i", playerid);
  312. return 1;
  313. }
  314. // NPC stopped playback (manual abort)
  315. if (!strcmp("RNPC:003", cmdtext, true, 8)) {
  316. // Reset onfoot movements after manual playback stop
  317. if (!IsPlayerInAnyVehicle(playerid)) {
  318. // Keep visible, static attirbutes to restore them later
  319. new Float:x, Float:y, Float:z, Float:ang, weapon, spec;
  320. GetPlayerPos(playerid, x, y, z);
  321. GetPlayerFacingAngle(playerid, ang);
  322. spec = GetPlayerSpecialAction(playerid);
  323. weapon = GetPlayerWeapon(playerid);
  324. // Create "blank" build and restore old static attributes
  325. RNPC_CreateBuild(playerid, PLAYER_RECORDING_TYPE_ONFOOT, 95);
  326. RNPC_SetWeaponID(weapon);
  327. RNPC_SetSpecialAction(spec);
  328. RNPC_SetAngleQuats(0.0, 360.0 - ang, 0.0);
  329. RNPC_AddPause(5);
  330. RNPC_FinishBuild();
  331. // OnRNPCPlaybackStopped is called when the stop-playback is finished
  332. rnpcPend{playerid} = RNPC_STOPPING;
  333. RNPC_StartBuildPlayback(playerid, 95);
  334. }
  335. return 1;
  336. }
  337. // NPC reports possible run-over vehicle
  338. // Do exact check and handle run-over
  339. if (!strcmp("RNPC:301", cmdtext, true, 8)) {
  340. new driverid = strval(cmdtext[9]),
  341. vehicleid = GetPlayerVehicleID(driverid);
  342. if (IsVehicleOnPlayer(playerid, vehicleid)) {
  343. #if !defined RNPC_DONT_PAUSE_ON_VEHICLEHIT
  344. // On the first hit, pause playback
  345. if (rnpcData[playerid][RNPC_VEHICLEHIT] == 0) {
  346. RNPC_PauseRecordingPlayback(playerid);
  347. }
  348. // Reset the reset timer
  349. if (rnpcData[playerid][RNPC_VEHICLEHIT_RESETTIMER] > 0) {
  350. KillTimer(rnpcData[playerid][RNPC_VEHICLEHIT_RESETTIMER]);
  351. }
  352. // Resets the vehicle hit status, even if the vehicle already is out of range
  353. rnpcData[playerid][RNPC_VEHICLEHIT_RESETTIMER] = SetTimerEx("ResetVehicleHit", 2200, 0, "i", playerid);
  354. #endif
  355. if (!CallLocalFunction("OnRNPCVehicleHit", "iiii", playerid, driverid, vehicleid, rnpcData[playerid][RNPC_VEHICLEHIT])) {
  356. // Default behaviour
  357. if (!rnpcData[playerid][RNPC_VEHICLEHIT]) {
  358. // Initial hit damage
  359. new Float:vx, Float:vy, Float:vz;
  360. GetVehicleVelocity(vehicleid, vx, vy, vz);
  361. SetRNPCHealth(playerid, GetRNPCHealth(playerid) - floatsqroot(vx*vx + vy*vy + vz*vz) * RNPC_VEHICLE_DMG_MOD, driverid, 49);
  362. } else {
  363. // Constant standing damage
  364. SetRNPCHealth(playerid, GetRNPCHealth(playerid) - 1.0, driverid, 49);
  365. }
  366. }
  367. rnpcData[playerid][RNPC_VEHICLEHIT]++;
  368. } /*else {
  369. // If vehicle just left the player, resume reset hitstate instantly
  370. // also setting up the stand-up resume timer
  371. if (rnpcData[playerid][RNPC_VEHICLEHIT] > 0) {
  372. // Reset the reset timer
  373. if ((rnpcData[playerid][RNPC_VEHICLEHIT_RESETTIMER] > 0) && 0) {
  374. KillTimer(rnpcData[playerid][RNPC_VEHICLEHIT_RESETTIMER]);
  375. }
  376. //ResetVehicleHit(playerid, RNPC_RESETVH_RESET);
  377. }
  378. }*/
  379. return 1;
  380. }
  381. // Ignore other unhandled RNPC messages
  382. if (!strcmp("RNPC:", cmdtext, true, 5)) return 1;
  383. return CallLocalFunction(OPCT_HOOKNAME, "is", playerid, cmdtext);
  384. }
  385. // Hook to either zcmd or default
  386. #if defined _zcmd_included
  387. #if defined _ALS_OnPlayerCommandReceived
  388. #undef OnPlayerCommandReceived
  389. #else
  390. #define _ALS_OnPlayerCommandReceived
  391. #endif
  392. #define OnPlayerCommandReceived RNPC_OnPlayerCommandReceived
  393. forward RNPC_OnPlayerCommandReceived(playerid, cmdtext[]);
  394. #else
  395. #if defined _ALS_OnPlayerCommandText
  396. #undef OnPlayerCommandText
  397. #else
  398. #define _ALS_OnPlayerCommandText
  399. #endif
  400. #define OnPlayerCommandText RNPC_OnPlayerCommandText
  401. forward RNPC_OnPlayerCommandText(playerid, cmdtext[]);
  402. #endif
  403. /**
  404. * Updating the data when the bot connected.
  405. */
  406. public OnPlayerConnect(playerid) {
  407. if (!IsPlayerRNPC(playerid)) return CallLocalFunction("RNPC_OnPlayerConnect", "i", playerid);
  408. rnpcPend{playerid} = RNPC_CONNECTED;
  409. rnpcCurSlot{playerid} = -1;
  410. rnpcData[playerid][RNPC_SHOOTABLE] = 0;
  411. rnpcData[playerid][RNPC_HEALTH] = 100.0;
  412. rnpcData[playerid][RNPC_DEAD] = 0;
  413. return CallLocalFunction("RNPC_OnPlayerConnect", "i", playerid);
  414. }
  415. #if defined _ALS_OnPlayerConnect
  416. #undef OnPlayerConnect
  417. #else
  418. #define _ALS_OnPlayerConnect
  419. #endif
  420. #define OnPlayerConnect RNPC_OnPlayerConnect
  421. forward RNPC_OnPlayerConnect(playerid);
  422. /**
  423. * Clearing the data when the bot disconnects.
  424. */
  425. public OnPlayerDisconnect(playerid, reason) {
  426. if (!IsPlayerRNPC(playerid)) return CallLocalFunction("RNPC_OnPlayerDisconnect", "ii", playerid, reason);
  427. rnpcPend{playerid} = RNPC_NOT_EXISTING;
  428. rnpcCurSlot{playerid} = -1;
  429. rnpcData[playerid][RNPC_SHOOTABLE] = 0;
  430. return CallLocalFunction("RNPC_OnPlayerDisconnect", "ii", playerid, reason);
  431. }
  432. #if defined _ALS_OnPlayerDisconnect
  433. #undef OnPlayerDisconnect
  434. #else
  435. #define _ALS_OnPlayerDisconnect
  436. #endif
  437. #define OnPlayerDisconnect RNPC_OnPlayerDisconnect
  438. forward RNPC_OnPlayerDisconnect(playerid, reason);
  439. /**
  440. * Setting spawn-related data (health etc)
  441. */
  442. public OnPlayerSpawn(playerid) {
  443. if (IsPlayerRNPC(playerid)) {
  444. rnpcData[playerid][RNPC_HEALTH] = 100.0;
  445. rnpcData[playerid][RNPC_DEAD] = 0;
  446. }
  447. #if defined RNPC_OnPlayerSpawn
  448. return RNPC_OnPlayerSpawn(playerid);
  449. #else
  450. return 1;
  451. #endif
  452. }
  453. #if defined _ALS_OnPlayerSpawn
  454. #undef OnPlayerSpawn
  455. #else
  456. #define _ALS_OnPlayerSpawn
  457. #endif
  458. #define OnPlayerSpawn RNPC_OnPlayerSpawn
  459. forward RNPC_OnPlayerSpawn(playerid);
  460. public OnPlayerGiveDamage(playerid, damagedid, Float: amount, weaponid, bodypart)
  461. {
  462. if (rnpcData[damagedid][RNPC_SHOOTABLE] && IsPlayerRNPC(damagedid)) {
  463. SetRNPCHealth(damagedid, GetRNPCHealth(damagedid) - amount, playerid, weaponid);
  464. }
  465. return CallLocalFunction("RNPC_OnPlayerGiveDamage", "iifii", playerid, damagedid, amount, weaponid, bodypart);
  466. }
  467. #if defined _ALS_OnPlayerGiveDamage
  468. #undef OnPlayerGiveDamage
  469. #else
  470. #define _ALS_OnPlayerGiveDamage
  471. #endif
  472. #define OnPlayerGiveDamage RNPC_OnPlayerGiveDamage
  473. forward RNPC_OnPlayerGiveDamage(playerid, damagedid, Float: amount, weaponid, bodypart);
  474. #if !defined RNPC_DONT_USE_DEAD_STREAMIN_FIX
  475. public OnPlayerStreamIn(playerid, forplayerid)
  476. {
  477. if (IsPlayerRNPC(playerid)) {
  478. if (rnpcData[playerid][RNPC_DEAD] > 0) {
  479. ApplyAnimation(playerid, "PED", "KO_skid_back", 4.1, 0, 1, 1, 1, 0, 1);
  480. }
  481. }
  482. return CallLocalFunction("RNPC_OnPlayerStreamIn", "ii", playerid, forplayerid);
  483. }
  484. #if defined _ALS_OnPlayerStreamIn
  485. #undef OnPlayerStreamIn
  486. #else
  487. #define _ALS_OnPlayerStreamIn
  488. #endif
  489. #define OnPlayerStreamIn RNPC_OnPlayerStreamIn
  490. forward RNPC_OnPlayerStreamIn(playerid, forplayerid);
  491. #endif
  492. // End of user functions ---------------------------------------------------
  493. // Version checker and stats collector
  494. #if !defined RNPC_NO_VERSION_CHECK
  495. #include <a_http>
  496. public OnGameModeInit() {
  497. printf(" RNPC versionchecker: checking for updates...");
  498. new url[72];
  499. format(url, sizeof(url), "version=%d&port=%d", RNPC_BUILD, GetServerVarAsInt("port"));
  500. HTTP(9000, HTTP_POST, RNPC_VERSION_STARTURL, url, "RNPC_http_versioncheck");
  501. return CallLocalFunction("RNPC_OnGameModeInit", "");
  502. }
  503. #if defined _ALS_OnGameModeInit
  504. #undef OnGameModeInit
  505. #else
  506. #define _ALS_OnGameModeInit
  507. #endif
  508. #define OnGameModeInit RNPC_OnGameModeInit
  509. forward RNPC_OnGameModeInit();
  510. forward RNPC_http_versioncheck(index, response_code, data[]);
  511. public RNPC_http_versioncheck(index, response_code, data[]) {
  512. if (index != 9000) return;
  513. if (response_code != 200) {
  514. printf(" RNPC versionchecker: Connection problem.");
  515. return;
  516. }
  517. if (strlen(data) > 1) {
  518. printf("------------------------------------------------------------------");
  519. printf(" RNPC versionchecker: New version available!", data);
  520. printf(" RNPC versionchecker: Your version: "RNPC_VERSION" ("RNPC_DATE")");
  521. printf(" RNPC versionchecker: New version: %s", data);
  522. printf(" RNPC versionchecker: Check "RNPC_VERSION_DLPAGE" for downloads");
  523. printf("------------------------------------------------------------------");
  524. }
  525. #if !defined RNPC_NO_STATUPDATES
  526. SetTimer("RNPC_http_statupdater", 60000 * 15, 1);
  527. #endif
  528. }
  529. #if !defined RNPC_NO_STATUPDATES
  530. forward RNPC_http_statupdater();
  531. public RNPC_http_statupdater() {
  532. new url[64];
  533. format(url, sizeof(url), "version=%d&port=%d", RNPC_BUILD, GetServerVarAsInt("port"));
  534. HTTP(0, HTTP_POST, RNPC_VERSION_UPDATEURL, url, "RNPC_http_versioncheck");
  535. }
  536. #endif
  537. #endif
  538. // EOF -------------------------------------------- Revoke SendClientMessge redirection
  539. #if defined RNPC_DEBUG
  540. #undef SendClientMessage
  541. #endif