HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. #include <amxmodx>
  2. #include <cstrike>
  3. #include <engine>
  4. #include <fun>
  5. #include <fakemeta>
  6. #include <hamsandwich>
  7. #include <xs>
  8.  
  9. #if AMXX_VERSION_NUM < 183
  10. #include <colorchat>
  11. #endif
  12.  
  13. #define PLUGIN "Deathrun: Core"
  14. #define VERSION "1.1.4"
  15. #define AUTHOR "Mistrick"
  16.  
  17. #pragma semicolon 1
  18.  
  19. #define IsPlayer(%1) (%1 && %1 <= g_iMaxPlayers)
  20.  
  21. #define WARMUP_TIME 15.0
  22. #define HEALER_MAX_HEALTH 150.0
  23.  
  24. enum (+=100)
  25. {
  26. TASK_RESPAWN = 100
  27. };
  28. enum _:Cvars
  29. {
  30. BLOCK_KILL,
  31. BLOCK_FALLDMG,
  32. AUTOTEAMBALANCE,
  33. LIMITTEAMS,
  34. RESTART
  35. };
  36.  
  37. enum Forwards
  38. {
  39. FW_NEW_TERRORIST
  40. };
  41.  
  42. new const PREFIX[] = "^4[DRM]";
  43.  
  44. new g_eCvars[Cvars], g_iForwards[Forwards], g_iReturn, g_bWarmUp = true;
  45. new g_iForwardSpawn, HamHook:g_iHamPreThink, Trie:g_tRemoveEntities;
  46. new g_msgShowMenu, g_msgVGUIMenu, g_msgAmmoPickup, g_msgWeapPickup;
  47. new g_iOldAmmoPickupBlock, g_iOldWeapPickupBlock, g_iTerrorist, g_iNextTerrorist, g_iMaxPlayers;
  48.  
  49. public plugin_init()
  50. {
  51. register_plugin(PLUGIN, VERSION, AUTHOR);
  52.  
  53. register_cvar("deathrun_core_version", VERSION, FCVAR_SERVER | FCVAR_SPONLY);
  54.  
  55. g_eCvars[BLOCK_KILL] = register_cvar("deathrun_block_kill", "1"); //Blookolja az öngyilkosságot 1-BE 0- KI
  56. g_eCvars[BLOCK_FALLDMG] = register_cvar("deathrun_block_falldmg", "1"); //Ha leesel valahonnan nem sebződsz 1-be 0-Ki
  57.  
  58. g_eCvars[AUTOTEAMBALANCE] = get_cvar_pointer("mp_autoteambalance");
  59. g_eCvars[LIMITTEAMS] = get_cvar_pointer("mp_limitteams");
  60. g_eCvars[RESTART] = get_cvar_pointer("sv_restart");
  61.  
  62. register_clcmd("chooseteam", "Command_ChooseTeam");
  63.  
  64. RegisterHam(Ham_Spawn, "player", "Ham_PlayerSpawn_Pre", false);
  65. RegisterHam(Ham_Spawn, "player", "Ham_PlayerSpawn_Post", true);
  66. RegisterHam(Ham_Killed, "player", "Ham_PlayerKilled_Post", true);
  67. RegisterHam(Ham_Use, "func_button", "Ham_UseButton_Pre", false);
  68. RegisterHam(Ham_TakeDamage, "player", "Ham_TakeDamage_Pre", false);
  69. RegisterHam(Ham_TraceAttack, "player", "Ham_TraceAttack_Pre", false);
  70.  
  71. register_forward(FM_ClientKill, "FM_ClientKill_Pre", false);
  72. register_forward(FM_GetGameDescription, "FM_GetGameDescription_Pre", false);
  73.  
  74. register_touch("func_door", "weaponbox", "Engine_TouchFuncDoor");
  75.  
  76. g_iForwards[FW_NEW_TERRORIST] = CreateMultiForward("dr_chosen_new_terrorist", ET_IGNORE, FP_CELL);
  77.  
  78. g_msgVGUIMenu = get_user_msgid("VGUIMenu");
  79. g_msgShowMenu = get_user_msgid("ShowMenu");
  80. g_msgAmmoPickup = get_user_msgid("AmmoPickup");
  81. g_msgWeapPickup = get_user_msgid("WeapPickup");
  82.  
  83. register_message(g_msgVGUIMenu, "Message_Menu");
  84. register_message(g_msgShowMenu, "Message_Menu");
  85.  
  86. DisableHamForward(g_iHamPreThink = RegisterHam(Ham_Player_PreThink, "player", "Ham_PlayerPreThink_Post", true));
  87. unregister_forward(FM_Spawn, g_iForwardSpawn, 0);
  88. TrieDestroy(g_tRemoveEntities);
  89.  
  90. set_task(WARMUP_TIME, "Task_WarmupOff");
  91.  
  92. Block_Commands();
  93. CheckMap();
  94.  
  95. g_iMaxPlayers = get_maxplayers();
  96. }
  97. public Task_WarmupOff()
  98. {
  99. g_bWarmUp = false;
  100. set_pcvar_num(g_eCvars[RESTART], 1);
  101. }
  102. CheckMap()
  103. {
  104. new ent = find_ent_by_class(-1, "info_player_deathmatch");
  105.  
  106. if(is_valid_ent(ent))
  107. {
  108. register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0");
  109. register_logevent("Event_RoundStart", 2, "1=Round_Start");
  110. }
  111.  
  112. ent = -1;
  113. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door")))
  114. {
  115. new spawnflags = pev(ent, pev_spawnflags);
  116. if ((spawnflags & SF_DOOR_USE_ONLY) && UTIL_IsTargetActivate(ent))
  117. {
  118. set_pev(ent, pev_spawnflags, spawnflags & ~SF_DOOR_USE_ONLY);
  119. }
  120. }
  121. }
  122. public plugin_precache()
  123. {
  124. new const szRemoveEntities[][] =
  125. {
  126. "func_bomb_target", "func_escapezone", "func_hostage_rescue", "func_vip_safetyzone", "info_vip_start",
  127. "hostage_entity", "info_bomb_target", "func_buyzone","info_hostage_rescue", "monster_scientist"
  128. };
  129. g_tRemoveEntities = TrieCreate();
  130. for(new i = 0; i < sizeof(szRemoveEntities); i++)
  131. {
  132. TrieSetCell(g_tRemoveEntities, szRemoveEntities[i], i);
  133. }
  134. g_iForwardSpawn = register_forward(FM_Spawn, "FakeMeta_Spawn_Pre", 0);
  135. engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "func_buyzone"));
  136. }
  137. public FakeMeta_Spawn_Pre(ent)
  138. {
  139. if(!pev_valid(ent)) return FMRES_IGNORED;
  140.  
  141. static szClassName[32]; pev(ent, pev_classname, szClassName, charsmax(szClassName));
  142.  
  143. if(TrieKeyExists(g_tRemoveEntities, szClassName))
  144. {
  145. engfunc(EngFunc_RemoveEntity, ent);
  146. return FMRES_SUPERCEDE;
  147. }
  148. return FMRES_IGNORED;
  149. }
  150. public plugin_cfg()
  151. {
  152. register_dictionary("deathrun_core.txt");
  153. }
  154. public plugin_natives()
  155. {
  156. register_library("deathrun_core");
  157. register_native("dr_get_terrorist", "native_get_terrorist", 1);
  158. register_native("dr_set_next_terrorist", "native_set_next_terrorist", 1);
  159. register_native("dr_get_next_terrorist", "native_get_next_terrorist", 1);
  160. }
  161. public native_get_terrorist()
  162. {
  163. return g_iTerrorist;
  164. }
  165. public native_set_next_terrorist(id)
  166. {
  167. g_iNextTerrorist = id;
  168. }
  169. public native_get_next_terrorist()
  170. {
  171. return g_iNextTerrorist;
  172. }
  173. public client_putinserver(id)
  174. {
  175. if(!g_bWarmUp && _get_alive_players())
  176. {
  177. block_user_spawn(id);
  178. }
  179. }
  180. public client_disconnect(id)
  181. {
  182. if(id == g_iTerrorist)
  183. {
  184. new iPlayers[32], iNum; iNum = _get_players(iPlayers, true);
  185.  
  186. if(iNum >= 2)
  187. {
  188. new Float:fOrigin[3]; pev(id, pev_origin, fOrigin);
  189. g_iTerrorist = iPlayers[random(iNum)];
  190. cs_set_user_team(g_iTerrorist, CS_TEAM_T);
  191. ExecuteHamB(Ham_CS_RoundRespawn, g_iTerrorist);
  192. engfunc(EngFunc_SetOrigin, g_iTerrorist, fOrigin);
  193.  
  194. ExecuteForward(g_iForwards[FW_NEW_TERRORIST], g_iReturn, g_iTerrorist);
  195.  
  196. new szName[32]; get_user_name(g_iTerrorist, szName, charsmax(szName));
  197. new szNameLeaver[32]; get_user_name(id, szNameLeaver, charsmax(szNameLeaver));
  198. client_print_color(0, print_team_red, "%s %L", PREFIX, LANG_PLAYER, "DRC_TERRORIST_LEFT", szNameLeaver, szName);
  199. }
  200. else
  201. {
  202. set_pcvar_num(g_eCvars[RESTART], 5);
  203. }
  204. }
  205. }
  206. //******** Commands ********//
  207. public Command_ChooseTeam(id)
  208. {
  209. //Add custom menu
  210. return PLUGIN_HANDLED;
  211. }
  212. //***** Block Commands *****//
  213. Block_Commands()
  214. {
  215. new szBlockedCommands[][] = {"jointeam", "joinclass", "radio1", "radio2", "radio3"};
  216. for(new i = 0; i < sizeof(szBlockedCommands); i++)
  217. {
  218. register_clcmd(szBlockedCommands[i], "Command_BlockCmds");
  219. }
  220. }
  221. public Command_BlockCmds(id)
  222. {
  223. return PLUGIN_HANDLED;
  224. }
  225. //******** Events ********//
  226. public Event_NewRound()
  227. {
  228. set_pcvar_num(g_eCvars[AUTOTEAMBALANCE], 0);
  229. set_pcvar_num(g_eCvars[LIMITTEAMS], 0);
  230. TeamBalance();
  231. }
  232. TeamBalance()
  233. {
  234. if(g_bWarmUp) return;
  235.  
  236. new iPlayers[32], iNum, iPlayer; iNum = _get_players(iPlayers, false);
  237.  
  238. if(iNum < 1 || iNum == 1 && !is_user_connected(g_iTerrorist)) return;
  239.  
  240. if(is_user_connected(g_iTerrorist)) cs_set_user_team(g_iTerrorist, CS_TEAM_CT);
  241.  
  242. if(!is_user_connected(g_iNextTerrorist))
  243. {
  244. g_iTerrorist = iPlayers[random(iNum)];
  245. }
  246. else
  247. {
  248. g_iTerrorist = g_iNextTerrorist;
  249. g_iNextTerrorist = 0;
  250. }
  251.  
  252. cs_set_user_team(g_iTerrorist, CS_TEAM_T);
  253. for(new i = 0; i < iNum; i++)
  254. {
  255. iPlayer = iPlayers[i];
  256. if(iPlayer != g_iTerrorist) cs_set_user_team(iPlayer, CS_TEAM_CT);
  257. }
  258. new szName[32]; get_user_name(g_iTerrorist, szName, charsmax(szName));
  259. client_print_color(0, print_team_red, "%s %L", PREFIX, LANG_PLAYER, "DRC_BECAME_TERRORIST", szName);
  260. }
  261. public Event_RoundStart()
  262. {
  263. TerroristCheck();
  264. }
  265. TerroristCheck()
  266. {
  267. if(!is_user_connected(g_iTerrorist))
  268. {
  269. new players[32], pnum; get_players(players, pnum, "ae", "TERRORIST");
  270. g_iTerrorist = pnum ? players[0] : 0;
  271. }
  272. ExecuteForward(g_iForwards[FW_NEW_TERRORIST], g_iReturn, g_iTerrorist);
  273. }
  274. //******** Messages Credits: PRoSToTeM@ ********//
  275. public Message_Menu(const msg, const dest, const id)
  276. {
  277. const MENU_TEAM = 2;
  278. const SHOWTEAMSELECT = 3;
  279. const Menu_ChooseTeam = 1;
  280. const m_iMenu = 205;
  281. const m_iJoiningState = 121;
  282.  
  283. if (msg == g_msgShowMenu)
  284. {
  285. new szMsg[13]; get_msg_arg_string(4, szMsg, charsmax(szMsg));
  286. if (!equal(szMsg, "#Team_Select"))
  287. {
  288. return PLUGIN_CONTINUE;
  289. }
  290. }
  291. else if (get_msg_arg_int(1) != MENU_TEAM || get_msg_arg_int(2) & MENU_KEY_0)
  292. {
  293. return PLUGIN_CONTINUE;
  294. }
  295.  
  296. if (get_pdata_int(id, m_iMenu) == Menu_ChooseTeam || get_pdata_int(id, m_iJoiningState) != SHOWTEAMSELECT)
  297. {
  298. return PLUGIN_CONTINUE;
  299. }
  300.  
  301. EnableHamForward(g_iHamPreThink);
  302.  
  303. return PLUGIN_HANDLED;
  304. }
  305. //*******
  306. public Ham_PlayerSpawn_Pre(id)
  307. {
  308. g_iOldAmmoPickupBlock = get_msg_block(g_msgAmmoPickup);
  309. g_iOldWeapPickupBlock = get_msg_block(g_msgWeapPickup);
  310. set_msg_block(g_msgAmmoPickup, BLOCK_SET);
  311. set_msg_block(g_msgWeapPickup, BLOCK_SET);
  312. }
  313. public Ham_PlayerSpawn_Post(id)
  314. {
  315. set_msg_block(g_msgAmmoPickup, g_iOldAmmoPickupBlock);
  316. set_msg_block(g_msgWeapPickup, g_iOldWeapPickupBlock);
  317.  
  318. if(!is_user_alive(id)) return HAM_IGNORED;
  319.  
  320. block_user_radio(id);
  321.  
  322. strip_user_weapons(id);//bug with m_bHasPrimary
  323. give_item(id, "weapon_knife");
  324.  
  325. return HAM_IGNORED;
  326. }
  327. public Ham_PlayerKilled_Post(id)
  328. {
  329. if(g_bWarmUp && cs_get_user_team(id) == CS_TEAM_CT && _get_alive_players())
  330. {
  331. set_task(0.1, "Task_Respawn", id + TASK_RESPAWN);
  332. }
  333. }
  334. public Task_Respawn(id)
  335. {
  336. id -= TASK_RESPAWN;
  337. if(is_user_connected(id))
  338. {
  339. ExecuteHamB(Ham_CS_RoundRespawn, id);
  340. }
  341. }
  342. public Ham_UseButton_Pre(ent, caller, activator, use_type)
  343. {
  344. if(!IsPlayer(activator) || !is_user_alive(activator) || cs_get_user_team(activator) == CS_TEAM_T) return HAM_IGNORED;
  345.  
  346. new Float:fEntOrigin[3], Float:fPlayerOrigin[3];
  347. fEntOrigin = get_ent_brash_origin(ent);
  348. fPlayerOrigin = get_player_eyes_origin(activator);
  349.  
  350. new bool:bCanUse = allow_press_button(ent, fPlayerOrigin, fEntOrigin);
  351.  
  352. return bCanUse ? HAM_IGNORED : HAM_SUPERCEDE;
  353. }
  354. Float:get_ent_brash_origin(ent)
  355. {
  356. new Float:origin[3], Float:mins[3], Float:maxs[3];
  357. pev(ent, pev_absmin, mins);
  358. pev(ent, pev_absmax, maxs);
  359. xs_vec_add(mins, maxs, origin);
  360. xs_vec_mul_scalar(origin, 0.5, origin);
  361. return origin;
  362. }
  363. Float:get_player_eyes_origin(id)
  364. {
  365. new Float:origin[3], eyes_origin[3];
  366. get_user_origin(id, eyes_origin, 1);
  367. IVecFVec(eyes_origin, origin);
  368. return origin;
  369. }
  370. public Ham_TakeDamage_Pre(victim, inflictor, attacker, Float:damage, damage_bits)
  371. {
  372. if(damage < 0.0)
  373. {
  374. new Float:health; pev(victim, pev_health, health);
  375. if(health - damage > HEALER_MAX_HEALTH)
  376. return HAM_SUPERCEDE;
  377. }
  378. if(damage_bits & DMG_FALL && get_pcvar_num(g_eCvars[BLOCK_FALLDMG]) && cs_get_user_team(victim) == CS_TEAM_T)
  379. {
  380. return HAM_SUPERCEDE;
  381. }
  382. return HAM_IGNORED;
  383. }
  384. public Ham_TraceAttack_Pre(victim, idattacker, Float:damage, Float:direction[3], trace_result, damagebits)
  385. {
  386. if(damage < 0.0)
  387. {
  388. new Float:health; pev(victim, pev_health, health);
  389. if(health - damage > HEALER_MAX_HEALTH)
  390. return HAM_SUPERCEDE;
  391. }
  392. return HAM_IGNORED;
  393. }
  394. public Ham_PlayerPreThink_Post(id)
  395. {
  396. DisableHamForward(g_iHamPreThink);
  397.  
  398. new iOldShowMenuBlock = get_msg_block(g_msgShowMenu);
  399. new iOldVGUIMenuBlock = get_msg_block(g_msgVGUIMenu);
  400. set_msg_block(g_msgShowMenu, BLOCK_SET);
  401. set_msg_block(g_msgVGUIMenu, BLOCK_SET);
  402. engclient_cmd(id, "jointeam", "2");
  403. engclient_cmd(id, "joinclass", "5");
  404. set_msg_block(g_msgVGUIMenu, iOldVGUIMenuBlock);
  405. set_msg_block(g_msgShowMenu, iOldShowMenuBlock);
  406. }
  407. //*******
  408. public FM_ClientKill_Pre(id)
  409. {
  410. return (get_pcvar_num(g_eCvars[BLOCK_KILL]) || is_user_alive(id) && cs_get_user_team(id) == CS_TEAM_T) ? FMRES_SUPERCEDE : FMRES_IGNORED;
  411. }
  412. public FM_GetGameDescription_Pre()
  413. {
  414. static szGameName[32]; if(!szGameName[0]) formatex(szGameName, charsmax(szGameName), "Deathrun v%s", VERSION);
  415. forward_return(FMV_STRING, szGameName);
  416. return FMRES_SUPERCEDE;
  417. }
  418. public Engine_TouchFuncDoor(ent, toucher)
  419. {
  420. if(is_valid_ent(toucher))
  421. {
  422. remove_entity(toucher);
  423. }
  424. }
  425. //****************************************//
  426. stock _get_players(players[32], bool:alive = false)
  427. {
  428. new CsTeams:team, count;
  429. for(new i = 1; i <= g_iMaxPlayers; i++)
  430. {
  431. if(i == g_iTerrorist || !is_user_connected(i) || alive && !is_user_alive(i)) continue;
  432. team = cs_get_user_team(i);
  433. if(team == CS_TEAM_UNASSIGNED || team == CS_TEAM_SPECTATOR) continue;
  434. players[count++] = i;
  435. }
  436. return count;
  437. }
  438. stock _get_alive_players()
  439. {
  440. new players[32], pnum; get_players(players, pnum, "a");
  441. return pnum;
  442. }
  443. stock block_user_radio(id)
  444. {
  445. const m_iRadiosLeft = 192;
  446. set_pdata_int(id, m_iRadiosLeft, 0);
  447. }
  448. stock block_user_spawn(id)
  449. {
  450. const m_iSpawnCount = 365;
  451. set_pdata_int(id, m_iSpawnCount, 1);
  452. }
  453. stock bool:allow_press_button(ent, Float:start[3], Float:end[3], bool:ignore_players = true)
  454. {
  455. new trace = 0; engfunc(EngFunc_TraceLine, start, end, (ignore_players ? IGNORE_MONSTERS : DONT_IGNORE_MONSTERS), ent, trace);
  456. new Float:fraction; get_tr2(trace, TR_flFraction, fraction);
  457.  
  458. if(fraction == 1.0) return true;
  459.  
  460. new hit_ent = get_tr2(trace, TR_pHit);
  461.  
  462. if(!pev_valid(hit_ent)) return false;
  463.  
  464. new Float:fAbsMin[3]; pev(hit_ent, pev_absmin, fAbsMin);
  465. new Float:fAbsMax[3]; pev(hit_ent, pev_absmax, fAbsMax);
  466. new Float:fVolume[3]; xs_vec_sub(fAbsMax, fAbsMin, fVolume);
  467.  
  468. if(fVolume[0] < 48.0 && fVolume[1] < 48.0 && fVolume[2] < 48.0) return true;
  469.  
  470. return false;
  471. }
  472. stock bool:UTIL_IsTargetActivate(const ent)
  473. {
  474. new target_name[32]; pev(ent, pev_targetname, target_name, charsmax(target_name));
  475. return (target_name[0]) ? false : true;
  476. }
  477.