HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. #include <amxmodx>
  2. #include <fakemeta>
  3.  
  4. #define PLUGIN "TacticalRobot"
  5. #define VERSION "1.0"
  6. #define AUTHOR "Lain"
  7.  
  8. #define BOT_MAXNUM 32
  9. enum TargetType
  10. {
  11. TT_None = 0,
  12. TT_LookAt,
  13. TT_Move,
  14. TT_Follow,
  15. TT_Use,
  16. TT_Attack,
  17. TT_Attack2,
  18. TT_Reload,
  19. TT_Svencoop_Revive
  20. }
  21.  
  22.  
  23. new g_BotId[BOT_MAXNUM]
  24. new Float:g_BotTarget[BOT_MAXNUM][3]
  25. new TargetType:g_BotTargetType[BOT_MAXNUM]
  26. new g_BotTargetEnt[BOT_MAXNUM]
  27. new g_BotTargetWeapon[BOT_MAXNUM][32]
  28. new g_BotOldButton[BOT_MAXNUM]
  29. new g_BotCount
  30.  
  31. public plugin_init()
  32. {
  33. register_plugin(PLUGIN, VERSION, AUTHOR)
  34.  
  35. register_forward(FM_StartFrame, "fwd_StartFrame")
  36. }
  37.  
  38. public plugin_natives()
  39. {
  40. register_native("bot_create", "native_createbot")
  41. register_native("bot_settarget", "native_settarget")
  42. register_native("bot_isfree", "native_isfree")
  43. }
  44.  
  45. stock get_bot_index(id)
  46. {
  47. for(new i=0;i<g_BotCount;i++)
  48. if(g_BotId[i] == id)
  49. return i
  50. return -1
  51. }
  52.  
  53. public client_disconnect(id)
  54. {
  55. new i = get_bot_index(id)
  56. if(i != -1)
  57. {
  58. g_BotId[i] = 0
  59. g_BotTarget[i] = Float:{0.0, 0.0, 0.0}
  60. g_BotTargetType[i] = TT_None
  61. g_BotTargetEnt[i] = 0
  62. g_BotTargetWeapon[i] = ""
  63. g_BotOldButton[i] = 0
  64. g_BotCount -= 1
  65. }
  66. }
  67.  
  68. public native_settarget(id, num)
  69. {
  70. if(num != 5)
  71. return
  72. new bot = get_param(1)
  73. new i = get_bot_index(bot)
  74. if(i == -1)
  75. return
  76. get_array_f(2, g_BotTarget[i], 3)
  77. g_BotTargetType[i] = TargetType:get_param(3)
  78. g_BotTargetEnt[i] = get_param(4)
  79. get_string(5, g_BotTargetWeapon[i], 31)
  80. }
  81.  
  82. public bool:native_isfree(id, num)
  83. {
  84. if(num != 1)
  85. return false
  86. new bot = get_param(1)
  87. new i = get_bot_index(bot)
  88. if(i == -1)
  89. return false
  90. if(g_BotTargetType[i] == TT_None)
  91. return true
  92. return false
  93. }
  94.  
  95. public native_createbot(id, num)
  96. {
  97. if(num != 1)
  98. return 0
  99. if(g_BotCount >= BOT_MAXNUM)
  100. return 0
  101. new name[128]
  102. get_string(1, name, 127)
  103. new bot = engfunc(EngFunc_CreateFakeClient, name)
  104. if(!bot)
  105. return 0
  106.  
  107. engfunc(EngFunc_FreeEntPrivateData, bot)
  108. bot_settings(bot)
  109.  
  110. static szRejectReason[128]
  111. dllfunc(DLLFunc_ClientConnect, bot, name, "127.0.0.1", szRejectReason)
  112. if(!is_user_connected(bot))
  113. return 0
  114.  
  115. dllfunc(DLLFunc_ClientPutInServer, bot)
  116. set_pev(bot,pev_spawnflags, pev(bot,pev_spawnflags) | FL_FAKECLIENT)
  117. set_pev(bot,pev_flags, pev(bot,pev_flags) | FL_FAKECLIENT)
  118.  
  119. g_BotId[g_BotCount] = bot
  120. g_BotCount += 1
  121.  
  122. return bot
  123. }
  124.  
  125. bot_settings(id)
  126. {
  127. set_user_info(id, "model", "aswat")
  128. set_user_info(id, "rate", "3500")
  129. set_user_info(id, "cl_updaterate", "30")
  130. set_user_info(id, "cl_lw", "0")
  131. set_user_info(id, "cl_lc", "0")
  132. set_user_info(id, "tracker", "0")
  133. set_user_info(id, "cl_dlmax", "128")
  134. set_user_info(id, "lefthand", "1")
  135. set_user_info(id, "friends", "0")
  136. set_user_info(id, "dm", "0")
  137. set_user_info(id, "ah", "1")
  138. set_user_info(id, "topcolor", "145")
  139. set_user_info(id, "bottomcolor", "150")
  140.  
  141. set_user_info(id, "*bot", "1")
  142. set_user_info(id, "_cl_autowepswitch", "1")
  143. set_user_info(id, "_vgui_menu", "0")
  144. set_user_info(id, "_vgui_menus", "0")
  145. }
  146.  
  147. public fwd_StartFrame()
  148. {
  149. for(new i=0;i<g_BotCount;i++)
  150. BotThink(i)
  151. }
  152.  
  153. BotThink(index)
  154. {
  155. static id, Float:target[3], TargetType:tt, te, tw[32], oldbutton
  156. id = g_BotId[index]
  157. target = g_BotTarget[index]
  158. tt = g_BotTargetType[index]
  159. te = g_BotTargetEnt[index]
  160. tw = g_BotTargetWeapon[index]
  161. oldbutton = g_BotOldButton[index]
  162. static Float:origin[3], Float:eye_origin[3], Float:speedforward, button
  163. pev(id, pev_origin, origin)
  164. pev(id, pev_view_ofs, eye_origin)
  165. eye_origin[0] += origin[0]
  166. eye_origin[1] += origin[1]
  167. eye_origin[2] += origin[2]
  168. speedforward = 0.0
  169. button = 0
  170. static bool:forwardBlocked, bool:thisAlive, bool:inWater, bool:onLadder
  171. forwardBlocked = fForwardBlocked(id)
  172. thisAlive = IsAlive(id)
  173. inWater = (pev(id, pev_waterlevel) == 3)?true:false
  174. onLadder = (pev(id, pev_movetype) == MOVETYPE_FLY)?true:false
  175. static bool:resetTarget
  176. resetTarget = false
  177. if(!thisAlive)
  178. {
  179. button |= IN_ATTACK
  180. resetTarget = true
  181. }
  182. else
  183. {
  184. if(te && !pev_valid(te))
  185. te = 0
  186. if(te)
  187. {
  188. if(!IsAlive(te) && tt != TT_Svencoop_Revive)
  189. te = 0
  190. else if(IsAlive(te) && tt == TT_Svencoop_Revive)
  191. te = 0
  192. }
  193. if(te && !FVisible(eye_origin, te, id))
  194. {
  195. te = 0
  196. get_user_aim(id, target)
  197. }
  198. if(te)
  199. BodyTarget(te, target)
  200.  
  201. static Float:dist, Float:dist2D
  202. dist = distToEnt(target, id)
  203. dist2D = distToEnt(target, id, true)
  204.  
  205. if(tt == TT_Reload)
  206. goto doAct
  207.  
  208. if(tt != TT_None && (tt == TT_LookAt || FVisible2(eye_origin, target, id)))
  209. entity_set_aim(id, target)
  210. else
  211. {
  212. resetTarget = true
  213. goto end
  214. }
  215.  
  216. doAct:
  217. if(strlen(tw) > 0)
  218. engclient_cmd(id, tw)
  219.  
  220. switch(tt)
  221. {
  222. case TT_None:
  223. {
  224. }
  225. case TT_LookAt:
  226. {
  227. resetTarget = true
  228. }
  229. case TT_Move:
  230. {
  231. if(inWater || onLadder)
  232. {
  233. if(dist > 30.0)
  234. speedforward = 400.0
  235. else if(dist < 5.0)
  236. speedforward = -50.0
  237. else
  238. resetTarget = true
  239. }
  240. else
  241. {
  242. if(dist2D > 30.0)
  243. speedforward = 400.0
  244. else if(dist2D < 5.0)
  245. speedforward = -50.0
  246. else
  247. resetTarget = true
  248. }
  249. if(speedforward > 0.0)
  250. button |= IN_FORWARD
  251. else if(speedforward < 0.0)
  252. button |= IN_BACK
  253. if(speedforward > 0.0 && forwardBlocked && !(oldbutton & IN_JUMP))
  254. button |= IN_DUCK | IN_JUMP
  255. }
  256. case TT_Follow:
  257. {
  258. if(te)
  259. {
  260. if(inWater || onLadder)
  261. {
  262. if(dist > 200.0)
  263. speedforward = 400.0
  264. else if(dist < 80.0)
  265. speedforward = -50.0
  266. }
  267. else
  268. {
  269. if(dist2D > 200.0)
  270. speedforward = 400.0
  271. else if(dist2D < 80.0)
  272. speedforward = -50.0
  273. }
  274. if(speedforward > 0.0)
  275. button |= IN_FORWARD
  276. else if(speedforward < 0.0)
  277. button |= IN_BACK
  278. if(speedforward > 0.0 && forwardBlocked && !(oldbutton & IN_JUMP))
  279. button |= IN_DUCK | IN_JUMP
  280. }
  281. else
  282. resetTarget = true
  283. }
  284. case TT_Use:
  285. {
  286. if(te)
  287. {
  288. if(inWater || onLadder)
  289. {
  290. if(dist > 30.0)
  291. speedforward = 400.0
  292. else if(dist < 5.0)
  293. speedforward = -50.0
  294. else
  295. {
  296. button |= IN_USE
  297. resetTarget = true
  298. }
  299. }
  300. else
  301. {
  302. if(dist2D > 30.0)
  303. speedforward = 400.0
  304. else if(dist2D < 5.0)
  305. speedforward = -50.0
  306. else
  307. {
  308. button |= IN_USE
  309. resetTarget = true
  310. }
  311. }
  312. if(speedforward > 0.0)
  313. button |= IN_FORWARD
  314. else if(speedforward < 0.0)
  315. button |= IN_BACK
  316. if(speedforward > 0.0 && forwardBlocked && !(oldbutton & IN_JUMP))
  317. button |= IN_DUCK | IN_JUMP
  318. }
  319. else
  320. resetTarget = true
  321. }
  322. case TT_Attack:
  323. {
  324. if(te)
  325. {
  326. static clip, ammo
  327. get_user_weapon(id, clip, ammo)
  328. if(clip != 0)
  329. button |= IN_ATTACK
  330. else
  331. button |= IN_RELOAD
  332. }
  333. else
  334. resetTarget = true
  335. }
  336. case TT_Attack2:
  337. {
  338. button |= IN_ATTACK2
  339. resetTarget = true
  340. }
  341. case TT_Reload:
  342. {
  343. button |= IN_RELOAD
  344. resetTarget = true
  345. }
  346. case TT_Svencoop_Revive:
  347. {
  348. if(te)
  349. {
  350. if(inWater || onLadder)
  351. {
  352. if(dist > 50.0)
  353. speedforward = 400.0
  354. else if(dist < 5.0)
  355. speedforward = -50.0
  356. else
  357. button |= IN_ATTACK2
  358. }
  359. else
  360. {
  361. if(dist2D > 50.0)
  362. speedforward = 400.0
  363. else if(dist2D < 5.0)
  364. speedforward = -50.0
  365. else
  366. button |= IN_ATTACK2
  367. }
  368. if(speedforward > 0.0)
  369. button |= IN_FORWARD
  370. else if(speedforward < 0.0)
  371. button |= IN_BACK
  372. if(speedforward > 0.0 && forwardBlocked && !(oldbutton & IN_JUMP))
  373. button |= IN_DUCK | IN_JUMP
  374. }
  375. else
  376. resetTarget = true
  377. }
  378. }
  379. }
  380.  
  381. end:
  382. static Float:msecval
  383. global_get(glb_frametime, msecval)
  384. new msec = floatround(msecval * 1000.0)
  385. static Float:viewangles[3]
  386. pev(id, pev_v_angle, viewangles)
  387. engfunc(EngFunc_RunPlayerMove, id, viewangles, speedforward, 0.0, 0.0, button, 0, msec)
  388. if(resetTarget)
  389. {
  390. get_user_aim(id, g_BotTarget[index])
  391. g_BotTargetType[index] = TT_None
  392. g_BotTargetEnt[index] = 0
  393. g_BotTargetWeapon[index] = ""
  394. g_BotOldButton[index] = button
  395. }
  396. else
  397. {
  398. g_BotTarget[index] = target
  399. g_BotOldButton[index] = button
  400. }
  401. }
  402.  
  403. bool:fForwardBlocked(ent)
  404. {
  405. static Float:origin[3], Float:end[3]
  406. pev(ent, pev_origin, origin)
  407. velocity_by_aim(ent, 48, end)
  408. end[0] += origin[0]
  409. end[1] += origin[1]
  410. end[2] = origin[2] + 6.0
  411. static tr, Float:flFraction
  412. tr = create_tr2()
  413. engfunc(EngFunc_TraceHull, origin, end, 0, HULL_HEAD, ent, tr)
  414. get_tr2(tr, TR_flFraction, flFraction)
  415. if(flFraction != 1.0)
  416. {
  417. free_tr2(tr)
  418. return true
  419. }
  420. end[2] += 18.0
  421. engfunc(EngFunc_TraceHull, origin, end, 0, HULL_HEAD, ent, tr)
  422. get_tr2(tr, TR_flFraction, flFraction)
  423. free_tr2(tr)
  424. return flFraction!=1.0?true:false
  425. }
  426.  
  427. stock BodyTarget(ent, Float:vecTarget[3])
  428. {
  429. static Float:absmin[3], Float:absmax[3]
  430. pev(ent, pev_absmin, absmin)
  431. pev(ent, pev_absmax, absmax)
  432. vecTarget[0] = (absmin[0] + absmax[0]) * 0.5
  433. vecTarget[1] = (absmin[1] + absmax[1]) * 0.5
  434. vecTarget[2] = (absmin[2] + absmax[2]) * 0.5
  435. }
  436.  
  437. stock bool:FVisible(Float:vecSrc[3], pTarget, pSkip)
  438. {
  439. static tr, Float:vecTarget[3], Float:flFraction
  440. tr = create_tr2()
  441. BodyTarget(pTarget, vecTarget)
  442. engfunc(EngFunc_TraceLine, vecSrc, vecTarget, (1 | 0x100), pSkip, tr)
  443. get_tr2(tr, TR_flFraction, flFraction)
  444. free_tr2(tr)
  445. return (flFraction == 1.0)
  446. }
  447.  
  448. stock bool:FVisible2(Float:vecSrc[3], Float:vecTarget[3], pSkip)
  449. {
  450. static tr, Float:flFraction
  451. tr = create_tr2()
  452. engfunc(EngFunc_TraceLine, vecSrc, vecTarget, (1 | 0x100), pSkip, tr)
  453. get_tr2(tr, TR_flFraction, flFraction)
  454. free_tr2(tr)
  455. return (flFraction == 1.0)
  456. }
  457.  
  458. stock Float:fpev(_index, _value) { static Float:v; pev(_index, _value, v); return v; }
  459. stock bool:IsAlive(pEnt) { return (pev(pEnt, pev_deadflag)==0 && fpev(pEnt, pev_health)>0.0); }
  460.  
  461. stock entity_set_aim(ent,const Float:origin2[3])
  462. {
  463. if(!pev_valid(ent))
  464. return 0;
  465.  
  466. static Float:origin[3]
  467. origin[0] = origin2[0]
  468. origin[1] = origin2[1]
  469. origin[2] = origin2[2]
  470.  
  471. static Float:ent_origin[3], Float:view_ofs[3]
  472.  
  473. pev(ent,pev_origin,ent_origin)
  474. pev(ent,pev_view_ofs,view_ofs)
  475. ent_origin[0] += view_ofs[0]
  476. ent_origin[1] += view_ofs[1]
  477. ent_origin[2] += view_ofs[2]
  478.  
  479. origin[0] -= ent_origin[0]
  480. origin[1] -= ent_origin[1]
  481. origin[2] -= ent_origin[2]
  482.  
  483. static Float:v_length
  484. v_length = vector_length(origin)
  485.  
  486. static Float:aim_vector[3]
  487. aim_vector[0] = origin[0] / v_length
  488. aim_vector[1] = origin[1] / v_length
  489. aim_vector[2] = origin[2] / v_length
  490.  
  491. static Float:new_angles[3]
  492. vector_to_angle(aim_vector,new_angles)
  493.  
  494. if(new_angles[1]>180.0) new_angles[1] -= 360
  495. if(new_angles[1]<-180.0) new_angles[1] += 360
  496. if(new_angles[1]==180.0 || new_angles[1]==-180.0) new_angles[1]=-179.999999
  497.  
  498. new_angles[0] *= -1.0
  499.  
  500. set_pev(ent,pev_v_angle,new_angles)
  501.  
  502. new_angles[0] /= -3.0
  503. if(new_angles[0] > 90.0) new_angles[0] -= 120.0
  504.  
  505. set_pev(ent,pev_angles,new_angles)
  506.  
  507. return 1;
  508. }
  509.  
  510. stock get_user_aim(id, Float:aimorig[3])
  511. {
  512. static Float:origin[3], Float:view_ofs[3]
  513. pev(id,pev_origin, origin)
  514. pev(id,pev_view_ofs, view_ofs)
  515. origin[0] += view_ofs[0]
  516. origin[1] += view_ofs[1]
  517. origin[2] += view_ofs[2]
  518.  
  519. static Float:vec[3]
  520. pev(id, pev_v_angle, vec)
  521. engfunc(EngFunc_MakeVectors, vec)
  522. global_get(glb_v_forward, vec)
  523. vec[0] = origin[0] + vec[0] * 9999.0
  524. vec[1] = origin[1] + vec[1] * 9999.0
  525. vec[2] = origin[2] + vec[2] * 9999.0
  526.  
  527. static line, hit
  528. line = create_tr2()
  529. engfunc(EngFunc_TraceLine, origin, vec, 0, id, line)
  530. get_tr2(line,TR_vecEndPos, aimorig)
  531. hit = get_tr2(line, TR_pHit)
  532. free_tr2(line)
  533. return hit
  534. }
  535.  
  536. stock Float:Distance2D(Float:vec1[3],Float:vec2[3]) return floatsqroot((vec1[0]-vec2[0])*(vec1[0]-vec2[0])+(vec1[1]-vec2[1])*(vec1[1]-vec2[1]))
  537.  
  538. stock Float:distToEnt(Float:src[3], ent, bool:_2D=false)
  539. {
  540. static Float:origin[3]
  541. pev(ent, pev_origin, origin)
  542. return _2D?Distance2D(origin, src):vector_distance(origin, src)
  543. }
  544.  
  545. stock kick(id)
  546. {
  547. server_cmd("kick #%d", get_user_userid(id))
  548. server_exec()
  549. }