HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. //#define CSDM
  2. //Uncomment the above line if you have CSDM installed
  3.  
  4. /*
  5. Changelog
  6. ---------
  7. v1.2:
  8. - Fixed plugin not working when csdm is not installed.
  9. v1.1:
  10. - Better approach to wall planting.
  11. - Fixed c4_wait not getting disabled.
  12. */
  13.  
  14. #include <amxmodx>
  15. #include <cstrike>
  16. #include <csx>
  17. #include <fakemeta>
  18.  
  19. #if defined CSDM
  20. #include <csdm>
  21. #endif
  22.  
  23. #define OFFSET_TEAM 114
  24. #define OFFSET_CSDEATHS 444
  25.  
  26. #define NO_CSDM_TASK_ID 199
  27. #define STACK_SIZE 16
  28.  
  29. // PCvars
  30. new g_pcvarAnywhere
  31. new g_pcvarBuy
  32. new g_pcvarCTBuy
  33. new g_pcvarKills
  34. new g_pcvarWall
  35. new g_pcvarCost
  36. new g_pcvarWait
  37. new g_pcvarCsdm
  38.  
  39. // Cache
  40. new g_msgDeath
  41. new g_msgShowTimer
  42. new g_msgScoreInfo
  43.  
  44. new g_RoundEndDisabled
  45. new g_PlanterID
  46. new g_Planters[STACK_SIZE]
  47.  
  48. public plugin_precache()
  49. {
  50. g_pcvarAnywhere = register_cvar("c4_anywhere", "1");
  51.  
  52. // Create PlantAnywhere Bombsite
  53.  
  54. if(get_pcvar_num(g_pcvarAnywhere))
  55. CreateBombTarget();
  56. }
  57.  
  58. public plugin_init()
  59. {
  60. register_plugin("Plant Anywhere 2", "1.2", "Av3ngeR");
  61.  
  62. register_concmd("c4", "cmdBuyC4");
  63. register_srvcmd("c4_disable_roundend", "cmdNoRoundEnd");
  64.  
  65. register_event("HLTV", "eventNewRound", "a", "1=0", "2=0");
  66. register_event("23", "eventBombExplode", "a", "1=17", "6=-105", "7=17");
  67.  
  68. register_logevent("eventRoundStart", 2, "1=Round_Start");
  69. register_logevent("eventJoinTerrorist", 3, "1=joined team", "2=TERRORIST");
  70. register_logevent("eventBombPlanted", 3, "2=Planted_The_Bomb");
  71. register_logevent("eventBombDefused", 3, "2=Defused_The_Bomb")
  72.  
  73. register_forward(FM_Touch, "forwardTouch");
  74. register_forward(FM_CmdStart, "forwardCmdStart");
  75.  
  76. g_pcvarBuy = register_cvar("c4_buy", "1");
  77. g_pcvarCTBuy = register_cvar("c4_buy_ct", "0");
  78. g_pcvarKills = register_cvar("c4_kill", "1");
  79. g_pcvarWall = register_cvar("c4_wall", "1");
  80. g_pcvarCost = register_cvar("c4_cost", "3000");
  81. g_pcvarWait = register_cvar("c4_wait", "20");
  82. g_pcvarCsdm = register_cvar("csdm_active", "0");
  83.  
  84. g_msgDeath = get_user_msgid("DeathMsg");
  85. g_msgShowTimer = get_user_msgid("ShowTimer");
  86. g_msgScoreInfo = get_user_msgid("ScoreInfo");
  87. }
  88.  
  89. public forwardCmdStart(id, ucHandle, Seed)
  90. {
  91. if(is_user_alive(id) && (get_user_weapon(id) == CSW_C4))
  92. {
  93. // Disable planting till amx_c4Wait seconds
  94. if(task_exists(id) || task_exists(NO_CSDM_TASK_ID))
  95. {
  96. // DevconeS's Code
  97. new buttons = get_uc(ucHandle,UC_Buttons)
  98.  
  99. if(buttons & IN_ATTACK)
  100. {
  101. buttons &= ~IN_ATTACK
  102. set_uc(ucHandle,UC_Buttons,buttons)
  103. }
  104. }
  105. }
  106. }
  107.  
  108. public forwardTouch(touchedID,toucherID)
  109. {
  110. static touchedClass[32], toucherClass[32];
  111.  
  112. if(!pev_valid(touchedID))
  113. return FMRES_IGNORED;
  114.  
  115. // Get Classnames of the entity
  116. pev(touchedID, pev_classname, touchedClass, 31);
  117. pev(toucherID, pev_classname, toucherClass, 31);
  118.  
  119. if(equal(touchedClass, "weaponbox") && equal(toucherClass, "player"))
  120. {
  121. // Get Modelname of the weapon entity
  122.  
  123. static touchedModel[32];
  124. pev(touchedID, pev_model, touchedModel, 31);
  125.  
  126. // Do not allow player to pickup bomb if he already has it
  127.  
  128. if(equal(touchedModel, "models/w_backpack.mdl"))
  129. {
  130. if(user_has_weapon(toucherID, CSW_C4))
  131. return FMRES_SUPERCEDE
  132. }
  133. }
  134. return FMRES_IGNORED
  135. }
  136.  
  137. public cmdNoRoundEnd()
  138. {
  139. fm_remove_entity_name("func_bomb_target");
  140. fm_remove_entity_name("info_bomb_target");
  141.  
  142. CreateBombTarget();
  143.  
  144. g_RoundEndDisabled = 1;
  145. }
  146.  
  147. public cmdBuyC4(id)
  148. {
  149. if(!is_user_alive(id))
  150. return;
  151.  
  152. if(!get_pcvar_num(g_pcvarBuy))
  153. {
  154. client_print(id, print_center, "#Cstrike_Not_Available")
  155. return;
  156. }
  157.  
  158. if(!cs_get_user_buyzone(id))
  159. {
  160. if(!get_pcvar_num(g_pcvarCsdm))
  161. {
  162. client_print(id, print_center, "You must be in the buy zone in order to purchase")
  163. return;
  164. }
  165. }
  166.  
  167. if(cs_get_user_team(id) == CS_TEAM_CT)
  168. {
  169. if(!get_pcvar_num(g_pcvarCTBuy))
  170. {
  171. client_print(id, print_center, "#Cstrike_TitlesTXT_Cannot_Buy_This")
  172. return;
  173. }
  174. }
  175.  
  176. if(user_has_weapon(id, CSW_C4))
  177. {
  178. client_print(id, print_center, "#Cstrike_Already_Own_Weapon");
  179. return;
  180. }
  181.  
  182. new BombCost = get_pcvar_num(g_pcvarCost);
  183. new PlayerMoney = cs_get_user_money(id);
  184.  
  185. if(PlayerMoney < BombCost)
  186. {
  187. client_print(id, print_center, "#Cstrike_TitlesTXT_Not_Enough_Money");
  188. return;
  189. }
  190.  
  191. fm_give_item(id, "weapon_c4");
  192. cs_set_user_money(id, PlayerMoney - BombCost);
  193. cs_set_user_plant(id, 1);
  194.  
  195. if(get_pcvar_num(g_pcvarAnywhere))
  196. {
  197. if(get_pcvar_num(g_pcvarWait) <= 1)
  198. return;
  199.  
  200. if(get_pcvar_num(g_pcvarCsdm))
  201. {
  202. // Avoid multiple tasks due to multiple buys
  203.  
  204. if(task_exists(id))
  205. remove_task(id);
  206.  
  207. set_task(get_pcvar_float(g_pcvarWait), "AllowPlanting", id);
  208.  
  209. client_print(id, print_chat, "You are allowed to plant after %d seconds", get_pcvar_num(g_pcvarWait));
  210. }
  211. }
  212. }
  213.  
  214. public eventJoinTerrorist()
  215. {
  216. if(!get_pcvar_num(g_pcvarBuy))
  217. return;
  218.  
  219. new id;
  220.  
  221. id = get_loguser_index();
  222.  
  223. client_print(id, print_chat, "Terrorists can buy C4 ($%d) by entering ^"c4^" in console", get_pcvar_num(g_pcvarCost));
  224. }
  225.  
  226. public eventNewRound()
  227. {
  228. // Remove Bomb Objectives so dat there is no round-end
  229. // Server has to restart to revert back
  230.  
  231. if(!g_RoundEndDisabled)
  232. {
  233. if(get_pcvar_num(g_pcvarCsdm))
  234. {
  235. cmdNoRoundEnd();
  236. }
  237. }
  238.  
  239. // Clear all plants
  240. for(new i=0; i < STACK_SIZE; i++)
  241. {
  242. g_Planters[i] = 0;
  243. }
  244. }
  245.  
  246. public eventRoundStart()
  247. {
  248. if(!get_pcvar_num(g_pcvarAnywhere))
  249. return;
  250.  
  251. new id, Max;
  252.  
  253. static Players[32];
  254.  
  255. get_players(Players, Max, "ae", "TERRORIST");
  256.  
  257. for(new i=0; i<Max; i++)
  258. {
  259. // Cache
  260. id = Players[i];
  261.  
  262. if(user_has_weapon(id, CSW_C4))
  263. {
  264. if(get_pcvar_num(g_pcvarWait) < 1)
  265. break;
  266.  
  267. // Needs to be displayed regardless of g_pcvarCsdm
  268. client_print(id, print_chat, "You are allowed to plant after %d seconds", get_pcvar_num(g_pcvarWait));
  269.  
  270. if(get_pcvar_num(g_pcvarCsdm))
  271. {
  272. // Avoid multiple tasks due to multiple restarts in g_pcvarWait seconds
  273.  
  274. if(task_exists(id))
  275. remove_task(id);
  276.  
  277. set_task(get_pcvar_float(g_pcvarWait), "AllowPlanting", id);
  278. }
  279. }
  280. }
  281.  
  282. // Should not be inside loop since it won't get executed if no one has the C4
  283.  
  284. if(!get_pcvar_num(g_pcvarCsdm))
  285. {
  286. // Avoid multiple tasks due to multiple restarts in g_pcvarWait seconds
  287.  
  288. if(task_exists(NO_CSDM_TASK_ID))
  289. {
  290. remove_task(NO_CSDM_TASK_ID);
  291. }
  292.  
  293. set_task(get_pcvar_float(g_pcvarWait), "AllowPlanting", NO_CSDM_TASK_ID);
  294. }
  295. }
  296.  
  297. public eventBombPlanted()
  298. {
  299. new id = get_loguser_index();
  300.  
  301. if(get_pcvar_num(g_pcvarKills))
  302. {
  303. for(new i=0; i < STACK_SIZE; i++)
  304. {
  305. if(g_Planters[i] > 0)
  306. continue;
  307.  
  308. g_Planters[i] = id;
  309. break;
  310. }
  311. }
  312.  
  313. // Based on Cheap_Suit's Code
  314.  
  315. if(!get_pcvar_num(g_pcvarWall))
  316. return;
  317.  
  318. new Float:Origin[3], Float:Normal[3];
  319. if(!fm_get_aim_origin_normal(id, Origin, Normal))
  320. return;
  321.  
  322. new c4;
  323. while((c4 = fm_find_ent_by_model(c4, "grenade", "models/w_c4.mdl")))
  324. {
  325.  
  326. if(pev(c4, pev_movetype) == MOVETYPE_FLY || (pev(c4, pev_flags) & FL_ONGROUND))
  327. continue;
  328.  
  329. set_pev(c4, pev_movetype, MOVETYPE_FLY);
  330.  
  331. Origin[1] -= 0.7;
  332. engfunc(EngFunc_SetOrigin, c4, Origin);
  333.  
  334. new Float:Angles[3];
  335. vector_to_angle(Normal, Angles);
  336. Angles[1] -= 90.0;
  337. Angles[2] -= 90.0;
  338. set_pev(c4, pev_angles, Angles);
  339. }
  340. }
  341.  
  342. public eventBombExplode()
  343. {
  344. for(new i=0; i < STACK_SIZE; i++)
  345. {
  346. if(g_Planters[i] > 0)
  347. {
  348. g_PlanterID = g_Planters[i];
  349. g_Planters[i] = g_Planters[++i];
  350. g_Planters[++i] = 0;
  351. break;
  352. }
  353. }
  354.  
  355. // Timer doesn't show up when objectives are removed
  356.  
  357. if(g_RoundEndDisabled)
  358. {
  359. message_begin(MSG_ALL, g_msgShowTimer, _, 0);
  360. message_end();
  361. }
  362.  
  363. if(get_pcvar_num(g_pcvarKills))
  364. {
  365. // No Target Bombed bonus
  366.  
  367. new Float:frags;
  368. pev(g_PlanterID, pev_frags, frags);
  369. fm_set_user_frags(g_PlanterID, frags - 3.0);
  370. }
  371. }
  372.  
  373. public eventBombDefused(id)
  374. {
  375. new Float:frags;
  376. pev(id, pev_frags, frags);
  377. fm_set_user_frags(id, frags + 3.0);
  378.  
  379. // Timer doesn't show up when objectives are removed
  380.  
  381. if(g_RoundEndDisabled)
  382. {
  383. message_begin(MSG_ALL, g_msgShowTimer, _, 0);
  384. message_end();
  385. }
  386. }
  387.  
  388. public client_death(KillerID , VictimID , WeaponID, HitboxID, isTK)
  389. {
  390. // CT killed by C4
  391.  
  392. if(get_pcvar_num(g_pcvarKills) && (WeaponID == CSW_C4) && (cs_get_user_team(VictimID) != cs_get_user_team(g_PlanterID)))
  393. {
  394. // Increase Planter's Frags by 1
  395.  
  396. new Float:frags;
  397. pev(g_PlanterID, pev_frags, frags);
  398. fm_set_user_frags(g_PlanterID, ++frags);
  399.  
  400. // Increase Victims's Deaths by 1
  401.  
  402. cs_set_user_deaths(VictimID, cs_get_user_deaths(VictimID) + 1);
  403.  
  404. // Displayed Death Message
  405.  
  406. message_begin(MSG_BROADCAST, g_msgDeath);
  407. write_byte(g_PlanterID);
  408. write_byte(VictimID);
  409. write_byte(0);
  410. write_string("c4");
  411. message_end();
  412. }
  413.  
  414.  
  415. #if defined CSDM
  416.  
  417. // Player doesnt respawn when objectives are removed
  418.  
  419. if(get_pcvar_num(g_pcvarCsdm) && !is_user_alive(VictimID))
  420. {
  421. csdm_respawn(VictimID);
  422. }
  423.  
  424. #endif
  425.  
  426.  
  427. }
  428.  
  429. public AllowPlanting() {}
  430.  
  431. public CreateBombTarget()
  432. {
  433. new NewBombTarget = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "func_bomb_target"))
  434. if(NewBombTarget > 0)
  435. {
  436. dllfunc(DLLFunc_Spawn, NewBombTarget)
  437. engfunc(EngFunc_SetSize, NewBombTarget, Float:{-100000.0,-100000.0,-100000.0}, Float:{100000.0,100000.0,100000.0})
  438. }
  439. }
  440.  
  441. stock get_loguser_index()
  442. {
  443. new Log[80], Name[32];
  444.  
  445. read_logargv(0, Log, 79);
  446. parse_loguser(Log, Name, 31);
  447.  
  448. return get_user_index(Name);
  449. }
  450.  
  451. stock fm_set_user_frags(id, Float:Frags)
  452. {
  453. set_pev(g_PlanterID, pev_frags, Frags);
  454.  
  455. message_begin(MSG_ALL, g_msgScoreInfo);
  456. write_byte(id);
  457. write_short(floatround(Frags));
  458. write_short(get_pdata_int(id, OFFSET_CSDEATHS));
  459. write_short(0);
  460. write_short(get_pdata_int(id, OFFSET_TEAM));
  461. message_end();
  462. }
  463.  
  464. // From fakemeta_util
  465. stock fm_find_ent_by_model(index, const classname[], const model[])
  466. {
  467. new ent = index, mdl[72];
  468. while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)))
  469. {
  470. pev(ent, pev_model, mdl, sizeof mdl - 1);
  471. if (equal(mdl, model))
  472. return ent;
  473. }
  474.  
  475. return 0;
  476. }
  477.  
  478. // From fakemeta_util
  479. stock fm_give_item(index, const item[])
  480. {
  481. if (!equal(item, "weapon_", 7) && !equal(item, "ammo_", 5) && !equal(item, "item_", 5) && !equal(item, "tf_weapon_", 10))
  482. return 0;
  483.  
  484. new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, item));
  485. if (!pev_valid(ent))
  486. return 0;
  487.  
  488. new Float:origin[3];
  489. pev(index, pev_origin, origin);
  490. set_pev(ent, pev_origin, origin);
  491. set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN);
  492. dllfunc(DLLFunc_Spawn, ent);
  493.  
  494. new save = pev(ent, pev_solid);
  495. dllfunc(DLLFunc_Touch, ent, index);
  496. if (pev(ent, pev_solid) != save)
  497. return ent;
  498.  
  499. engfunc(EngFunc_RemoveEntity, ent);
  500.  
  501. return -1;
  502. }
  503.  
  504. // From fakemeta_util
  505. stock fm_remove_entity_name(const classname[]) {
  506. new ent = -1, num = 0;
  507. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)))
  508. num += engfunc(EngFunc_RemoveEntity, ent);
  509.  
  510. return num;
  511. }
  512.  
  513. // From fakemeta_util (Combined 2 functions)
  514. stock fm_get_aim_origin_normal(index, Float:origin[3], Float:normal[3]) {
  515. new Float:start[3], Float:view_ofs[3];
  516. pev(index, pev_origin, start);
  517. pev(index, pev_view_ofs, view_ofs);
  518.  
  519. start[0] += view_ofs[0];
  520. start[1] += view_ofs[1];
  521. start[2] += view_ofs[2];
  522.  
  523. new Float:dest[3];
  524. pev(index, pev_v_angle, dest);
  525. engfunc(EngFunc_MakeVectors, dest);
  526. global_get(glb_v_forward, dest);
  527.  
  528. dest[0] *= 54.0;
  529. dest[1] *= 54.0;
  530. dest[2] *= 54.0;
  531.  
  532. dest[0] += start[0];
  533. dest[1] += start[1];
  534. dest[2] += start[2];
  535.  
  536. engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
  537. get_tr2(0, TR_vecEndPos, origin);
  538. get_tr2(0, TR_vecPlaneNormal, normal);
  539.  
  540. new Float:fraction;
  541. get_tr2(0, TR_flFraction, fraction);
  542. if (fraction >= 1.0)
  543. return 0;
  544.  
  545. return 1;
  546. }
  547.