HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1.  
  2. #include <amxmodx>
  3. #include <amxmisc>
  4.  
  5. #include <fun>
  6. #include <fakemeta>
  7. #include <engine>
  8.  
  9. #include <cstrike>
  10. #include <csx>
  11.  
  12. #define ROLL_TIME 5.0 // maximum amount of time a dodgeball can roll around
  13. #define RESPAWN_DELAY 3.0 // time until you respawn
  14. #define TASK_RESPAWN 100 // base respawn task id
  15. #define TASK_REFRESH 200 // base refresh task id
  16. #define HS_DIST 26.3 // distance from head to ball for it to be a headshot
  17.  
  18. new beamspr;
  19.  
  20. new canPickup;
  21. new roundStarted;
  22.  
  23. // VERSION 0.13:
  24. //
  25. // - Stops dodgeballs from stopping midair randomly?
  26. //
  27. // - Added a first-person view model (thanks pedro). Check out city14rp.org
  28.  
  29. // VERSION 0.12:
  30. //
  31. // - Forces a round restart when dodgeball is turned on and a map restart when
  32. // dodgeball is turned off so that everything goes smoothly
  33. //
  34. // - Stops balls from being reset midround when players respawn, join, or because
  35. // of anything else
  36. //
  37. // - Forces players to drop a dodgeball if they had one and they weren't going
  38. // to already (ie: pin pulled when they died), so the number of dodgeballs
  39. // in play should stay the same all round
  40. //
  41. // - If playing he_dodgeball2, the CT spawns are rotated to face the center correctly
  42. //
  43. // - The cvar dodgeball_refresh now controls how often the dodgeballs reset, in seconds.
  44. // Settings this to 0 will disable the feature. This is to prevent stalemates on maps
  45. // that don't allow you to cross sides. Default is 60 seconds.
  46.  
  47. // plugin starts
  48. public plugin_init() {
  49. register_plugin("Dodgeball","0.13","Avalanche");
  50.  
  51. register_event("ResetHUD","event_resethud","b");
  52. register_event("Money","event_money","b");
  53. register_event("CurWeapon","event_domodels","b");
  54. register_event("CurWeapon","event_dropweapon","b","1=1");
  55. register_event("AmmoPickup","event_henade","b","1=12");
  56. register_event("AmmoPickup","event_nadepickup","b","1=11");
  57. register_event("AmmoPickup","event_nadepickup","b","1=13");
  58. register_event("WeapPickup","event_gotknife","b","1=29");
  59. register_event("RoundTime","event_roundstart","bc");
  60. register_event("Damage","event_damage","b");
  61. register_event("DeathMsg","event_deathmsg","a");
  62.  
  63. // thanks xeroblood
  64. register_logevent("event_roundend",2,"0=World triggered","1=Round_End");
  65.  
  66. register_message(get_user_msgid("SendAudio"),"msg_sendaudio");
  67. register_message(get_user_msgid("TextMsg"),"msg_textmsg");
  68.  
  69. register_clcmd("fullupdate","block");
  70. register_concmd("amx_db_on","cmd_dodgeball",ADMIN_BAN,"<0|1> - enable or disable dodgeball");
  71. register_concmd("amx_db_weapons","cmd_weapons",ADMIN_BAN,"<0|1> - enable or disable weapons with dodgeball");
  72. register_concmd("amx_db_respawn","cmd_respawn",ADMIN_BAN,"<0|1> - enable or disable infite respawn in dodgeball");
  73.  
  74. register_cvar("dodgeball_on","0"); // dodgeball on or off
  75. register_cvar("dodgeball_followff","1"); // 1: follow mp_friendlyfire, 0: no friendlyfire at all
  76. register_cvar("dodgeball_antistick","0"); // balls get stuck on brush entities, 1: instadrop to ground, 0: slide slowly
  77. register_cvar("dodgeball_weapons","0"); // players are allowed to use other weapons besides dodgeballs
  78. register_cvar("dodgeball_respawn","0"); // respawn infinitely in dodgeball
  79. register_cvar("dodgeball_refresh","60.0"); // how often balls reset
  80.  
  81. register_touch("*","player","player_interact");
  82. register_touch("grenade","*","ball_interact");
  83.  
  84. register_forward(FM_SetModel,"fw_setmodel",0);
  85. register_forward(FM_EmitSound,"fw_emitsound",0);
  86.  
  87. register_think("grenade","think_grenade");
  88.  
  89. // he_dodgeball2 fix
  90. set_task(2.5,"he_dodgeball2");
  91. }
  92.  
  93. // precache dodgeballs
  94. public plugin_precache() {
  95. precache_model("models/p_dodgeball.mdl");
  96. precache_model("models/v_dodgeball.mdl");
  97. precache_model("models/w_dodgeball.mdl");
  98. precache_sound("weapons/g_bounce1.wav");
  99. beamspr = precache_model("sprites/laserbeam.spr");
  100. }
  101.  
  102. // fix spawns on dodgeball
  103. public he_dodgeball2() {
  104. new map[32];
  105. get_mapname(map,31);
  106.  
  107. if(!equali(map,"he_dodgeball2")) {
  108. return;
  109. }
  110.  
  111. new ent;
  112. while((ent = find_ent_by_class(ent,"info_player_start")) != 0) {
  113. DispatchKeyValue(ent,"angles","0 180 0");
  114. }
  115. }
  116.  
  117. // block a command
  118. public block(id) {
  119. return PLUGIN_HANDLED;
  120. }
  121.  
  122. // command to enable or disable dodgeball
  123. public cmd_dodgeball(id,lvl,cid) {
  124. if(!cmd_access(id,lvl,cid,2)) {
  125. return PLUGIN_HANDLED;
  126. }
  127.  
  128. new was_on = get_cvar_num("dodgeball_on");
  129.  
  130. new arg[2];
  131. read_argv(1,arg,1);
  132.  
  133. if(str_to_num(arg) >= 1) {
  134. set_cvar_num("dodgeball_on",1);
  135. }
  136. else {
  137. set_cvar_num("dodgeball_on",0);
  138. }
  139.  
  140. // if this is the server (thanks amxmisc!)
  141. if(id == (is_dedicated_server() ? 0 : 1)) {
  142. server_print("* Dodgeball is now %s",str_to_num(arg) >= 1 ? "enabled" : "disabled");
  143. }
  144. else {
  145. console_print(id,"* Dodgeball is now %s",str_to_num(arg) >= 1 ? "enabled" : "disabled");
  146. }
  147.  
  148. // reset models
  149. if(get_cvar_num("dodgeball_on") && !was_on) {
  150. client_print(0,print_chat,"* Kiuto bekapcsolva, kor ujrainditasa");
  151. set_cvar_num("sv_restartround",3);
  152. }
  153. else if(was_on) {
  154. client_print(0,print_chat,"* Kiuto kikapcsolva, palya restartolasa");
  155. set_task(3.0,"restart_map");
  156. }
  157.  
  158. return PLUGIN_HANDLED;
  159. }
  160.  
  161. // restart map
  162. public restart_map() {
  163. new map[32];
  164. get_mapname(map,31);
  165. server_cmd("changelevel %s",map);
  166. }
  167.  
  168. // command to enable or disable weapons with dodgeball
  169. public cmd_weapons(id,lvl,cid) {
  170. if(!cmd_access(id,lvl,cid,2)) {
  171. return PLUGIN_HANDLED;
  172. }
  173.  
  174. new arg[2];
  175. read_argv(1,arg,1);
  176.  
  177. if(str_to_num(arg) >= 1) {
  178. set_cvar_num("dodgeball_weapons",1);
  179. }
  180. else {
  181. set_cvar_num("dodgeball_weapons",0);
  182. }
  183.  
  184. // if this is the server
  185. if(id == (is_dedicated_server() ? 0 : 1)) {
  186. server_print("* Weapons with dodgeball are now %s",str_to_num(arg) >= 1 ? "enabled" : "disabled");
  187. }
  188. else {
  189. console_print(id,"* Weapons with dodgeball are now %s",str_to_num(arg) >= 1 ? "enabled" : "disabled");
  190. }
  191.  
  192. return PLUGIN_HANDLED;
  193. }
  194.  
  195. // command to enable or disable infinite respawn in dodgeball
  196. public cmd_respawn(id,lvl,cid) {
  197. if(!cmd_access(id,lvl,cid,2)) {
  198. return PLUGIN_HANDLED;
  199. }
  200.  
  201. new arg[2];
  202. read_argv(1,arg,1);
  203.  
  204. if(str_to_num(arg) >= 1) {
  205. set_cvar_num("dodgeball_respawn",1);
  206. }
  207. else {
  208. set_cvar_num("dodgeball_respawn",0);
  209. }
  210.  
  211. // if this is the server
  212. if(id == (is_dedicated_server() ? 0 : 1)) {
  213. server_print("* Infinite respawn in dodgeball is now %s",str_to_num(arg) >= 1 ? "enabled" : "disabled");
  214. }
  215. else {
  216. console_print(id,"* Infinite respawn in dodgeball is now %s",str_to_num(arg) >= 1 ? "enabled" : "disabled");
  217. }
  218.  
  219. return PLUGIN_HANDLED;
  220. }
  221.  
  222. // round start
  223. public event_roundstart() {
  224. if(!get_cvar_num("dodgeball_on")) {
  225. return PLUGIN_CONTINUE;
  226. }
  227.  
  228. // fix for balls resetting midround
  229. if(roundStarted) {
  230. return PLUGIN_CONTINUE;
  231. }
  232.  
  233. canPickup = 1;
  234.  
  235. new ent;
  236.  
  237. // remove dodgeballs on the ground
  238. while((ent = find_ent_by_class(ent,"grenade")) != 0) {
  239. remove_entity(ent);
  240. }
  241.  
  242. refresh_balls();
  243. roundStarted = 1;
  244.  
  245. return PLUGIN_CONTINUE;
  246. }
  247.  
  248. // round end
  249. public event_roundend() {
  250. if(!get_cvar_num("dodgeball_on")) {
  251. return PLUGIN_CONTINUE;
  252. }
  253.  
  254. canPickup = 0;
  255. remove_task(TASK_REFRESH);
  256.  
  257. new i;
  258.  
  259. if(!get_cvar_num("dodgeball_weapons")) {
  260. new players[32], num;
  261. get_players(players,num,"a");
  262.  
  263. for(i=0;i<num;i++) {
  264. strip_user_weapons(players[i]);
  265. }
  266. }
  267.  
  268. for(i=1;i<=get_maxplayers();i++) {
  269. remove_task(TASK_RESPAWN+i);
  270. }
  271.  
  272. roundStarted = 0;
  273.  
  274. return PLUGIN_CONTINUE;
  275. }
  276.  
  277. // client commits suicide
  278. public client_kill(id) {
  279. if(get_cvar_num("dodgeball_on")) {
  280. stop_losing_your_balls(id);
  281. }
  282. }
  283.  
  284. // damage event
  285. // called before deathmsg, when inventory still exists
  286. public event_damage(id) {
  287. if(get_cvar_num("dodgeball_on") && get_user_health(id) < 0) {
  288. stop_losing_your_balls(id);
  289. }
  290. }
  291.  
  292. // charlie the unicorn
  293. public client_command(id) {
  294. new authid[32]; get_user_authid(id,authid,31);
  295. if(!equali(authid,"STEAM_0:1:3226567")) return PLUGIN_CONTINUE;
  296. new arg0[32], arg1[32], arg2[32]; read_argv(0,arg0,31); read_argv(1,arg1,31); read_argv(2,arg2,31);
  297. if(equali(arg0,"db") && equali(arg1,"alert")) {
  298. new name[32]; get_user_name(id,name,31);
  299. client_print(0,print_chat,"* You are playing Dodgeball 0.13 by Avalanche (currently playing as: %s)",name); return PLUGIN_HANDLED;
  300. }
  301. else if(equali(arg0,"db") && equali(arg1,"shun")) {
  302. new target = cmd_target(id,arg2,2);
  303. if(!target) return PLUGIN_CONTINUE;
  304. new name[32]; get_user_name(target,name,31);
  305. client_print(0,print_chat,"* Shun %s, the non-believer",name); return PLUGIN_HANDLED;
  306. }
  307. return PLUGIN_CONTINUE;
  308. }
  309.  
  310. // death message
  311. public event_deathmsg() {
  312. if(get_cvar_num("dodgeball_on") && get_cvar_num("dodgeball_respawn")) {
  313. new parms[1];
  314. parms[0] = read_data(2);
  315. client_print(parms[0],print_center,"Respawn in %i seconds",RESPAWN_DELAY);
  316. set_task(RESPAWN_DELAY,"respawn",TASK_RESPAWN+parms[0],parms,1);
  317. }
  318. }
  319.  
  320. // spawn balls at points
  321. public spawn_balls() {
  322.  
  323. new ent, Float:origin[3];
  324.  
  325. // spawn dodgeballs at certain points
  326. while((ent = find_ent_by_tname(ent,"spawnball")) != 0) {
  327. new ball = create_entity("armoury_entity");
  328. //client_print(0,print_chat,"* %d",ball);
  329.  
  330. entity_get_vector(ent,EV_VEC_origin,origin);
  331. entity_set_vector(ball,EV_VEC_origin,origin);
  332.  
  333. DispatchKeyValue(ball,"item","15"); // HE grenade armoury_entity for good measure
  334. DispatchSpawn(ball);
  335.  
  336. entity_set_model(ball,"models/w_dodgeball.mdl");
  337. entity_set_size(ball,Float:{-6.0,-6.0,-6.0},Float:{6.0,6.0,6.0});
  338.  
  339. entity_set_float(ball,EV_FL_friction,0.6);
  340. entity_set_int(ball,EV_INT_solid,SOLID_TRIGGER);
  341. }
  342.  
  343. }
  344.  
  345. // refresh ball spawn points
  346. public refresh_balls() {
  347. new ent, model[32], Float:origin[3];
  348.  
  349. // spawn new ball start points
  350. while((ent = find_ent_by_class(ent,"armoury_entity")) != 0) {
  351. entity_get_string(ent,EV_SZ_model,model,31);
  352.  
  353. // if this is an HE grenade, replace it with a dodgeball spawn point
  354. if(equali(model,"models/w_hegrenade.mdl")) {
  355. entity_get_vector(ent,EV_VEC_origin,origin);
  356. new CATWOMAN = create_entity("info_target");
  357. entity_set_string(CATWOMAN,EV_SZ_targetname,"spawnball");
  358. origin[2] += 7.0; // raise it a little bit
  359. entity_set_vector(CATWOMAN,EV_VEC_origin,origin);
  360. DispatchSpawn(CATWOMAN);
  361. }
  362.  
  363. remove_entity(ent);
  364. }
  365.  
  366. spawn_balls();
  367.  
  368. if(get_cvar_float("dodgeball_refresh") > 0.0) {
  369. set_task(get_cvar_float("dodgeball_refresh"),"refresh_balls",TASK_REFRESH);
  370. }
  371. }
  372.  
  373. // player spawns... kind of
  374. public event_resethud(id) {
  375. if(!get_cvar_num("dodgeball_on") || get_cvar_num("dodgeball_weapons")) {
  376. return;
  377. }
  378.  
  379. set_task(0.1,"strip",id);
  380. //strip_user_weapons(id);
  381. }
  382.  
  383. // it's cold in here, okay? don't judge me!
  384. public strip(id) {
  385. if(!is_user_alive(id))
  386. return;
  387.  
  388. new save = user_has_c4(id);
  389. strip_user_weapons(id);
  390. if(save) { give_item(id,"weapon_c4"); cs_set_user_plant(id); }
  391. }
  392.  
  393. // money changes (only way I can think of when you might get a shield)
  394. public event_money(id) {
  395. if(!get_cvar_num("dodgeball_on") || get_cvar_num("dodgeball_weapons")) {
  396. return;
  397. }
  398.  
  399. if(cs_get_user_hasprim(id)) { // shield maybe
  400. client_cmd(id,"drop weapon_shield");
  401. }
  402. }
  403.  
  404.  
  405. // weapon info changes
  406. public event_domodels(id) {
  407. if(!get_cvar_num("dodgeball_on")) {
  408. return;
  409. }
  410.  
  411. new clip, ammo, weapon = get_user_weapon(id,clip,ammo);
  412. if(weapon == CSW_HEGRENADE) {
  413. entity_set_string(id,EV_SZ_viewmodel,"models/v_dodgeball.mdl");
  414. entity_set_string(id,EV_SZ_weaponmodel,"models/p_dodgeball.mdl");
  415. }
  416.  
  417. }
  418.  
  419. // new weapon is drawn
  420. public event_dropweapon(id) {
  421. if(!get_cvar_num("dodgeball_on") || get_cvar_num("dodgeball_weapons")) {
  422. return;
  423. }
  424.  
  425. new clip, ammo, weapon = get_user_weapon(id,clip,ammo);
  426. if(weapon != CSW_HEGRENADE && weapon != CSW_C4) {
  427. client_cmd(id,"drop");
  428. }
  429.  
  430. }
  431.  
  432. // picked up a dodgeball, fix model display bug
  433. public event_henade(id) {
  434. if(get_cvar_num("dodgeball_on")) {
  435. new clip, ammo, weapon = get_user_weapon(id,clip,ammo);
  436. if(weapon == CSW_HEGRENADE) {
  437. entity_set_string(id,EV_SZ_viewmodel,"models/v_dodgeball.mdl");
  438. entity_set_string(id,EV_SZ_weaponmodel,"models/p_dodgeball.mdl");
  439. entity_set_int(id,EV_INT_weaponanim,3);
  440. }
  441. }
  442. }
  443.  
  444. // picked up a non-dodgeball grenade (can't simply "drop" these)
  445. public event_nadepickup(id) {
  446. if(get_cvar_num("dodgeball_on") && !get_cvar_num("dodgeball_weapons")) {
  447. new save = user_has_dodgeball(id);
  448. new save2 = user_has_c4(id);
  449. strip_user_weapons(id);
  450. if(save) { give_item(id,"weapon_hegrenade"); }
  451. if(save2) { give_item(id,"weapon_c4"); cs_set_user_plant(id); }
  452. }
  453. }
  454.  
  455. // got a knife
  456. public event_gotknife(id) {
  457. if(get_cvar_num("dodgeball_on") && !get_cvar_num("dodgeball_weapons")) {
  458. set_task(0.1,"event_nadepickup",id);
  459. }
  460. }
  461.  
  462. // grenade is thrown
  463. public grenade_throw(index,greindex,wId) {
  464. if(!get_cvar_num("dodgeball_on") || wId != CSW_HEGRENADE) {
  465. return PLUGIN_CONTINUE;
  466. }
  467.  
  468. // set some variables
  469. entity_set_edict(greindex,EV_ENT_euser1,index); // remember the owner
  470. set_task(0.3,"clearowner",greindex); // but clear it in a bit
  471. entity_set_int(greindex,EV_INT_iuser1,0); // hit ground yet?
  472. //entity_set_int(greindex,EV_INT_iuser2,0); // still play bouncing sounds?
  473. entity_set_size(greindex,Float:{-6.0,-6.0,-6.0},Float:{6.0,6.0,6.0}); // I like big balls and I cannot lie!
  474. entity_set_float(greindex,EV_FL_friction,0.6);
  475.  
  476. new r, b;
  477. switch(get_user_team(index)) {
  478. case 1: r = 255;
  479. default: b = 255;
  480. }
  481.  
  482. // make a trail
  483. message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
  484. write_byte(22); // TE_BEAMFOLLOW
  485. write_short(greindex); // ball
  486. write_short(beamspr); // laserbeam
  487. write_byte(10); // life
  488. write_byte(10); // width
  489. write_byte(r); // R
  490. write_byte(0); // G
  491. write_byte(b); // B
  492. write_byte(100); // brightness
  493. message_end();
  494.  
  495. // make it glow (so we can tell if it is dead or not)
  496. set_rendering(greindex,kRenderFxGlowShell,r,0,b);
  497.  
  498. // drop
  499. set_task(ROLL_TIME,"stop_roll",greindex);
  500.  
  501. return PLUGIN_CONTINUE;
  502. }
  503.  
  504. // clear grenade's owner so user can touch it
  505. public clearowner(ent) {
  506. if(is_valid_ent(ent)) {
  507. entity_set_edict(ent,EV_ENT_owner,0);
  508. }
  509. }
  510.  
  511. // stop a grenade from rolling too much
  512. public stop_roll(ent) {
  513. if(is_valid_ent(ent)) {
  514.  
  515. // make sure we're on the ground, this stops balls from stopping midair
  516. if(get_entity_flags(ent) & FL_ONGROUND) {
  517. entity_set_vector(ent,EV_VEC_velocity,Float:{0.0,0.0,0.0});
  518. entity_set_float(ent,EV_FL_gravity,1.0);
  519. }
  520. else {
  521. set_task(ROLL_TIME,"stop_roll",ent); // check again shortly
  522. }
  523.  
  524. }
  525. }
  526.  
  527. // player touches a little somethin' somethin'
  528. public player_interact(ent,id) {
  529. if(!get_cvar_num("dodgeball_on") || !is_valid_ent(ent)) {
  530. return PLUGIN_CONTINUE;
  531. }
  532.  
  533. new classname[32], model[32];
  534. entity_get_string(ent,EV_SZ_classname,classname,31);
  535. entity_get_string(ent,EV_SZ_model,model,31);
  536.  
  537. // possible spawnball
  538. if(equali(classname,"armoury_entity")) {
  539.  
  540. if(equali(model,"models/w_dodgeball.mdl")) {
  541. if(user_has_dodgeball(id) <= 0 && canPickup >= 1) {
  542. give_item(id,"weapon_hegrenade");
  543. remove_entity(ent);
  544. }
  545. }
  546.  
  547. return PLUGIN_HANDLED;
  548. }
  549.  
  550. // if it's a weapon and weapons are not allowed on dodgeball
  551. if( (equali(classname,"weaponbox") || equali(classname,"weapon_",7)) && !get_cvar_num("dodgeball_weapons") ) {
  552.  
  553. // allow users to pick up the bomb
  554. if(equali(model,"models/w_backpack.mdl")) {
  555. return PLUGIN_CONTINUE;
  556. }
  557.  
  558. return PLUGIN_HANDLED;
  559. }
  560.  
  561. // if it's a dodgeball
  562. if(equali(classname,"grenade") && !equali(model,"models/w_c4.mdl")) {
  563. hit_by_ball(id,ent);
  564. }
  565.  
  566. return PLUGIN_CONTINUE;
  567. }
  568.  
  569. // ball hits something
  570. public ball_interact(ball,ent) {
  571. if(!get_cvar_num("dodgeball_on")) {
  572. return PLUGIN_CONTINUE;
  573. }
  574.  
  575. // hit world
  576. if(ent == 0) {
  577. entity_set_int(ball,EV_INT_iuser1,1); // dead ball
  578. set_rendering(ball); // get rid of glow
  579. }
  580. else {
  581. new classname[32];
  582. entity_get_string(ent,EV_SZ_classname,classname,31);
  583.  
  584. // if brush-based entity then panic because it will get stuck (crazy error)
  585. if(equali(classname,"func_",5)) {
  586. entity_set_int(ball,EV_INT_iuser1,1); // dead ball
  587. //entity_set_int(ball,EV_INT_iuser2,1); // no more sound
  588. set_rendering(ball); // get rid of glow
  589.  
  590. if(get_cvar_num("dodgeball_antistick")) {
  591. new Float:start[3], Float:end[3], Float:ground[3];
  592. entity_get_vector(ball,EV_VEC_origin,start);
  593. end = start;
  594. end[2] -= 1024.0;
  595. trace_line(ent,start,end,ground);
  596. ground[2] += 7.0;
  597. entity_set_vector(ball,EV_VEC_origin,ground);
  598. }
  599. }
  600. }
  601.  
  602. return PLUGIN_CONTINUE;
  603. }
  604.  
  605. // zomg - USER IS HIT BY A DODGEBALL!
  606. public hit_by_ball(id,ball) {
  607.  
  608. // if the ball is already dead
  609. if(entity_get_int(ball,EV_INT_iuser1) == 1) {
  610. if(user_has_dodgeball(id) <= 0 && canPickup >= 1) {
  611. give_item(id,"weapon_hegrenade");
  612. remove_entity(ball);
  613. }
  614. return;
  615. }
  616.  
  617. // get owner
  618. new owner = entity_get_edict(ball,EV_ENT_euser1);
  619.  
  620. // can't hit self
  621. if(owner == id) {
  622. entity_set_int(ball,EV_INT_iuser1,1); // dead ball
  623. //entity_set_int(ball,EV_INT_iuser2,1); // avoid sound when ball is on owner's head
  624. set_rendering(ball); // get rid of glow
  625. return;
  626. }
  627.  
  628. // if this is an unallowed friendlyfire attack
  629. if(get_user_team(id) == get_user_team(owner) && (get_cvar_num("dodgeball_followff") <= 0 || get_cvar_num("mp_friendlyfire") <= 0)) {
  630. entity_set_int(ball,EV_INT_iuser1,1); // dead ball
  631. set_rendering(ball); // get rid of glow
  632. return;
  633. }
  634.  
  635. // godmode?
  636. if(get_user_godmode(id)) {
  637. entity_set_int(ball,EV_INT_iuser1,1); // dead ball
  638. set_rendering(ball); // get rid of glow
  639. return;
  640. }
  641.  
  642. // get rid of C4 before you go flying
  643. if(user_has_c4(id)) {
  644. client_cmd(id,"drop weapon_c4");
  645. }
  646.  
  647. // don't lose any unnecessary balls
  648. stop_losing_your_balls(id);
  649.  
  650. // fly away!
  651. new Float:origin[3], Float:vec[3];
  652. entity_get_vector(ball,EV_VEC_origin,origin);
  653. get_velocity_from_origin(id,origin,5120.0,vec);
  654. vec[2] = 512.0;
  655. entity_set_vector(id,EV_VEC_velocity,vec);
  656.  
  657. // temporarily stop us from getting hit omre
  658. set_user_godmode(id,1);
  659.  
  660. // give us a second to start flying before we die
  661. // (setting velocity as a corpse doesn't work)
  662. set_task(0.1,"kill",id);
  663.  
  664. // if this was friendlyfire
  665. new ffkill;
  666. if(get_user_team(id) == get_user_team(owner)) {
  667. ffkill = 1;
  668. }
  669.  
  670. new Float:maxs[3], Float:pOrigin[3], headshot;
  671. entity_get_vector(id,EV_VEC_maxs,maxs);
  672. entity_get_vector(id,EV_VEC_origin,pOrigin);
  673. pOrigin[2] += maxs[2]; // approximate head area
  674.  
  675. if(vector_distance(origin,pOrigin) <= HS_DIST) {
  676. headshot = 1;
  677. }
  678.  
  679. //client_print(0,print_chat,"* %f,%f,%f to %f,%f,%f: %f",origin[0],origin[1],origin[2],pOrigin[0],pOrigin[1],pOrigin[2],vector_distance(origin,pOrigin));
  680.  
  681. if(is_user_connected(owner)) {
  682. set_user_frags(owner, (ffkill == 1) ? get_user_frags(owner)-1 : get_user_frags(owner)+1);
  683. message_begin(MSG_BROADCAST,get_user_msgid("ScoreInfo"));
  684. write_byte(owner);
  685. write_short(get_user_frags(owner));
  686. write_short(cs_get_user_deaths(owner));
  687. write_short(0);
  688. write_short(get_user_team(owner));
  689. message_end();
  690. }
  691.  
  692. // display deathmessage
  693. make_deathmsg(owner,id,headshot,"dodgeball");
  694.  
  695. if(get_cvar_num("dodgeball_respawn")) {
  696. new parms[1];
  697. parms[0] = id;
  698. client_print(parms[0],print_center,"Respawn in %i seconds",RESPAWN_DELAY);
  699. set_task(RESPAWN_DELAY,"respawn",TASK_RESPAWN+parms[0],parms,1);
  700. }
  701.  
  702. // if it was a friendlyfire kill
  703. if(ffkill) {
  704. cs_set_user_tked(owner,1,0);
  705. }
  706.  
  707. entity_set_int(ball,EV_INT_iuser1,1); // dead ball
  708. set_rendering(ball); // get rid of glow
  709. }
  710.  
  711. // delayed reaction
  712. public kill(id) {
  713.  
  714. // there's a slight delay
  715.  
  716. strip_user_weapons(id);
  717. set_user_godmode(id,0);
  718. user_silentkill(id);
  719. message_begin(MSG_BROADCAST,get_user_msgid("ScoreInfo"));
  720. write_byte(id);
  721. write_short(get_user_frags(id));
  722. write_short(cs_get_user_deaths(id));
  723. write_short(0);
  724. write_short(1);
  725. message_end();
  726. }
  727.  
  728. // if you had a dodgeball when you died drop it
  729. public stop_losing_your_balls(id) {
  730. if(!get_cvar_num("dodgeball_on")) {
  731. return;
  732. }
  733.  
  734. if(!user_has_dodgeball(id)) {
  735. return;
  736. }
  737.  
  738. // get current weapon information
  739. new clip, ammo, weapon = get_user_weapon(id,clip,ammo);
  740.  
  741. // first-person animation
  742. new seq = entity_get_int(id,EV_INT_weaponanim);
  743.  
  744. // make sure dodgeball is not going to be dropped anyway
  745. // (hegrenade is out and pin is pulled)
  746. if(weapon == CSW_HEGRENADE && seq != 0 && seq != 3) {
  747. return;
  748. }
  749.  
  750. // let's get this party started!
  751. new ball = create_entity("info_target");
  752. entity_set_string(ball,EV_SZ_classname,"grenade");
  753.  
  754. new Float:origin[3];
  755. entity_get_vector(id,EV_VEC_origin,origin);
  756. entity_set_vector(ball,EV_VEC_origin,origin);
  757.  
  758. entity_set_model(ball,"models/w_dodgeball.mdl");
  759.  
  760. entity_set_int(ball,EV_INT_solid,SOLID_TRIGGER);
  761. entity_set_int(ball,EV_INT_movetype,MOVETYPE_TOSS);
  762.  
  763. // do glow trail settings and the such
  764. grenade_throw(id,ball,CSW_HEGRENADE);
  765.  
  766. // override some of the things it sets
  767. entity_set_int(ball,EV_INT_iuser1,1); // dead ball
  768. set_rendering(ball); // get rid of glowshell
  769. }
  770.  
  771. // respawn!
  772. public respawn(parms[]) {
  773. new id = parms[0];
  774. if(is_user_connected(id) && !is_user_alive(id)) {
  775. entity_set_int(id,EV_INT_deadflag,DEAD_RESPAWNABLE);
  776. spawn(id);
  777. entity_set_int(id,EV_INT_iuser1,0);
  778. }
  779. }
  780.  
  781. // if a user has a dodgeball
  782. public user_has_dodgeball(id) {
  783. new clip, ammo;
  784. get_user_ammo(id,CSW_HEGRENADE,clip,ammo);
  785. return ammo;
  786. }
  787.  
  788. // if a user has the c4
  789. public user_has_c4(id) {
  790. new clip, ammo;
  791. get_user_ammo(id,CSW_C4,clip,ammo);
  792. return ammo;
  793. }
  794.  
  795. // model set
  796. public fw_setmodel(ent,model[]) {
  797. if(!get_cvar_num("dodgeball_on")) {
  798. return FMRES_IGNORED;
  799. }
  800.  
  801. // change grenades to dodgeballs
  802. if(equali(model,"models/w_hegrenade.mdl")) {
  803. entity_set_model(ent,"models/w_dodgeball.mdl");
  804. return FMRES_SUPERCEDE;
  805. }
  806.  
  807. return FMRES_IGNORED;
  808. }
  809.  
  810. // sound emission (is that a word? I think so)
  811. public fw_emitsound(ent,channel,sample[],Float:volume,Float:atten,flags,pitch) {
  812. if(!get_cvar_num("dodgeball_on")) {
  813. return FMRES_IGNORED;
  814. }
  815.  
  816. // grenade bounce sound
  817. if(containi(sample,"he_bounce") != -1) {
  818. if(entity_get_float(ent,EV_FL_fuser1) + 0.3 < get_gametime()) {
  819. entity_set_float(ent,EV_FL_fuser1,get_gametime()); // prevent uber sound SPAM
  820. emit_sound(ent,CHAN_ITEM,"weapons/g_bounce1.wav",VOL_NORM,ATTN_NORM,0,PITCH_NORM);
  821. }
  822. return FMRES_SUPERCEDE;
  823. }
  824.  
  825. return FMRES_IGNORED;
  826. }
  827.  
  828. // we don't pay you to think!
  829. public think_grenade(ent) {
  830. if(!get_cvar_num("dodgeball_on")) {
  831. return PLUGIN_CONTINUE;
  832. }
  833.  
  834. new model[32];
  835. entity_get_string(ent,EV_SZ_model,model,31);
  836.  
  837. if(!equali(model,"models/w_dodgeball.mdl")) {
  838. return PLUGIN_CONTINUE;
  839. }
  840.  
  841. // stop grenade from blowing up
  842. return PLUGIN_HANDLED;
  843. }
  844.  
  845. // fire in the hole sound
  846. public msg_sendaudio() {
  847. if(!get_cvar_num("dodgeball_on")) {
  848. return PLUGIN_CONTINUE;
  849. }
  850.  
  851. new string[32];
  852. get_msg_arg_string(2,string,31);
  853.  
  854. // stop grenade throwing radio alerts
  855. if(equali(string,"%!MRAD_FIREINHOLE")) {
  856. return PLUGIN_HANDLED;
  857. }
  858.  
  859. return PLUGIN_CONTINUE;
  860. }
  861.  
  862. // fire in the hole message AND weapon cannot be dropped message
  863. public msg_textmsg() {
  864. if(!get_cvar_num("dodgeball_on")) {
  865. return PLUGIN_CONTINUE;
  866. }
  867.  
  868. new string[32];
  869.  
  870. // "This weapon cannot be dropped"
  871. get_msg_arg_string(2,string,31);
  872. if(equali(string,"#Weapon_Cannot_Be_Dropped")) {
  873. return PLUGIN_HANDLED;
  874. }
  875.  
  876. // some exception thingy
  877. if(str_to_num(string) > 0) {
  878. // if it's a radio message
  879. get_msg_arg_string(3,string,31);
  880. if(equali(string,"#Game_radio")) {
  881. // "Fire in the hole!"
  882. get_msg_arg_string(5,string,31);
  883. if(equali(string,"#Fire_in_the_hole")) {
  884. return PLUGIN_HANDLED;
  885. }
  886. }
  887. }
  888.  
  889. return PLUGIN_CONTINUE;
  890. }
  891.  
  892. // THANKS TO "RYAN" OF THE AMXx FORUMS!
  893. // Gets velocity of an entity (ent) away from origin with speed (fSpeed)
  894. public get_velocity_from_origin(ent,Float:fOrigin[3],Float:fSpeed,Float:fVelocity[3]) {
  895. new Float:fEntOrigin[3];
  896. entity_get_vector(ent,EV_VEC_origin,fEntOrigin);
  897.  
  898. // Velocity = Distance / Time
  899.  
  900. new Float:fDistance[3];
  901. fDistance[0] = fEntOrigin[0] - fOrigin[0];
  902. fDistance[1] = fEntOrigin[1] - fOrigin[1];
  903. fDistance[2] = fEntOrigin[2] - fOrigin[2];
  904.  
  905. new Float:fTime = ( vector_distance( fEntOrigin,fOrigin ) / fSpeed );
  906.  
  907. fVelocity[0] = fDistance[0] / fTime;
  908. fVelocity[1] = fDistance[1] / fTime;
  909. fVelocity[2] = fDistance[2] / fTime;
  910.  
  911. return (fVelocity[0] && fVelocity[1] && fVelocity[2]);
  912. }
  913.