Advertisement
Guest User

Untitled

a guest
Nov 16th, 2012
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 86.69 KB | None | 0 0
  1. #pragma semicolon 1
  2.  
  3. #include <sourcemod>
  4. #include <sdktools>
  5. #include <cstrike>
  6. #include <sdkhooks>
  7.  
  8. #define PLUGIN_VERSION "1.4.1"
  9.  
  10. // that's what GetLanguageCount() got me
  11. #define MAX_LANGUAGES 27
  12.  
  13. #define PREFIX "\x04Hide and Seek \x01> \x03"
  14.  
  15. // plugin cvars
  16. new Handle:g_hCVEnable = INVALID_HANDLE;
  17. new Handle:g_hCVFreezeCTs = INVALID_HANDLE;
  18. new Handle:g_hCVFreezeTime = INVALID_HANDLE;
  19. new Handle:g_hCVChangeLimit = INVALID_HANDLE;
  20. new Handle:g_hCVChangeLimittime = INVALID_HANDLE;
  21. new Handle:g_hCVAutoChoose = INVALID_HANDLE;
  22. new Handle:g_hCVWhistle = INVALID_HANDLE;
  23. new Handle:g_hCVWhistleTimes = INVALID_HANDLE;
  24. new Handle:g_hCVWhistleDelay = INVALID_HANDLE;
  25. new Handle:g_hCVAntiCheat = INVALID_HANDLE;
  26. new Handle:g_hCVCheatPunishment = INVALID_HANDLE;
  27. new Handle:g_hCVHiderWinFrags = INVALID_HANDLE;
  28. new Handle:g_hCVSlaySeekers = INVALID_HANDLE;
  29. new Handle:g_hCVHPSeekerEnable = INVALID_HANDLE;
  30. new Handle:g_hCVHPSeekerDec = INVALID_HANDLE;
  31. new Handle:g_hCVHPSeekerInc = INVALID_HANDLE;
  32. new Handle:g_hCVHPSeekerBonus = INVALID_HANDLE;
  33. new Handle:g_hCVOpacityEnable = INVALID_HANDLE;
  34. new Handle:g_hCVHiderSpeed = INVALID_HANDLE;
  35. new Handle:g_hCVDisableRightKnife = INVALID_HANDLE;
  36. new Handle:g_hCVDisableDucking = INVALID_HANDLE;
  37. new Handle:g_hCVAutoThirdPerson = INVALID_HANDLE;
  38. new Handle:g_hCVHiderFreezeMode = INVALID_HANDLE;
  39. new Handle:g_hCVHideBlood = INVALID_HANDLE;
  40. new Handle:g_hCVShowHideHelp = INVALID_HANDLE;
  41. new Handle:g_hCVShowProgressBar = INVALID_HANDLE;
  42. new Handle:g_hCVCTRatio = INVALID_HANDLE;
  43. new Handle:g_hCVDisableUse = INVALID_HANDLE;
  44. new Handle:g_hCVHiderFreezeInAir = INVALID_HANDLE;
  45. new Handle:g_hCVRemoveShadows = INVALID_HANDLE;
  46. new Handle:g_hCVUseTaxedInRandom = INVALID_HANDLE;
  47.  
  48. // primary enableswitch
  49. new bool:g_bEnableHnS = true;
  50.  
  51. // config and menu handles
  52. new Handle:g_hModelMenu[MAX_LANGUAGES] = {INVALID_HANDLE, ...};
  53. new String:g_sModelMenuLanguage[MAX_LANGUAGES][4];
  54. new Handle:kv;
  55.  
  56. // offsets
  57. new g_Render;
  58. new g_flFlashDuration;
  59. new g_flFlashMaxAlpha;
  60. new g_Freeze;
  61. new g_iHasNightVision;
  62. new g_flLaggedMovementValue;
  63. new g_flProgressBarStartTime;
  64. new g_iProgressBarDuration;
  65. new g_iAccount;
  66.  
  67. new bool:g_bInThirdPersonView[MAXPLAYERS+1] = {false,...};
  68. new bool:g_bIsFreezed[MAXPLAYERS+1] = {false,...};
  69. new Handle:g_hRoundTimeTimer = INVALID_HANDLE;
  70. new Handle:g_iRoundTime = INVALID_HANDLE;
  71. new g_iRoundStartTime = 0;
  72.  
  73. new g_iFirstCTSpawn = 0;
  74. new g_iFirstTSpawn = 0;
  75. new Handle:g_hShowCountdownTimer = INVALID_HANDLE;
  76. new Handle:g_hSpamCommandsTimer = INVALID_HANDLE;
  77. new bool:g_bRoundEnded = false;
  78. new bool:g_bFirstSpawn[MAXPLAYERS+1] = {true,...};
  79.  
  80. // Cheat cVar part
  81. new Handle:g_hCheckVarTimer[MAXPLAYERS+1] = {INVALID_HANDLE,...};
  82. new String:cheat_commands[][] = {"cl_radaralpha", "r_shadows"};
  83. new bool:g_bConVarViolation[MAXPLAYERS+1][2]; // 2 = amount of cheat_commands. update if you add one.
  84. new g_iConVarMessage[MAXPLAYERS+1][2]; // 2 = amount of cheat_commands. update if you add one.
  85. new Handle:g_hCheatPunishTimer[MAXPLAYERS+1] = {INVALID_HANDLE};
  86.  
  87. // Terrorist Modelchange stuff
  88. new g_iTotalModelsAvailable = 0;
  89. new g_iModelChangeCount[MAXPLAYERS+1] = {0,...};
  90. new bool:g_bAllowModelChange[MAXPLAYERS+1] = {true,...};
  91. new Handle:g_hAllowModelChangeTimer[MAXPLAYERS+1] = {INVALID_HANDLE,...};
  92. // Model ground fix
  93. new Float:g_iFixedModelHeight[MAXPLAYERS+1] = {0.0,...};
  94. new bool:g_bClientIsHigher[MAXPLAYERS+1] = {false,...};
  95. new g_iLowModelSteps[MAXPLAYERS+1] = {0,...};
  96.  
  97. new bool:g_bIsCTWaiting[MAXPLAYERS+1] = {false,...};
  98. new Handle:g_hFreezeCTTimer[MAXPLAYERS+1] = {INVALID_HANDLE,...};
  99. new Handle:g_hUnfreezeCTTimer[MAXPLAYERS+1] = {INVALID_HANDLE,...};
  100.  
  101. // protected server cvars
  102. new String:protected_cvars[][] = {"mp_flashlight",
  103. "sv_footsteps",
  104. "mp_limitteams",
  105. "mp_autoteambalance",
  106. "mp_freezetime",
  107. "sv_nonemesis",
  108. "sv_nomvp",
  109. "sv_nostats",
  110. "mp_playerid",
  111. "sv_allowminmodels",
  112. "sv_turbophysics",
  113. "mp_teams_unbalance_limit"
  114. };
  115. new forced_values[] = {0, // mp_flashlight
  116. 0, // sv_footsteps
  117. 0, // mp_limitteams
  118. 0, // mp_autoteambalance
  119. 0, // mp_freezetime
  120. 1, // sv_nonemesis
  121. 1, // sv_nomvp
  122. 1, // sv_nostats
  123. 1, // mp_playerid
  124. 0, // sv_allowminmodels
  125. 1, // sv_turbophysics
  126. 0 // mp_teams_unbalance_limit
  127. };
  128. new previous_values[12] = {0,...}; // save previous values when forcing above, so we can restore the config if hns is disabled midgame. !same as comment next line!
  129. new Handle:g_hProtectedConvar[12] = {INVALID_HANDLE,...}; // 12 = amount of protected_cvars. update if you add one.
  130. new Handle:g_hForceCamera = INVALID_HANDLE;
  131.  
  132. // whistle sounds
  133. new g_iWhistleCount[MAXPLAYERS+1] = {0,...};
  134. new Handle:g_hWhistleDelay = INVALID_HANDLE;
  135. new bool:g_bWhistlingAllowed = true;
  136. new String:whistle_sounds[][] = {"ambient/animal/cow.wav", "ambient/animal/horse_4.wav", "ambient/animal/horse_5.wav", "ambient/machines/train_horn_3.wav", "ambient/misc/creak3.wav", "doors/door_metal_gate_close1.wav", "ambient/misc/flush1.wav"};
  137.  
  138. // Teambalance
  139. new g_iLastJoinedCT = -1;
  140. new bool:g_bCTToSwitch[MAXPLAYERS+1] = {false,...};
  141.  
  142. public Plugin:myinfo =
  143. {
  144. name = "Hide and Seek",
  145. author = "Jannik 'Peace-Maker' Hartung and Vladislav Dolgov",
  146. description = "Terrorists set a model and hide, CT seek terrorists.",
  147. version = PLUGIN_VERSION,
  148. url = "http://www.wcfan.de/ | http://www.elistor.ru/"
  149. };
  150.  
  151. public OnPluginStart()
  152. {
  153. new Handle:hVersion = CreateConVar("sm_hns_version", PLUGIN_VERSION, "Hide and seek", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
  154. if(hVersion != INVALID_HANDLE)
  155. SetConVarString(hVersion, PLUGIN_VERSION);
  156.  
  157. // Config cvars
  158. g_hCVEnable = CreateConVar("sm_hns_enable", "1", "Enable the Hide and Seek Mod?", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  159. g_hCVFreezeCTs = CreateConVar("sm_hns_freezects", "1", "Should CTs get freezed and blinded on spawn?", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  160. g_hCVFreezeTime = CreateConVar("sm_hns_freezetime", "25.0", "How long should the CTs are freezed after spawn?", FCVAR_PLUGIN, true, 1.00, true, 120.00);
  161. g_hCVChangeLimit = CreateConVar("sm_hns_changelimit", "2", "How often a T is allowed to choose his model ingame? 0 = unlimited", FCVAR_PLUGIN, true, 0.00);
  162. g_hCVChangeLimittime = CreateConVar("sm_hns_changelimittime", "30.0", "How long should a T be allowed to change his model again after spawn?", FCVAR_PLUGIN, true, 0.00);
  163. g_hCVAutoChoose = CreateConVar("sm_hns_autochoose", "0", "Should the plugin choose models for the hiders automatically?", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  164. g_hCVWhistle = CreateConVar("sm_hns_whistle", "1", "Are terrorists allowed to whistle?", FCVAR_PLUGIN);
  165. g_hCVWhistleTimes = CreateConVar("sm_hns_whistle_times", "5", "How many times a hider is allowed to whistle per round?", FCVAR_PLUGIN);
  166. g_hCVWhistleDelay = CreateConVar("sm_hns_whistle_delay", "25.0", "How long after spawn should we delay the use of whistle? (Default: 25.0)", FCVAR_PLUGIN, true, 0.00, true, 120.00);
  167. g_hCVAntiCheat = CreateConVar("sm_hns_anticheat", "0", "Check player cheat convars, 0 = off/1 = on.", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  168. g_hCVCheatPunishment = CreateConVar("sm_hns_cheat_punishment", "1", "How to punish players with wrong cvar values after 15 seconds? 0: Disabled. 1: Switch to Spectator. 2: Kick", FCVAR_PLUGIN, true, 0.00, true, 2.00);
  169. g_hCVHiderWinFrags = CreateConVar("sm_hns_hider_win_frags", "5", "How many frags should surviving terrorists gain?", FCVAR_PLUGIN, true, 0.00, true, 10.00);
  170. g_hCVSlaySeekers = CreateConVar("sm_hns_slay_seekers", "0", "Should we slay all seekers on round end and there are still some hiders alive? (Default: 0)", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  171. g_hCVHPSeekerEnable = CreateConVar("sm_hns_hp_seeker_enable", "1", "Should CT lose HP when shooting, 0 = off/1 = on.", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  172. g_hCVHPSeekerDec = CreateConVar("sm_hns_hp_seeker_dec", "5", "How many hp should a CT lose on shooting?", FCVAR_PLUGIN, true, 0.00);
  173. g_hCVHPSeekerInc = CreateConVar("sm_hns_hp_seeker_inc", "15", "How many hp should a CT gain when hitting a hider?", FCVAR_PLUGIN, true, 0.00);
  174. g_hCVHPSeekerBonus = CreateConVar("sm_hns_hp_seeker_bonus", "50", "How many hp should a CT gain when killing a hider?", FCVAR_PLUGIN, true, 0.00);
  175. g_hCVOpacityEnable = CreateConVar("sm_hns_opacity_enable", "0", "Should T get more invisible on low hp, 0 = off/1 = on.", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  176. g_hCVHiderSpeed = CreateConVar("sm_hns_hidersspeed", "1.00", "Hiders speed (Default: 1.00).", FCVAR_PLUGIN, true, 1.00, true, 3.00);
  177. g_hCVDisableRightKnife =CreateConVar("sm_hns_disable_rightknife", "1", "Disable rightclick for CTs with knife? Prevents knifing without losing heatlh. (Default: 1).", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  178. g_hCVDisableDucking = CreateConVar("sm_hns_disable_ducking", "1", "Disable ducking. (Default: 1).", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  179. g_hCVAutoThirdPerson = CreateConVar("sm_hns_auto_thirdperson", "1", "Enable thirdperson view for hiders automatically. (Default: 1)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  180. g_hCVHiderFreezeMode = CreateConVar("sm_hns_hider_freeze_mode", "2", "0: Disables /freeze command for hiders, 1: Only freeze on position, be able to move camera, 2: Freeze completely (no cameramovements) (Default: 2)", FCVAR_PLUGIN, true, 0.00, true, 2.00);
  181. g_hCVHideBlood = CreateConVar("sm_hns_hide_blood", "1", "Hide blood on hider damage. (Default: 1)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  182. g_hCVShowHideHelp = CreateConVar("sm_hns_show_hidehelp", "1", "Show helpmenu explaining the game on first player spawn. (Default: 1)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  183. g_hCVShowProgressBar = CreateConVar("sm_hns_show_progressbar", "1", "Show progressbar for last 15 seconds of freezetime. (Default: 1)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  184. g_hCVCTRatio = CreateConVar("sm_hns_ct_ratio", "3", "The ratio of hiders to 1 seeker. 0 to disables teambalance. (Default: 3)", FCVAR_PLUGIN, true, 1.00, true, 64.00);
  185. g_hCVDisableUse = CreateConVar("sm_hns_disable_use", "1", "Disable CTs pushing things. (Default: 1)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  186. g_hCVHiderFreezeInAir = CreateConVar("sm_hns_hider_freeze_inair", "0", "Are hiders allowed to freeze in the air? (Default: 0)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  187. g_hCVRemoveShadows = CreateConVar("sm_hns_remove_shadows", "1", "Remove shadows from players and physic models? (Default: 1)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  188. g_hCVUseTaxedInRandom = CreateConVar("sm_hns_use_taxed_in_random", "0", "Include taxed models when using random model choice? (Default: 0)", FCVAR_PLUGIN, true, 0.00, true, 1.00);
  189.  
  190. g_bEnableHnS = GetConVarBool(g_hCVEnable);
  191. HookConVarChange(g_hCVEnable, Cfg_OnChangeEnable);
  192. HookConVarChange(FindConVar("mp_restartgame"), RestartGame);
  193.  
  194. if(g_bEnableHnS)
  195. {
  196. // !ToDo: Exclude hooks and other EnableHnS dependand functions into one seperate function.
  197. // Now you need to add the hooks to the Cfg_OnChangeEnable callback too..
  198. HookConVarChange(g_hCVHiderSpeed, OnChangeHiderSpeed);
  199. HookConVarChange(g_hCVAntiCheat, OnChangeAntiCheat);
  200.  
  201. // Hooking events
  202. HookEvent("player_spawn", Event_OnPlayerSpawn);
  203. HookEvent("weapon_fire", Event_OnWeaponFire);
  204. HookEvent("player_death", Event_OnPlayerDeath);
  205. HookEvent("player_blind", Event_OnPlayerBlind);
  206. HookEvent("round_start", Event_OnRoundStart);
  207. HookEvent("round_end", Event_OnRoundEnd);
  208. HookEvent("player_team", Event_OnPlayerTeam);
  209. HookEvent("item_pickup", Event_OnItemPickup);
  210. }
  211.  
  212. // Register console commands
  213. RegConsoleCmd("hide", Menu_SelectModel, "Opens a menu with different models to choose as hider.");
  214. RegConsoleCmd("hidemenu", Menu_SelectModel, "Opens a menu with different models to choose as hider.");
  215. RegConsoleCmd("tp", Toggle_ThirdPerson, "Toggles the view to thirdperson for hiders.");
  216. RegConsoleCmd("thirdperson", Toggle_ThirdPerson, "Toggles the view to thirdperson for hiders.");
  217. RegConsoleCmd("third", Toggle_ThirdPerson, "Toggles the view to thirdperson for hiders.");
  218. RegConsoleCmd("+3rd", Enable_ThirdPerson, "Set the view to thirdperson for hiders.");
  219. RegConsoleCmd("-3rd", Disable_ThirdPerson, "Set the view to firstperson for hiders.");
  220. RegConsoleCmd("jointeam", Command_JoinTeam);
  221. RegConsoleCmd("whistle", Play_Whistle, "Plays a random sound from the hiders position to give the seekers a hint.");
  222. RegConsoleCmd("whoami", Display_ModelName, "Displays the current models description in chat.");
  223. RegConsoleCmd("hidehelp", Display_Help, "Displays a panel with informations how to play.");
  224. RegConsoleCmd("freeze", Freeze_Cmd, "Toggles freezing for hiders.");
  225.  
  226.  
  227. RegConsoleCmd("overview_mode", Block_Cmd);
  228.  
  229. RegAdminCmd("sm_hns_force_whistle", ForceWhistle, ADMFLAG_CHAT, "Force a player to whistle");
  230. RegAdminCmd("sm_hns_reload_models", ReloadModels, ADMFLAG_RCON, "Reload the modellist from the map config file.");
  231.  
  232. // Loading translations
  233. LoadTranslations("plugin.hide_and_seek");
  234. LoadTranslations("common.phrases"); // for FindTarget()
  235.  
  236. // set the default values for cvar checking
  237. for(new x=1;x<=MaxClients;x++)
  238. {
  239. for(new y=0;y<sizeof(cheat_commands);y++)
  240. {
  241. g_bConVarViolation[x][y] = false;
  242. g_iConVarMessage[x][y] = 0;
  243. }
  244. if(IsClientInGame(x))
  245. OnClientPutInServer(x);
  246. }
  247.  
  248. if(g_bEnableHnS)
  249. {
  250. // start advertising spam
  251. g_hSpamCommandsTimer = CreateTimer(120.0, SpamCommands, 0);
  252. }
  253.  
  254. // hook cvars
  255. g_hForceCamera = FindConVar("mp_forcecamera");
  256. g_iRoundTime = FindConVar("mp_roundtime");
  257.  
  258. // get the offsets
  259. // for transparency
  260. g_Render = FindSendPropOffs("CAI_BaseNPC", "m_clrRender");
  261. if(g_Render == -1)
  262. SetFailState("Couldnt find the m_clrRender offset!");
  263.  
  264. // for hiding players on radar
  265. g_flFlashDuration = FindSendPropOffs("CCSPlayer", "m_flFlashDuration");
  266. if(g_flFlashDuration == -1)
  267. SetFailState("Couldnt find the m_flFlashDuration offset!");
  268. g_flFlashMaxAlpha = FindSendPropOffs("CCSPlayer", "m_flFlashMaxAlpha");
  269. if(g_flFlashMaxAlpha == -1)
  270. SetFailState("Couldnt find the m_flFlashMaxAlpha offset!");
  271. g_Freeze = FindSendPropOffs("CBasePlayer", "m_fFlags");
  272. if(g_Freeze == -1)
  273. SetFailState("Couldnt find the m_fFlags offset!");
  274. g_iHasNightVision = FindSendPropOffs("CCSPlayer", "m_bHasNightVision");
  275. if(g_iHasNightVision == -1)
  276. SetFailState("Couldnt find the m_bHasNightVision offset!");
  277. g_flLaggedMovementValue = FindSendPropOffs("CCSPlayer", "m_flLaggedMovementValue");
  278. if(g_flLaggedMovementValue == -1)
  279. SetFailState("Couldnt find the m_flLaggedMovementValue offset!");
  280. g_flProgressBarStartTime = FindSendPropOffs("CCSPlayer", "m_flProgressBarStartTime");
  281. if(g_flProgressBarStartTime == -1)
  282. SetFailState("Couldnt find the m_flProgressBarStartTime offset!");
  283. g_iProgressBarDuration = FindSendPropOffs("CCSPlayer", "m_iProgressBarDuration");
  284. if(g_iProgressBarDuration == -1)
  285. SetFailState("Couldnt find the m_iProgressBarDuration offset!");
  286. g_iAccount = FindSendPropOffs("CCSPlayer", "m_iAccount");
  287. if(g_iAccount == -1)
  288. SetFailState("Couldnt find the m_iAccount offset!");
  289.  
  290.  
  291. AutoExecConfig(true, "plugin.hide_and_seek");
  292. }
  293.  
  294. public OnPluginEnd()
  295. {
  296. if(g_bEnableHnS)
  297. ServerCommand("mp_restartgame 1");
  298. }
  299.  
  300. public OnConfigsExecuted()
  301. {
  302. if(g_bEnableHnS)
  303. {
  304. // set bad server cvars
  305. for(new i=0;i<sizeof(protected_cvars);i++)
  306. {
  307. g_hProtectedConvar[i] = FindConVar(protected_cvars[i]);
  308. previous_values[i] = GetConVarInt(g_hProtectedConvar[i]);
  309. SetConVarInt(g_hProtectedConvar[i], forced_values[i], true);
  310. HookConVarChange(g_hProtectedConvar[i], OnCvarChange);
  311. }
  312. }
  313. }
  314.  
  315. /*
  316. *
  317. * Generic Events
  318. *
  319. */
  320. public OnMapStart()
  321. {
  322. if(!g_bEnableHnS)
  323. return;
  324.  
  325. BuildMainMenu();
  326. for(new i=0;i<sizeof(whistle_sounds);i++)
  327. PrecacheSound(whistle_sounds[i], true);
  328.  
  329. PrecacheSound("radio/go.wav", true);
  330.  
  331. // prevent us from bugging after mapchange
  332. g_iFirstCTSpawn = 0;
  333. g_iFirstTSpawn = 0;
  334.  
  335. if(g_hShowCountdownTimer != INVALID_HANDLE)
  336. {
  337. KillTimer(g_hShowCountdownTimer);
  338. g_hShowCountdownTimer = INVALID_HANDLE;
  339. }
  340.  
  341. new bool:foundHostageZone = false;
  342.  
  343. // check if there is a hostage rescue zone
  344. new maxent = GetMaxEntities(), String:eName[64];
  345. for (new i=MaxClients;i<maxent;i++)
  346. {
  347. if ( IsValidEdict(i) && IsValidEntity(i) )
  348. {
  349. GetEdictClassname(i, eName, sizeof(eName));
  350. if(StrContains(eName, "func_hostage_rescue") != -1)
  351. {
  352. foundHostageZone = true;
  353. }
  354. }
  355. }
  356.  
  357. // add a hostage rescue zone if there isn't one, so T will win after round time
  358. if(!foundHostageZone)
  359. {
  360. new ent = CreateEntityByName("func_hostage_rescue");
  361. if (ent>0)
  362. {
  363. new Float:orign[3] = {-1000.0,...};
  364. DispatchKeyValue(ent, "targetname", "hidenseek_roundend");
  365. DispatchKeyValueVector(ent, "orign", orign);
  366. DispatchSpawn(ent);
  367. }
  368. }
  369.  
  370. // Remove shadows
  371. // Thanks to Bacardi and Leonardo @ http://forums.alliedmods.net/showthread.php?t=154269
  372. if(GetConVarBool(g_hCVRemoveShadows))
  373. {
  374. new ent = -1;
  375. while((ent = FindEntityByClassname(ent, "shadow_control")) != -1)
  376. {
  377. SetVariantInt(1);
  378. AcceptEntityInput(ent, "SetShadowsDisabled");
  379. }
  380. }
  381. }
  382.  
  383. public OnMapEnd()
  384. {
  385. if(!g_bEnableHnS)
  386. return;
  387.  
  388. CloseHandle(kv);
  389. for(new i=0;i<MAX_LANGUAGES;i++)
  390. {
  391. if(g_hModelMenu[i] != INVALID_HANDLE)
  392. {
  393. CloseHandle(g_hModelMenu[i]);
  394. g_hModelMenu[i] = INVALID_HANDLE;
  395. }
  396. Format(g_sModelMenuLanguage[i], 4, "");
  397. }
  398.  
  399. g_iFirstCTSpawn = 0;
  400. g_iFirstTSpawn = 0;
  401.  
  402. if(g_hShowCountdownTimer != INVALID_HANDLE)
  403. {
  404. KillTimer(g_hShowCountdownTimer);
  405. g_hShowCountdownTimer = INVALID_HANDLE;
  406. }
  407.  
  408. if(g_hRoundTimeTimer != INVALID_HANDLE)
  409. {
  410. KillTimer(g_hRoundTimeTimer);
  411. g_hRoundTimeTimer = INVALID_HANDLE;
  412. }
  413.  
  414. if(g_hWhistleDelay != INVALID_HANDLE)
  415. {
  416. KillTimer(g_hWhistleDelay);
  417. g_hWhistleDelay = INVALID_HANDLE;
  418. }
  419. }
  420.  
  421. public OnClientPutInServer(client)
  422. {
  423. if(!g_bEnableHnS)
  424. return;
  425.  
  426. if(!IsFakeClient(client) && GetConVarBool(g_hCVAntiCheat))
  427. g_hCheckVarTimer[client] = CreateTimer(1.0, StartVarChecker, client, TIMER_REPEAT);
  428.  
  429. // Hook weapon pickup
  430. SDKHook(client, SDKHook_WeaponCanUse, OnWeaponCanUse);
  431.  
  432. // Hook attackings to hide blood
  433. SDKHook(client, SDKHook_TraceAttack, OnTraceAttack);
  434. }
  435.  
  436. public OnClientDisconnect(client)
  437. {
  438. if(!g_bEnableHnS)
  439. return;
  440.  
  441. // set the default values for cvar checking
  442. if(!IsFakeClient(client))
  443. {
  444. for(new i=0;i<sizeof(cheat_commands);i++)
  445. {
  446. g_bConVarViolation[client][i] = false;
  447. g_iConVarMessage[client][i] = 0;
  448. }
  449.  
  450. g_bInThirdPersonView[client] = false;
  451. g_bIsFreezed[client] = false;
  452. g_iModelChangeCount[client] = 0;
  453. g_bIsCTWaiting[client] = false;
  454. g_iWhistleCount[client] = 0;
  455. if (g_hCheatPunishTimer[client] != INVALID_HANDLE)
  456. {
  457. KillTimer(g_hCheatPunishTimer[client]);
  458. g_hCheatPunishTimer[client] = INVALID_HANDLE;
  459. }
  460. if (g_bAllowModelChange[client] && g_hAllowModelChangeTimer[client] != INVALID_HANDLE)
  461. {
  462. KillTimer(g_hAllowModelChangeTimer[client]);
  463. g_hAllowModelChangeTimer[client] = INVALID_HANDLE;
  464. }
  465. if(g_hFreezeCTTimer[client] != INVALID_HANDLE)
  466. {
  467. KillTimer(g_hFreezeCTTimer[client]);
  468. g_hFreezeCTTimer[client] = INVALID_HANDLE;
  469. }
  470. if(g_hUnfreezeCTTimer[client] != INVALID_HANDLE)
  471. {
  472. KillTimer(g_hUnfreezeCTTimer[client]);
  473. g_hUnfreezeCTTimer[client] = INVALID_HANDLE;
  474. }
  475. }
  476. g_bAllowModelChange[client] = true;
  477. g_bFirstSpawn[client] = true;
  478.  
  479. g_bClientIsHigher[client] = false;
  480. g_iFixedModelHeight[client] = 0.0;
  481. g_iLowModelSteps[client] = 0;
  482.  
  483. // Teambalancer
  484. g_bCTToSwitch[client] = false;
  485. CreateTimer(0.1, Timer_ChangeTeam, client, TIMER_FLAG_NO_MAPCHANGE);
  486.  
  487. /*if (g_hCheckVarTimer[client] != INVALID_HANDLE)
  488. {
  489. KillTimer(g_hCheckVarTimer[client]);
  490. g_hCheckVarTimer[client] = INVALID_HANDLE;
  491. }*/
  492. }
  493.  
  494. // prevent players from ducking
  495. public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon)
  496. {
  497. if(!g_bEnableHnS)
  498. return Plugin_Continue;
  499.  
  500. new iInitialButtons = buttons;
  501.  
  502. decl String:weaponName[30];
  503. // don't allow ct's to shoot in the beginning of the round
  504. new team = GetClientTeam(client);
  505. GetClientWeapon(client, weaponName, sizeof(weaponName));
  506. if(team == CS_TEAM_CT && g_bIsCTWaiting[client] && (buttons & IN_ATTACK || buttons & IN_ATTACK2))
  507. {
  508. buttons &= ~IN_ATTACK;
  509. buttons &= ~IN_ATTACK2;
  510. } // disable rightclick knifing for cts
  511. else if(team == CS_TEAM_CT && GetConVarBool(g_hCVDisableRightKnife) && buttons & IN_ATTACK2 && !strcmp(weaponName, "weapon_knife"))
  512. {
  513. buttons &= ~IN_ATTACK2;
  514. }
  515.  
  516. // Modelfix
  517. if(g_iFixedModelHeight[client] != 0.0 && IsPlayerAlive(client) && GetClientTeam(client) == CS_TEAM_T)
  518. {
  519. new Float:vecVelocity[3];
  520. vecVelocity[0] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[0]");
  521. vecVelocity[1] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[1]");
  522. vecVelocity[2] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[2]");
  523. // Player isn't moving
  524. if(vecVelocity[0] == 0.0 && vecVelocity[1] == 0.0 && vecVelocity[2] == 0.0 && !(buttons & IN_FORWARD || buttons & IN_BACK || buttons & IN_MOVELEFT || buttons & IN_MOVERIGHT || buttons & IN_JUMP))
  525. {
  526. if(!g_bClientIsHigher[client] && GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") != -1)
  527. {
  528. new Float:vecClientOrigin[3];
  529. GetClientAbsOrigin(client, vecClientOrigin);
  530. vecClientOrigin[2] += g_iFixedModelHeight[client];
  531. TeleportEntity(client, vecClientOrigin, NULL_VECTOR, NULL_VECTOR);
  532. SetEntityMoveType(client, MOVETYPE_NONE);
  533. g_bClientIsHigher[client] = true;
  534. g_iLowModelSteps[client] = 0;
  535. }
  536. }
  537. // Player is running for 60 thinks? make him visible for a short time
  538. else if(g_iLowModelSteps[client] == 60)
  539. {
  540. if(!g_bClientIsHigher[client] && GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") != -1)
  541. {
  542. new Float:vecClientOrigin[3];
  543. GetClientAbsOrigin(client, vecClientOrigin);
  544. vecClientOrigin[2] += g_iFixedModelHeight[client];
  545. TeleportEntity(client, vecClientOrigin, NULL_VECTOR, NULL_VECTOR);
  546. }
  547. g_iLowModelSteps[client] = 0;
  548. }
  549. // Player is moving
  550. else if(!g_bIsFreezed[client])
  551. {
  552. if(g_bClientIsHigher[client])
  553. {
  554. new Float:vecClientOrigin[3];
  555. GetClientAbsOrigin(client, vecClientOrigin);
  556. vecClientOrigin[2] -= g_iFixedModelHeight[client];
  557. TeleportEntity(client, vecClientOrigin, NULL_VECTOR, NULL_VECTOR);
  558. SetEntityMoveType(client, MOVETYPE_WALK);
  559. g_bClientIsHigher[client] = false;
  560. }
  561. g_iLowModelSteps[client]++;
  562. }
  563.  
  564. // Always disable ducking for that kind of models.
  565. if(buttons & IN_DUCK)
  566. {
  567. buttons &= ~IN_DUCK;
  568. }
  569. }
  570.  
  571. // disable ducking for everyone
  572. if(buttons & IN_DUCK && GetConVarBool(g_hCVDisableDucking))
  573. buttons &= ~IN_DUCK;
  574.  
  575. // disable use for everyone
  576. if(GetConVarBool(g_hCVDisableUse) && buttons & IN_USE)
  577. buttons &= ~IN_USE;
  578.  
  579. if(iInitialButtons != buttons)
  580. return Plugin_Changed;
  581. else
  582. return Plugin_Continue;
  583. }
  584.  
  585. // SDKHook Callbacks
  586. public Action:OnWeaponCanUse(client, weapon)
  587. {
  588. // Allow only CTs to use a weapon
  589. if(g_bEnableHnS && GetClientTeam(client) != CS_TEAM_CT)
  590. {
  591. return Plugin_Handled;
  592. }
  593. return Plugin_Continue;
  594. }
  595.  
  596. // Used to block blood
  597. // set a normal model right before death to avoid errors
  598. public Action:OnTraceAttack(victim, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup)
  599. {
  600. if(!g_bEnableHnS)
  601. return Plugin_Continue;
  602.  
  603. if(GetClientTeam(victim) == CS_TEAM_T)
  604. {
  605. new remainingHealth = GetClientHealth(victim)-RoundToFloor(damage);
  606.  
  607. // Attacker is a human?
  608. if(GetConVarBool(g_hCVHPSeekerEnable) && attacker > 0 && attacker <= MaxClients && IsPlayerAlive(attacker))
  609. {
  610. new decrease = GetConVarInt(g_hCVHPSeekerDec);
  611.  
  612. SetEntityHealth(attacker, GetClientHealth(attacker)+GetConVarInt(g_hCVHPSeekerInc)+decrease);
  613.  
  614. // the hider died? give extra health! need to add the decreased value again, since he fired his gun and lost hp.
  615. // possible "bug": seeker could be slayed because weapon_fire is called earlier than player_hurt.
  616. if(remainingHealth < 0)
  617. SetEntityHealth(attacker, GetClientHealth(attacker)+GetConVarInt(g_hCVHPSeekerBonus)+decrease);
  618. }
  619.  
  620. // prevent errors in console because of missing death animation of prop ;)
  621. if(remainingHealth < 0)
  622. {
  623. SetEntityModel(victim, "models/player/t_guerilla.mdl");
  624. return Plugin_Continue; // just let the damage get through
  625. }
  626. else if(GetConVarBool(g_hCVOpacityEnable))
  627. {
  628. new alpha = 150 + RoundToNearest(10.5*float(remainingHealth/10));
  629.  
  630. SetEntData(victim, g_Render+3, alpha, 1, true);
  631. SetEntityRenderMode(victim, RENDER_TRANSTEXTURE);
  632. }
  633.  
  634. if(GetConVarBool(g_hCVHideBlood))
  635. {
  636. // Simulate the damage
  637. SetEntityHealth(victim, remainingHealth);
  638.  
  639. // Don't show the blood!
  640. return Plugin_Handled;
  641. }
  642. }
  643.  
  644. return Plugin_Continue;
  645. }
  646.  
  647. /*
  648. *
  649. * Hooked Events
  650. *
  651. */
  652. // Player Spawn event
  653. public Action:Event_OnPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
  654. {
  655. if(!g_bEnableHnS)
  656. return Plugin_Continue;
  657.  
  658. new client = GetClientOfUserId(GetEventInt(event, "userid"));
  659. new team = GetClientTeam(client);
  660.  
  661. if(team <= CS_TEAM_SPECTATOR || !IsPlayerAlive(client))
  662. return Plugin_Continue;
  663. else if(team == CS_TEAM_T) // Team T
  664. {
  665. // set the mp_forcecamera value correctly, so he can use thirdperson again
  666. if(!IsFakeClient(client) && GetConVarInt(g_hForceCamera) == 1)
  667. SendConVarValue(client, g_hForceCamera, "0");
  668.  
  669. // reset model change count
  670. g_iModelChangeCount[client] = 0;
  671. g_bInThirdPersonView[client] = false;
  672. if(!IsFakeClient(client) && g_hAllowModelChangeTimer[client] != INVALID_HANDLE)
  673. {
  674. KillTimer(g_hAllowModelChangeTimer[client]);
  675. g_hAllowModelChangeTimer[client] = INVALID_HANDLE;
  676. }
  677. g_bAllowModelChange[client] = true;
  678.  
  679. // Reset model fix height
  680. g_iFixedModelHeight[client] = 0.0;
  681. g_bClientIsHigher[client] = false;
  682.  
  683. // set the speed
  684. SetEntDataFloat(client, g_flLaggedMovementValue, GetConVarFloat(g_hCVHiderSpeed), true);
  685.  
  686. // reset the transparent
  687. if(GetConVarBool(g_hCVOpacityEnable))
  688. {
  689. SetEntData(client,g_Render+3,255,1,true);
  690. SetEntityRenderMode(client, RENDER_TRANSTEXTURE);
  691. }
  692.  
  693. new Float:changeLimitTime = GetConVarFloat(g_hCVChangeLimittime);
  694.  
  695. // Assign a model to bots immediately and disable all menus or timers.
  696. if(IsFakeClient(client))
  697. g_hAllowModelChangeTimer[client] = CreateTimer(0.1, DisableModelMenu, client);
  698. else
  699. {
  700. // only disable the menu, if it's not unlimited
  701. if(changeLimitTime > 0.0)
  702. g_hAllowModelChangeTimer[client] = CreateTimer(changeLimitTime, DisableModelMenu, client);
  703.  
  704. // Set them to thirdperson automatically
  705. if(GetConVarBool(g_hCVAutoThirdPerson))
  706. SetThirdPersonView(client, true);
  707.  
  708. if(GetConVarBool(g_hCVAutoChoose))
  709. SetRandomModel(client);
  710. else if(changeLimitTime > 0.0)
  711. DisplayMenu(g_hModelMenu[GetClientLanguageID(client)], client, RoundToFloor(changeLimitTime));
  712. else
  713. DisplayMenu(g_hModelMenu[GetClientLanguageID(client)], client, MENU_TIME_FOREVER);
  714. }
  715.  
  716. g_iWhistleCount[client] = 0;
  717. g_bIsFreezed[client] = false;
  718.  
  719. if(g_iFirstTSpawn == 0)
  720. {
  721. if(g_hWhistleDelay != INVALID_HANDLE)
  722. {
  723. KillTimer(g_hWhistleDelay);
  724. g_hWhistleDelay = INVALID_HANDLE;
  725. }
  726.  
  727. new Float:whistle_delay = GetConVarFloat(g_hCVWhistleDelay);
  728. if(!g_bWhistlingAllowed && whistle_delay > 0.0)
  729. {
  730. g_hWhistleDelay = CreateTimer(whistle_delay, Timer_AllowWhistle, _, TIMER_FLAG_NO_MAPCHANGE);
  731. }
  732. else
  733. {
  734. g_bWhistlingAllowed = true;
  735. }
  736. g_iFirstTSpawn = GetTime();
  737. }
  738.  
  739. if(GetConVarBool(g_hCVFreezeCTs))
  740. PrintToChat(client, "%s%t", PREFIX, "seconds to hide", RoundToFloor(GetConVarFloat(g_hCVFreezeTime)));
  741. else
  742. PrintToChat(client, "%s%t", PREFIX, "seconds to hide", 0);
  743. }
  744. else if(team == CS_TEAM_CT) // Team CT
  745. {
  746. if(!IsFakeClient(client) && GetConVarInt(g_hForceCamera) == 1)
  747. SendConVarValue(client, g_hForceCamera, "1");
  748.  
  749. new currentTime = GetTime();
  750. new Float:freezeTime = GetConVarFloat(g_hCVFreezeTime);
  751. // don't keep late spawning cts blinded longer than the others :)
  752. if(g_iFirstCTSpawn == 0)
  753. {
  754. if(g_hShowCountdownTimer != INVALID_HANDLE)
  755. {
  756. KillTimer(g_hShowCountdownTimer);
  757. g_hShowCountdownTimer = INVALID_HANDLE;
  758. if(GetConVarBool(g_hCVShowProgressBar))
  759. {
  760. for(new i=1;i<=MaxClients;i++)
  761. {
  762. if(IsClientInGame(i))
  763. {
  764. SetEntDataFloat(i, g_flProgressBarStartTime, 0.0, true);
  765. SetEntData(i, g_iProgressBarDuration, 0, 4, true);
  766. }
  767. }
  768. }
  769. }
  770. else if(GetConVarBool(g_hCVFreezeCTs))
  771. {
  772. // show time in center
  773. g_hShowCountdownTimer = CreateTimer(0.01, ShowCountdown, RoundToFloor(GetConVarFloat(g_hCVFreezeTime)));
  774. }
  775. g_iFirstCTSpawn = currentTime;
  776. }
  777. // only freeze spawning players if the freezetime is still running.
  778. if(GetConVarBool(g_hCVFreezeCTs) && (float(currentTime - g_iFirstCTSpawn) < freezeTime))
  779. {
  780. g_bIsCTWaiting[client] = true;
  781. CreateTimer(0.05, FreezePlayer, client, TIMER_FLAG_NO_MAPCHANGE);
  782.  
  783. // Start freezing player
  784. g_hFreezeCTTimer[client] = CreateTimer(2.0, FreezePlayer, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
  785.  
  786. if(g_hUnfreezeCTTimer[client] != INVALID_HANDLE)
  787. {
  788. KillTimer(g_hUnfreezeCTTimer[client]);
  789. g_hUnfreezeCTTimer[client] = INVALID_HANDLE;
  790. }
  791.  
  792. // Stop freezing player
  793. g_hUnfreezeCTTimer[client] = CreateTimer(freezeTime-float(currentTime - g_iFirstCTSpawn), UnFreezePlayer, client, TIMER_FLAG_NO_MAPCHANGE);
  794.  
  795. PrintToChat(client, "%s%t", PREFIX, "Wait for t to hide", RoundToFloor(freezeTime-float(currentTime - g_iFirstCTSpawn)));
  796. }
  797.  
  798. // show help menu on first spawn
  799. if(GetConVarBool(g_hCVShowHideHelp) && g_bFirstSpawn[client])
  800. {
  801. Display_Help(client, 0);
  802. g_bFirstSpawn[client] = false;
  803. }
  804.  
  805. // Make sure CTs have a knife
  806. CreateTimer(2.0, Timer_CheckCTHasKnife, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE);
  807. }
  808.  
  809. // hide radar
  810. // Huge thanks to GoD-Tony!
  811. SetEntDataFloat(client, g_flFlashDuration, 10000.0, true);
  812. SetEntDataFloat(client, g_flFlashMaxAlpha, 0.5, true);
  813.  
  814. return Plugin_Continue;
  815. }
  816.  
  817. // subtract 5hp for every shot a seeker is giving
  818. public Action:Event_OnWeaponFire(Handle:event, const String:name[], bool:dontBroadcast)
  819. {
  820. if(!g_bEnableHnS)
  821. return Plugin_Continue;
  822.  
  823. if(!GetConVarBool(g_hCVHPSeekerEnable) || g_bRoundEnded)
  824. return Plugin_Continue;
  825.  
  826. new client = GetClientOfUserId(GetEventInt(event, "userid"));
  827. new decreaseHP = GetConVarInt(g_hCVHPSeekerDec);
  828. new clientHealth = GetClientHealth(client);
  829.  
  830. // he can take it
  831. if((clientHealth-decreaseHP) > 0)
  832. {
  833. SetEntityHealth(client, (clientHealth-decreaseHP));
  834. }
  835. else // slay him
  836. {
  837. ForcePlayerSuicide(client);
  838. }
  839. return Plugin_Continue;
  840. }
  841.  
  842. public Action:Event_OnRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
  843. {
  844. if(!g_bEnableHnS)
  845. return Plugin_Continue;
  846.  
  847. g_bRoundEnded = false;
  848. g_bWhistlingAllowed = false;
  849.  
  850. // When disabling +use or "e" button open all doors on the map and keep them opened.
  851. new bool:bUse = GetConVarBool(g_hCVDisableUse);
  852.  
  853. new maxent = GetMaxEntities(), String:eName[64];
  854. for (new i=MaxClients;i<maxent;i++)
  855. {
  856. if ( IsValidEdict(i) && IsValidEntity(i) )
  857. {
  858. GetEdictClassname(i, eName, sizeof(eName));
  859. // remove bombzones and hostages so no normal gameplay could end the round
  860. if ( StrContains(eName, "hostage_entity") != -1 || StrContains(eName, "func_bomb_target") != -1 || (StrContains(eName, "func_buyzone") != -1 && GetEntProp(i, Prop_Data, "m_iTeamNum", 4) == CS_TEAM_T))
  861. {
  862. RemoveEdict(i);
  863. }
  864. // Open all doors
  865. else if(bUse && StrContains(eName, "_door", false) != -1)
  866. {
  867. AcceptEntityInput(i, "Open");
  868. HookSingleEntityOutput(i, "OnClose", EntOutput_OnClose);
  869. }
  870. }
  871. }
  872.  
  873. // Remove shadows
  874. // Thanks to Bacardi and Leonardo @ http://forums.alliedmods.net/showthread.php?t=154269
  875. if(GetConVarBool(g_hCVRemoveShadows))
  876. {
  877. new ent = -1;
  878. while((ent = FindEntityByClassname(ent, "shadow_control")) != -1)
  879. {
  880. SetVariantInt(1);
  881. AcceptEntityInput(ent, "SetShadowsDisabled");
  882. }
  883. }
  884.  
  885. // show the roundtime in env_hudhint entity
  886. g_iRoundStartTime = GetTime();
  887. new realRoundTime = RoundToNearest(GetConVarFloat(g_iRoundTime)*60.0);
  888. g_hRoundTimeTimer = CreateTimer(0.5, ShowRoundTime, realRoundTime, TIMER_FLAG_NO_MAPCHANGE);
  889. return Plugin_Continue;
  890. }
  891. // give terrorists frags
  892. public Action:Event_OnRoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
  893. {
  894. if(!g_bEnableHnS)
  895. return Plugin_Continue;
  896.  
  897. // round has ended. used to not decrease seekers hp on shoot
  898. g_bRoundEnded = true;
  899.  
  900. g_iFirstCTSpawn = 0;
  901. g_iFirstTSpawn = 0;
  902.  
  903. if(g_hShowCountdownTimer != INVALID_HANDLE)
  904. {
  905. KillTimer(g_hShowCountdownTimer);
  906. g_hShowCountdownTimer = INVALID_HANDLE;
  907. }
  908.  
  909. if(g_hRoundTimeTimer != INVALID_HANDLE)
  910. {
  911. KillTimer(g_hRoundTimeTimer);
  912. g_hRoundTimeTimer = INVALID_HANDLE;
  913. }
  914.  
  915. if(g_hWhistleDelay != INVALID_HANDLE)
  916. {
  917. KillTimer(g_hWhistleDelay);
  918. g_hWhistleDelay = INVALID_HANDLE;
  919. }
  920.  
  921. new winnerTeam = GetEventInt(event, "winner");
  922.  
  923. if(winnerTeam == CS_TEAM_T)
  924. {
  925. new increaseFrags = GetConVarInt(g_hCVHiderWinFrags);
  926.  
  927. new bool:aliveTerrorists = false;
  928. new iFrags = 0;
  929. // increase playerscore of all alive Terrorists
  930. for(new i=1;i<=MaxClients;i++)
  931. {
  932. if(IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == CS_TEAM_T)
  933. {
  934. if(increaseFrags > 0)
  935. {
  936. // increase kills by x
  937. iFrags = GetClientFrags(i) + increaseFrags;
  938. SetEntProp(i, Prop_Data, "m_iFrags", iFrags, 4);
  939. aliveTerrorists = true;
  940. }
  941.  
  942. // set godmode for the rest of the round
  943. SetEntProp(i, Prop_Data, "m_takedamage", 0, 1);
  944. }
  945. }
  946.  
  947. if(aliveTerrorists)
  948. {
  949. PrintToChatAll("%s%t", PREFIX, "got frags", increaseFrags);
  950. }
  951.  
  952. if(GetConVarBool(g_hCVSlaySeekers))
  953. {
  954. // slay all seekers
  955. for(new i=1;i<=MaxClients;i++)
  956. {
  957. if(IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == CS_TEAM_CT)
  958. {
  959. ForcePlayerSuicide(i);
  960. }
  961. }
  962. }
  963. }
  964.  
  965. // Switch the flagged players to CT
  966. CreateTimer(0.1, Timer_SwitchTeams, _, TIMER_FLAG_NO_MAPCHANGE);
  967.  
  968. return Plugin_Continue;
  969. }
  970.  
  971. // remove ragdolls on death...
  972. public Action:Event_OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
  973. {
  974. if(!g_bEnableHnS)
  975. return Plugin_Continue;
  976.  
  977. new client = GetClientOfUserId(GetEventInt(event, "userid"));
  978.  
  979. if(g_iFixedModelHeight[client] != 0.0 && g_bClientIsHigher[client])
  980. {
  981. SetEntityMoveType(client, MOVETYPE_WALK);
  982. g_bClientIsHigher[client] = false;
  983. }
  984. g_iFixedModelHeight[client] = 0.0;
  985. g_bClientIsHigher[client] = false;
  986.  
  987. // Show guns again.
  988. SetThirdPersonView(client, false);
  989.  
  990. // set the mp_forcecamera value correctly, so he can watch his teammates
  991. // This doesn't work. Even if the convar is set to 0, the hiders are only able to spectate their teammates..
  992. if(GetConVarInt(g_hForceCamera) == 1)
  993. {
  994. if(!IsFakeClient(client) && GetClientTeam(client) != CS_TEAM_T)
  995. SendConVarValue(client, g_hForceCamera, "1");
  996. else if(!IsFakeClient(client))
  997. SendConVarValue(client, g_hForceCamera, "0");
  998. }
  999.  
  1000. if (!IsValidEntity(client) || IsPlayerAlive(client))
  1001. return Plugin_Continue;
  1002.  
  1003. // Unfreeze, if freezed before
  1004. if(g_bIsFreezed[client])
  1005. {
  1006. if(GetConVarInt(g_hCVHiderFreezeMode) == 1)
  1007. SetEntityMoveType(client, MOVETYPE_WALK);
  1008. else
  1009. {
  1010. SetEntData(client, g_Freeze, FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND, 4, true);
  1011. SetEntityMoveType(client, MOVETYPE_WALK);
  1012. }
  1013.  
  1014. g_bIsFreezed[client] = false;
  1015. }
  1016.  
  1017. new ragdoll = GetEntPropEnt(client, Prop_Send, "m_hRagdoll");
  1018. if (ragdoll<0)
  1019. return Plugin_Continue;
  1020.  
  1021. RemoveEdict(ragdoll);
  1022.  
  1023. return Plugin_Continue;
  1024. }
  1025.  
  1026. public Event_OnPlayerBlind(Handle:event, const String:name[], bool:dontBroadcast)
  1027. {
  1028. if(!g_bEnableHnS)
  1029. return;
  1030.  
  1031. // Thanks to GoD-Tony!
  1032. new userid = GetEventInt(event, "userid");
  1033. new client = GetClientOfUserId(userid);
  1034. new Float:iDuration = GetEntDataFloat(client, g_flFlashDuration);
  1035. if(iDuration > 0.1)
  1036. iDuration -= 0.1;
  1037.  
  1038. if (client && GetClientTeam(client) > 1)
  1039. CreateTimer(iDuration, Timer_FlashEnd, userid, TIMER_FLAG_NO_MAPCHANGE);
  1040. }
  1041.  
  1042. public Action:Event_OnPlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
  1043. {
  1044. if(!g_bEnableHnS)
  1045. return Plugin_Continue;
  1046.  
  1047. new client = GetClientOfUserId(GetEventInt(event, "userid"));
  1048. new team = GetEventInt(event, "team");
  1049. new bool:disconnect = GetEventBool(event, "disconnect");
  1050.  
  1051. // Handle the thirdperson view values
  1052. // terrors are always allowed to view players in thirdperson
  1053. if(client && !IsFakeClient(client) && GetConVarInt(g_hForceCamera) == 1)
  1054. {
  1055. if(team == CS_TEAM_T)
  1056. SendConVarValue(client, g_hForceCamera, "0");
  1057. else if(team != CS_TEAM_CT)
  1058. SendConVarValue(client, g_hForceCamera, "1");
  1059. }
  1060.  
  1061. // Player disconnected?
  1062. if(disconnect)
  1063. g_bCTToSwitch[client] = false;
  1064.  
  1065. // Player joined spectator?
  1066. if(!disconnect && team < CS_TEAM_T)
  1067. {
  1068. g_bCTToSwitch[client] = false;
  1069.  
  1070. // Unblind and show weapons again
  1071. SetEntProp(client, Prop_Send, "m_bDrawViewmodel", 1);
  1072. PerformBlind(client, 0);
  1073.  
  1074. // Reset the model fix
  1075. if(g_iFixedModelHeight[client] != 0.0 && g_bClientIsHigher[client])
  1076. {
  1077. SetEntityMoveType(client, MOVETYPE_OBSERVER);
  1078. }
  1079. g_iFixedModelHeight[client] = 0.0;
  1080. g_bClientIsHigher[client] = false;
  1081.  
  1082. // Unfreeze, if freezed before
  1083. if(g_bIsFreezed[client])
  1084. {
  1085. if(GetConVarInt(g_hCVHiderFreezeMode) == 1)
  1086. SetEntityMoveType(client, MOVETYPE_OBSERVER);
  1087. else
  1088. {
  1089. SetEntData(client, g_Freeze, FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND, 4, true);
  1090. SetEntityMoveType(client, MOVETYPE_OBSERVER);
  1091. }
  1092.  
  1093. g_bIsFreezed[client] = false;
  1094. }
  1095. }
  1096.  
  1097. // Reset the last joined ct, if he left
  1098. if(disconnect && g_iLastJoinedCT == client)
  1099. g_iLastJoinedCT = -1;
  1100.  
  1101. // Strip the player if joined T midround
  1102. if(!disconnect && team == CS_TEAM_T && IsPlayerAlive(client))
  1103. {
  1104. StripPlayerWeapons(client);
  1105. }
  1106.  
  1107. // Ignore, if Teambalance is disabled
  1108. if(GetConVarFloat(g_hCVCTRatio) == 0.0)
  1109. return Plugin_Continue;
  1110.  
  1111. // GetTeamClientCount() doesn't handle the teamchange we're called for in player_team,
  1112. // so wait two frames to update the counts
  1113. CreateTimer(0.2, Timer_ChangeTeam, client, TIMER_FLAG_NO_MAPCHANGE);
  1114.  
  1115. return Plugin_Continue;
  1116. }
  1117.  
  1118. public Event_OnItemPickup(Handle:event, const String:name[], bool:dontBroadcast)
  1119. {
  1120. if(!g_bEnableHnS)
  1121. return;
  1122.  
  1123. new client = GetClientOfUserId(GetEventInt( event, "userid"));
  1124. decl String:sItem[100];
  1125. GetEventString(event, "item", sItem, sizeof(sItem));
  1126.  
  1127. // restrict nightvision
  1128. if(StrEqual(sItem, "nvgs", false))
  1129. SetEntData(client, g_iHasNightVision, 0, 4, true);
  1130. }
  1131.  
  1132. public EntOutput_OnClose(const String:output[], caller, activator, Float:delay)
  1133. {
  1134. AcceptEntityInput(caller, "Open");
  1135. }
  1136.  
  1137. /*
  1138. *
  1139. * Timer Callbacks
  1140. *
  1141. */
  1142.  
  1143. // Freeze player function
  1144. public Action:FreezePlayer(Handle:timer, any:client)
  1145. {
  1146. if(!IsClientInGame(client) || !IsPlayerAlive(client) || !g_bIsCTWaiting[client])
  1147. {
  1148. g_hFreezeCTTimer[client] = INVALID_HANDLE;
  1149. return Plugin_Stop;
  1150. }
  1151.  
  1152. // Force him to watch at the ground.
  1153. new Float:fPlayerEyes[3];
  1154. GetClientEyeAngles(client, fPlayerEyes);
  1155. fPlayerEyes[0] = 180.0;
  1156. TeleportEntity(client, NULL_VECTOR, fPlayerEyes, NULL_VECTOR);
  1157. SetEntData(client, g_Freeze, FL_CLIENT|FL_ATCONTROLS, 4, true);
  1158. SetEntityMoveType(client, MOVETYPE_NONE);
  1159. PerformBlind(client, 255);
  1160.  
  1161. return Plugin_Continue;
  1162. }
  1163.  
  1164. // Unfreeze player function
  1165. public Action:UnFreezePlayer(Handle:timer, any:client)
  1166. {
  1167. g_hUnfreezeCTTimer[client] = INVALID_HANDLE;
  1168.  
  1169. if(!IsClientInGame(client) || !IsPlayerAlive(client))
  1170. return Plugin_Stop;
  1171.  
  1172. SetEntData(client, g_Freeze, FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND, 4, true);
  1173. SetEntityMoveType(client, MOVETYPE_WALK);
  1174.  
  1175. if(!IsConVarCheater(client))
  1176. PerformBlind(client, 0);
  1177.  
  1178. g_bIsCTWaiting[client] = false;
  1179.  
  1180. EmitSoundToClient(client, "radio/go.wav");
  1181.  
  1182. PrintToChat(client, "%s%t", PREFIX, "Go search");
  1183.  
  1184. return Plugin_Stop;
  1185. }
  1186.  
  1187. public Action:DisableModelMenu(Handle:timer, any:client)
  1188. {
  1189.  
  1190. g_hAllowModelChangeTimer[client] = INVALID_HANDLE;
  1191.  
  1192. if(!IsClientInGame(client))
  1193. return Plugin_Stop;
  1194.  
  1195. g_bAllowModelChange[client] = false;
  1196.  
  1197. if(IsPlayerAlive(client))
  1198. PrintToChat(client, "%s%t", PREFIX, "Modelmenu Disabled");
  1199.  
  1200. // didn't he chose a model?
  1201. if(GetClientTeam(client) == CS_TEAM_T && g_iModelChangeCount[client] == 0)
  1202. {
  1203. // give him a random one.
  1204. PrintToChat(client, "%s%t", PREFIX, "Did not choose model");
  1205. SetRandomModel(client);
  1206. }
  1207.  
  1208. return Plugin_Stop;
  1209. }
  1210.  
  1211. public Action:StartVarChecker(Handle:timer, any:client)
  1212. {
  1213. if (!IsClientInGame(client))
  1214. return Plugin_Stop;
  1215.  
  1216. // allow watching
  1217. if(GetClientTeam(client) < CS_TEAM_T)
  1218. {
  1219. PerformBlind(client, 0);
  1220. return Plugin_Continue;
  1221. }
  1222.  
  1223. // check all defined cvars for value "0"
  1224. for(new i=0;i<sizeof(cheat_commands);i++)
  1225. QueryClientConVar(client, cheat_commands[i], ConVarQueryFinished:ClientConVar, client);
  1226.  
  1227. if(IsConVarCheater(client))
  1228. {
  1229. // Blind and Freeze player
  1230. PerformBlind(client, 255);
  1231. SetEntityMoveType(client, MOVETYPE_NONE);
  1232.  
  1233. if(GetConVarInt(g_hCVCheatPunishment) != 0 && g_hCheatPunishTimer[client] == INVALID_HANDLE)
  1234. {
  1235. g_hCheatPunishTimer[client] = CreateTimer(15.0, PerformCheatPunishment, client, TIMER_FLAG_NO_MAPCHANGE);
  1236. }
  1237. }
  1238. else
  1239. {
  1240. if(g_hCheatPunishTimer[client] != INVALID_HANDLE)
  1241. {
  1242. KillTimer(g_hCheatPunishTimer[client]);
  1243. g_hCheatPunishTimer[client] = INVALID_HANDLE;
  1244. }
  1245.  
  1246. if(!g_bIsCTWaiting[client])
  1247. {
  1248. if(IsPlayerAlive(client))
  1249. SetEntityMoveType(client, MOVETYPE_WALK);
  1250. PerformBlind(client, 0);
  1251. }
  1252. }
  1253.  
  1254. return Plugin_Continue;
  1255. }
  1256.  
  1257. public Action:PerformCheatPunishment(Handle:timer, any:client)
  1258. {
  1259. g_hCheatPunishTimer[client] = INVALID_HANDLE;
  1260.  
  1261. if(!IsClientInGame(client) || !IsConVarCheater(client))
  1262. return Plugin_Stop;
  1263.  
  1264. new punishmentType = GetConVarInt(g_hCVCheatPunishment);
  1265. if(punishmentType == 1 && GetClientTeam(client) != CS_TEAM_SPECTATOR )
  1266. {
  1267. g_bCTToSwitch[client] = false;
  1268.  
  1269. // Unblind and show weapons again
  1270. SetEntProp(client, Prop_Send, "m_bDrawViewmodel", 1);
  1271. PerformBlind(client, 0);
  1272.  
  1273. // Reset the model fix
  1274. if(g_iFixedModelHeight[client] != 0.0 && g_bClientIsHigher[client])
  1275. {
  1276. SetEntityMoveType(client, MOVETYPE_OBSERVER);
  1277. }
  1278. g_iFixedModelHeight[client] = 0.0;
  1279. g_bClientIsHigher[client] = false;
  1280.  
  1281. // Unfreeze, if freezed before
  1282. if(g_bIsFreezed[client])
  1283. {
  1284. if(GetConVarInt(g_hCVHiderFreezeMode) == 1)
  1285. SetEntityMoveType(client, MOVETYPE_OBSERVER);
  1286. else
  1287. {
  1288. SetEntData(client, g_Freeze, FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND, 4, true);
  1289. SetEntityMoveType(client, MOVETYPE_OBSERVER);
  1290. }
  1291.  
  1292. g_bIsFreezed[client] = false;
  1293. }
  1294.  
  1295. if(g_iLastJoinedCT == client)
  1296. g_iLastJoinedCT = -1;
  1297.  
  1298. ChangeClientTeam(client, CS_TEAM_SPECTATOR);
  1299. PrintToChatAll("%s%N %t", PREFIX, client, "Spectator Cheater");
  1300. }
  1301. else if(punishmentType == 2)
  1302. {
  1303. for(new i=0;i<sizeof(cheat_commands);i++)
  1304. if(g_bConVarViolation[client][i])
  1305. PrintToConsole(client, "Hide and Seek: %t %s 0", "Print to console", cheat_commands[i]);
  1306. KickClient(client, "Hide and Seek: %t", "Kick bad cvars");
  1307. }
  1308. return Plugin_Stop;
  1309. }
  1310.  
  1311. // teach the players the /whistle and /tp commands
  1312. public Action:SpamCommands(Handle:timer, any:data)
  1313. {
  1314. if(GetConVarBool(g_hCVWhistle) && data == 1)
  1315. PrintToChatAll("%s%t", PREFIX, "T type /whistle");
  1316. else if(!GetConVarBool(g_hCVWhistle) || data == 0)
  1317. {
  1318. for(new i=1;i<=MaxClients;i++)
  1319. if(IsClientInGame(i) && GetClientTeam(i) == CS_TEAM_T)
  1320. PrintToChat(i, "%s%t", PREFIX, "T type /tp");
  1321. }
  1322. g_hSpamCommandsTimer = CreateTimer(120.0, SpamCommands, (data==0?1:0));
  1323. return Plugin_Stop;
  1324. }
  1325.  
  1326. // show all players a countdown
  1327. // CT: I'm coming!
  1328. public Action:ShowCountdown(Handle:timer, any:freezeTime)
  1329. {
  1330. new seconds = freezeTime - GetTime() + g_iFirstCTSpawn;
  1331. PrintCenterTextAll("%d", seconds);
  1332. if(seconds <= 0)
  1333. {
  1334. g_hShowCountdownTimer = INVALID_HANDLE;
  1335. if(GetConVarBool(g_hCVShowProgressBar))
  1336. {
  1337. for(new i=1;i<=MaxClients;i++)
  1338. {
  1339. if(IsClientInGame(i))
  1340. {
  1341. SetEntDataFloat(i, g_flProgressBarStartTime, 0.0, true);
  1342. SetEntData(i, g_iProgressBarDuration, 0, 4, true);
  1343. }
  1344. }
  1345. }
  1346. return Plugin_Stop;
  1347. }
  1348.  
  1349. // m_iProgressBarDuration has a limit of 15 seconds, so start showing the bar on 15 seconds left.
  1350. if(GetConVarBool(g_hCVShowProgressBar) && (seconds) < 15)
  1351. {
  1352. for(new i=1;i<=MaxClients;i++)
  1353. {
  1354. if(IsClientInGame(i) && GetEntProp(i, Prop_Send, "m_iProgressBarDuration") == 0)
  1355. {
  1356. SetEntDataFloat(i, g_flProgressBarStartTime, GetGameTime(), true);
  1357. SetEntData(i, g_iProgressBarDuration, seconds, 4, true);
  1358. }
  1359. }
  1360. }
  1361.  
  1362. g_hShowCountdownTimer = CreateTimer(0.5, ShowCountdown, freezeTime);
  1363.  
  1364. return Plugin_Stop;
  1365. }
  1366.  
  1367. public Action:ShowRoundTime(Handle:timer, any:roundTime)
  1368. {
  1369. decl String:timeLeft[10];
  1370. new seconds = roundTime - GetTime() + g_iRoundStartTime;
  1371.  
  1372. new minutes = RoundToFloor(float(seconds) / 60.0);
  1373. new secs = seconds - minutes*60;
  1374. if(secs < 10)
  1375. Format(timeLeft, sizeof(timeLeft), "%d:0%d", minutes, secs);
  1376. else
  1377. Format(timeLeft, sizeof(timeLeft), "%d:%d", minutes, secs);
  1378.  
  1379. new countalivect;
  1380. new countalivet;
  1381.  
  1382. for(new i=1;i<=MaxClients;i++)
  1383. {
  1384. if (IsPlayerAlive(i))
  1385. {
  1386. if (GetClientTeam(i) == 2)
  1387. countalivet++;
  1388.  
  1389. if (GetClientTeam(i) == 3)
  1390. countalivect++;
  1391. }
  1392.  
  1393. if(IsClientInGame(i) && g_bInThirdPersonView[i])
  1394. {
  1395. new Handle:hBuffer = StartMessageOne("KeyHintText", i);
  1396. BfWriteByte(hBuffer, 1);
  1397. BfWriteString(hBuffer, timeLeft);
  1398. EndMessage();
  1399. }
  1400. }
  1401.  
  1402. if (countalivet == 0 || countalivect == 0)
  1403. ServerCommand("mp_restartgame 1");
  1404.  
  1405. if (seconds == 0)
  1406. ServerCommand("mp_restartgame 1");
  1407.  
  1408.  
  1409.  
  1410.  
  1411. if(seconds > 0)
  1412. g_hRoundTimeTimer = CreateTimer(0.5, ShowRoundTime, roundTime, TIMER_FLAG_NO_MAPCHANGE);
  1413. else
  1414. g_hRoundTimeTimer = INVALID_HANDLE;
  1415.  
  1416. return Plugin_Stop;
  1417. }
  1418.  
  1419. public Action:Timer_AllowWhistle(Handle:timer, any:data)
  1420. {
  1421. g_bWhistlingAllowed = true;
  1422.  
  1423. g_hWhistleDelay = INVALID_HANDLE;
  1424. return Plugin_Stop;
  1425. }
  1426.  
  1427. public Action:Timer_SwitchTeams(Handle:timer, any:data)
  1428. {
  1429. decl String:sName[64];
  1430. for(new i=1;i<=MaxClients;i++)
  1431. {
  1432. if(g_bCTToSwitch[i])
  1433. {
  1434. if(IsClientInGame(i))
  1435. {
  1436. GetClientName(i, sName, sizeof(sName));
  1437. CS_SwitchTeam(i, CS_TEAM_T);
  1438. PrintToChatAll("%s%t", PREFIX, "switched", sName);
  1439. }
  1440. g_bCTToSwitch[i] = false;
  1441. }
  1442. }
  1443. return Plugin_Stop;
  1444. }
  1445.  
  1446. public Action:Timer_ChangeTeam(Handle:timer, any:client)
  1447. {
  1448. new iCTCount = GetTeamClientCount(CS_TEAM_CT);
  1449. new iTCount = GetTeamClientCount(CS_TEAM_T);
  1450.  
  1451. new iToBeSwitched = 0;
  1452.  
  1453. // Check, how many cts are going to get switched to terror at the end of the round
  1454. new iTeam;
  1455. for(new i=1;i<=MaxClients;i++)
  1456. {
  1457. // Don't care for cheaters
  1458. if(IsConVarCheater(i))
  1459. {
  1460. if(IsClientInGame(i))
  1461. {
  1462. iTeam = GetClientTeam(i);
  1463. if(iTeam == CS_TEAM_CT)
  1464. iCTCount--;
  1465. else if(iTeam == CS_TEAM_T)
  1466. iTCount--;
  1467. }
  1468. }
  1469. else if(g_bCTToSwitch[i])
  1470. {
  1471. iCTCount--;
  1472. iTCount++;
  1473. iToBeSwitched++;
  1474. }
  1475. }
  1476. //PrintToServer("Debug: %d players are flagged to switch at the end of the round.", iToBeSwitched);
  1477. new Float:fRatio = FloatDiv(float(iCTCount), float(iTCount));
  1478.  
  1479. new Float:fCFGCTRatio = GetConVarFloat(g_hCVCTRatio);
  1480.  
  1481. new Float:fCFGRatio = FloatDiv(1.0, fCFGCTRatio);
  1482.  
  1483. //PrintToServer("Debug: Initial CTCount: %d TCount: %d Ratio: %f, CFGRatio: %f", iCTCount, iTCount, fRatio, fCFGRatio);
  1484.  
  1485. decl String:sName[64];
  1486. // There are more CTs than we want in the CT team and it's not the first CT
  1487. if((iCTCount > 0 || iTCount > 0) && iCTCount != 1 && fRatio > fCFGRatio)
  1488. {
  1489. //PrintToServer("Debug: Too much CTs! Taking action...");
  1490. // Any players flagged to be moved at the end of the round?
  1491. if(iToBeSwitched > 0)
  1492. {
  1493. for(new i=1;i<=MaxClients;i++)
  1494. {
  1495. if(g_bCTToSwitch[i])
  1496. {
  1497. g_bCTToSwitch[i] = false;
  1498. iCTCount++;
  1499. iTCount--;
  1500. GetClientName(i, sName, sizeof(sName));
  1501. PrintToChatAll("%s%t.", PREFIX, "stop switch", sName);
  1502.  
  1503. //PrintToServer("Debug: Unflagged one player from being switched to T. CTCount: %d TCount: %d Ratio: %f", iCTCount, iTCount, FloatDiv(float(iCTCount), float(iTCount)));
  1504.  
  1505. // switched enough players?
  1506. if(float(iTCount) < fCFGCTRatio || FloatDiv(float(iCTCount), float(iTCount)) <= fCFGRatio)
  1507. {
  1508. //PrintToServer("Debug: Switched enough players after unflagging.");
  1509. return Plugin_Stop;
  1510. }
  1511. }
  1512. }
  1513. }
  1514.  
  1515. // First check, if the last change has been from x->CT
  1516. if(client && IsClientInGame(client) && GetClientTeam(client) == CS_TEAM_CT)
  1517. {
  1518. // Reverse the change or put him in T directly
  1519. iCTCount--;
  1520. iTCount++;
  1521. ChangeClientTeam(client, CS_TEAM_T);
  1522. GetClientName(client, sName, sizeof(sName));
  1523. PrintToChatAll("%s%t", PREFIX, "switched", sName);
  1524.  
  1525. //PrintToServer("Debug: Switched the player %s straight back to T. CTCount: %d TCount: %d Ratio: %f", sName, iCTCount, iTCount, FloatDiv(float(iCTCount), float(iTCount)));
  1526.  
  1527. // switched enough players?
  1528. if(float(iTCount) < fCFGCTRatio || FloatDiv(float(iCTCount), float(iTCount)) <= fCFGRatio)
  1529. {
  1530. //PrintToServer("Debug: Switched enough players after reversing the last change.");
  1531. return Plugin_Stop;
  1532. }
  1533. }
  1534. // Switch last joined CT
  1535. else if(g_iLastJoinedCT != -1)
  1536. {
  1537. // Dead? switch directly.
  1538. if(IsClientInGame(g_iLastJoinedCT) && !IsPlayerAlive(g_iLastJoinedCT))
  1539. {
  1540. iCTCount--;
  1541. iTCount++;
  1542. ChangeClientTeam(g_iLastJoinedCT, CS_TEAM_T);
  1543. GetClientName(g_iLastJoinedCT, sName, sizeof(sName));
  1544. PrintToChatAll("%s%t", PREFIX, "switched", sName);
  1545. //PrintToServer("Debug: Switched the last joined CT %s to T. CTCount: %d TCount: %d Ratio: %f", sName, iCTCount, iTCount, FloatDiv(float(iCTCount), float(iTCount)));
  1546. }
  1547. else if(IsClientInGame(g_iLastJoinedCT))
  1548. {
  1549. iCTCount--;
  1550. iTCount++;
  1551. g_bCTToSwitch[g_iLastJoinedCT] = true;
  1552. GetClientName(g_iLastJoinedCT, sName, sizeof(sName));
  1553. PrintToChatAll("%s%t", PREFIX, "going to switch", sName);
  1554. //PrintToServer("Debug: Flagged the last joined CT %s to switch at roundend. CTCount: %d TCount: %d Ratio: %f", sName, iCTCount, iTCount, FloatDiv(float(iCTCount), float(iTCount)));
  1555. }
  1556.  
  1557. // switched enough players?
  1558. if(float(iTCount) < fCFGCTRatio || FloatDiv(float(iCTCount), float(iTCount)) <= fCFGRatio)
  1559. {
  1560. //PrintToServer("Debug: Switched enough players after checking the last joined CT.");
  1561. return Plugin_Stop;
  1562. }
  1563. }
  1564.  
  1565. // First search for a dead seeker, so we can switch him
  1566. // @TODO: Take care for ranking on the scoreboard or longest playtime as CT
  1567. for(new i=1;i<=MaxClients;i++)
  1568. {
  1569. // switched enough players?
  1570. if(float(iTCount) < fCFGCTRatio || FloatDiv(float(iCTCount), float(iTCount)) <= fCFGRatio)
  1571. {
  1572. //PrintToServer("Debug: Switched enough players after switching dead cts");
  1573. return Plugin_Stop;
  1574. }
  1575.  
  1576. // Switch one ct to t immediately.
  1577. if(IsClientInGame(i) && !IsPlayerAlive(i) && GetClientTeam(i) == CS_TEAM_CT && !g_bCTToSwitch[i])
  1578. {
  1579. iCTCount--;
  1580. iTCount++;
  1581. ChangeClientTeam(i, CS_TEAM_T);
  1582. GetClientName(i, sName, sizeof(sName));
  1583. PrintToChatAll("%s%t", PREFIX, "switched", sName);
  1584. //PrintToServer("Debug: Switched dead CT %s to T. CTCount: %d TCount: %d Ratio: %f", sName, iCTCount, iTCount, FloatDiv(float(iCTCount), float(iTCount)));
  1585. }
  1586. }
  1587.  
  1588. // Still not enough switched? Just pick a random one and switch him at the end of the round
  1589. for(new i=1;i<=MaxClients;i++)
  1590. {
  1591. // switched enough players?
  1592. if(float(iTCount) < fCFGCTRatio || FloatDiv(float(iCTCount), float(iTCount)) <= fCFGRatio)
  1593. {
  1594. //PrintToServer("Debug: Switched enough players after flagging alive CTs");
  1595. return Plugin_Stop;
  1596. }
  1597.  
  1598. if(IsClientInGame(i) && GetClientTeam(i) == CS_TEAM_CT && !g_bCTToSwitch[i])
  1599. {
  1600. iCTCount--;
  1601. iTCount++;
  1602. g_bCTToSwitch[i] = true;
  1603. GetClientName(i, sName, sizeof(sName));
  1604. PrintToChatAll("%s%t", PREFIX, "going to switch", sName);
  1605. //PrintToServer("Debug: Flagging alive CT %s to switch to T at roundend. CTCount: %d TCount: %d Ratio: %f", sName, iCTCount, iTCount, FloatDiv(float(iCTCount), float(iTCount)));
  1606. }
  1607. }
  1608. }
  1609. // Is the player in CT now?
  1610. // He joined last!
  1611. else if(client && IsClientInGame(client) && GetClientTeam(client) == CS_TEAM_CT)
  1612. {
  1613. g_iLastJoinedCT = client;
  1614. }
  1615. return Plugin_Stop;
  1616. }
  1617.  
  1618. // Make sure CTs have knifes
  1619. public Action:Timer_CheckCTHasKnife(Handle:timer, any:userid)
  1620. {
  1621. new client = GetClientOfUserId(userid);
  1622. if(!client)
  1623. return Plugin_Stop;
  1624.  
  1625. if(IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == CS_TEAM_CT)
  1626. {
  1627. new iWeapon = GetPlayerWeaponSlot(client, 2);
  1628. if(iWeapon == -1)
  1629. {
  1630. iWeapon = GivePlayerItem(client, "weapon_knife");
  1631. EquipPlayerWeapon(client, iWeapon);
  1632. }
  1633. }
  1634.  
  1635. return Plugin_Stop;
  1636. }
  1637.  
  1638. // Hide the radar again after flashing
  1639. public Action:Timer_FlashEnd(Handle:timer, any:userid)
  1640. {
  1641. new client = GetClientOfUserId(userid);
  1642.  
  1643. if (client && GetClientTeam(client) > 1)
  1644. {
  1645. SetEntDataFloat(client, g_flFlashDuration, 10000.0, true);
  1646. SetEntDataFloat(client, g_flFlashMaxAlpha, 0.5, true);
  1647. }
  1648.  
  1649. return Plugin_Stop;
  1650. }
  1651.  
  1652. /*
  1653. *
  1654. * Console Command Handling
  1655. *
  1656. */
  1657.  
  1658. // say /hide /hidemenu
  1659. public Action:Menu_SelectModel(client,args)
  1660. {
  1661. if (!g_bEnableHnS || g_hModelMenu[GetClientLanguageID(client)] == INVALID_HANDLE)
  1662. {
  1663. return Plugin_Handled;
  1664. }
  1665.  
  1666. if(GetClientTeam(client) == CS_TEAM_T)
  1667. {
  1668. new changeLimit = GetConVarInt(g_hCVChangeLimit);
  1669. if(g_bAllowModelChange[client] && (changeLimit == 0 || g_iModelChangeCount[client] < (changeLimit+1)))
  1670. {
  1671. if(GetConVarBool(g_hCVAutoChoose))
  1672. SetRandomModel(client);
  1673. else
  1674. DisplayMenu(g_hModelMenu[GetClientLanguageID(client)], client, RoundToFloor(GetConVarFloat(g_hCVChangeLimittime)));
  1675. }
  1676. else
  1677. PrintToChat(client, "%s%t", PREFIX, "Modelmenu Disabled");
  1678. }
  1679. else
  1680. {
  1681. PrintToChat(client, "%s%t", PREFIX, "Only terrorists can select models");
  1682. }
  1683. return Plugin_Handled;
  1684. }
  1685.  
  1686. // say /tp /third /thirdperson
  1687. public Action:Toggle_ThirdPerson(client, args)
  1688. {
  1689. if (!g_bEnableHnS || !IsClientInGame(client) || !IsPlayerAlive(client))
  1690. return Plugin_Handled;
  1691.  
  1692. // Only allow Terrorists to use thirdperson view
  1693. if(GetClientTeam(client) != CS_TEAM_T)
  1694. {
  1695. PrintToChat(client, "%s%t", PREFIX, "Only terrorists can use");
  1696. return Plugin_Handled;
  1697. }
  1698.  
  1699. if(!g_bInThirdPersonView[client])
  1700. {
  1701. SetThirdPersonView(client, true);
  1702. PrintToChat(client, "%s%t", PREFIX, "Type again for ego");
  1703. }
  1704. else
  1705. {
  1706. SetThirdPersonView(client, false);
  1707. // remove the roundtime message
  1708. new Handle:hBuffer = StartMessageOne("KeyHintText", client);
  1709. BfWriteByte(hBuffer, 1);
  1710. BfWriteString(hBuffer, "");
  1711. EndMessage();
  1712. }
  1713.  
  1714. return Plugin_Handled;
  1715. }
  1716.  
  1717. // say /+3rd
  1718. public Action:Enable_ThirdPerson(client, args)
  1719. {
  1720. if (!g_bEnableHnS || !IsClientInGame(client) || !IsPlayerAlive(client))
  1721. return Plugin_Handled;
  1722.  
  1723. // Only allow Terrorists to use thirdperson view
  1724. if(GetClientTeam(client) != CS_TEAM_T)
  1725. {
  1726. PrintToChat(client, "%s%t", PREFIX, "Only terrorists can use");
  1727. return Plugin_Handled;
  1728. }
  1729.  
  1730. if(!g_bInThirdPersonView[client])
  1731. {
  1732. SetThirdPersonView(client, true);
  1733. PrintToChat(client, "%s%t", PREFIX, "Type again for ego");
  1734. }
  1735.  
  1736. return Plugin_Handled;
  1737. }
  1738.  
  1739. // say /-3rd
  1740. public Action:Disable_ThirdPerson(client, args)
  1741. {
  1742. if (!g_bEnableHnS || !IsClientInGame(client) || !IsPlayerAlive(client))
  1743. return Plugin_Handled;
  1744.  
  1745. // Only allow Terrorists to use thirdperson view
  1746. if(GetClientTeam(client) != CS_TEAM_T)
  1747. {
  1748. PrintToChat(client, "%s%t", PREFIX, "Only terrorists can use");
  1749. return Plugin_Handled;
  1750. }
  1751.  
  1752. if(g_bInThirdPersonView[client])
  1753. {
  1754. SetThirdPersonView(client, false);
  1755. // remove the roundtime message
  1756. new Handle:hBuffer = StartMessageOne("KeyHintText", client);
  1757. BfWriteByte(hBuffer, 1);
  1758. BfWriteString(hBuffer, "");
  1759. EndMessage();
  1760. }
  1761.  
  1762. return Plugin_Handled;
  1763. }
  1764.  
  1765. // jointeam command
  1766. // handle the team sizes
  1767. public Action:Command_JoinTeam(client, args)
  1768. {
  1769. if (!g_bEnableHnS || !client || !IsClientInGame(client) || GetConVarFloat(g_hCVCTRatio) == 0.0)
  1770. {
  1771. return Plugin_Continue;
  1772. }
  1773.  
  1774. decl String:text[192];
  1775. if (!GetCmdArgString(text, sizeof(text)))
  1776. {
  1777. return Plugin_Continue;
  1778. }
  1779.  
  1780. StripQuotes(text);
  1781.  
  1782. // Player wants to join CT
  1783. if(strcmp(text, "3", false) == 0)
  1784. {
  1785. new iCTCount = GetTeamClientCount(CS_TEAM_CT);
  1786. new iTCount = GetTeamClientCount(CS_TEAM_T);
  1787.  
  1788. // This client would be in CT if we continue.
  1789. iCTCount++;
  1790.  
  1791. // And would leave T
  1792. if(GetClientTeam(client) == CS_TEAM_T)
  1793. iTCount--;
  1794.  
  1795. // Check, how many terrors are going to get switched to ct at the end of the round
  1796. for(new i=1;i<=MaxClients;i++)
  1797. {
  1798. if(g_bCTToSwitch[i])
  1799. {
  1800. iCTCount--;
  1801. iTCount++;
  1802. }
  1803. }
  1804.  
  1805. new Float:fRatio = FloatDiv(float(iCTCount), float(iTCount));
  1806.  
  1807. new Float:fCFGRatio = FloatDiv(1.0, GetConVarFloat(g_hCVCTRatio));
  1808.  
  1809. //PrintToServer("Debug: Player %N wants to join CT. CTCount: %d TCount: %d Ratio: %f", client, iCTCount, iTCount, FloatDiv(float(iCTCount), float(iTCount)));
  1810.  
  1811. // There are more CTs than we want in the CT team.
  1812. if(iCTCount > 1 && fRatio > fCFGRatio)
  1813. {
  1814. PrintCenterText(client, "CT team is full");
  1815. //PrintToServer("Debug: Blocked.");
  1816. return Plugin_Handled;
  1817. }
  1818. }
  1819.  
  1820. return Plugin_Continue;
  1821. }
  1822.  
  1823. // say /whistle
  1824. // plays a random sound loudly
  1825. public Action:Play_Whistle(client,args)
  1826. {
  1827. // check if whistling is enabled
  1828. if(!g_bEnableHnS || !GetConVarBool(g_hCVWhistle) || !IsPlayerAlive(client))
  1829. return Plugin_Handled;
  1830.  
  1831. // only Ts are allowed to whistle
  1832. if(GetClientTeam(client) != CS_TEAM_T)
  1833. {
  1834. PrintToChat(client, "%s%t", PREFIX, "Only terrorists can use");
  1835. return Plugin_Handled;
  1836. }
  1837.  
  1838. if(!g_bWhistlingAllowed)
  1839. {
  1840. PrintToChat(client, "%s%t", PREFIX, "Whistling not allowed yet");
  1841. return Plugin_Handled;
  1842. }
  1843.  
  1844. new cvarWhistleTimes = GetConVarInt(g_hCVWhistleTimes);
  1845.  
  1846. if(g_iWhistleCount[client] < cvarWhistleTimes)
  1847. {
  1848. EmitSoundToAll(whistle_sounds[GetRandomInt(0, sizeof(whistle_sounds)-1)], client, SNDCHAN_AUTO, SNDLEVEL_GUNFIRE);
  1849. PrintToChatAll("%s%N %t", PREFIX, client, "whistled");
  1850. g_iWhistleCount[client]++;
  1851. PrintToChat(client, "%s%t", PREFIX, "whistles left", (cvarWhistleTimes-g_iWhistleCount[client]));
  1852. }
  1853. else
  1854. {
  1855. PrintToChat(client, "%s%t", PREFIX, "whistle limit exceeded", cvarWhistleTimes);
  1856. }
  1857.  
  1858. return Plugin_Handled;
  1859. }
  1860. // say /whoami
  1861. // displays the model name in chat again
  1862. public Action:Display_ModelName(client,args)
  1863. {
  1864. // only enable command, if player already chose a model
  1865. if(!g_bEnableHnS || !IsPlayerAlive(client) || g_iModelChangeCount[client] == 0)
  1866. return Plugin_Handled;
  1867.  
  1868. // only Ts can use a model
  1869. if(GetClientTeam(client) != CS_TEAM_T)
  1870. {
  1871. PrintToChat(client, "%s%t", PREFIX, "Only terrorists can use");
  1872. return Plugin_Handled;
  1873. }
  1874.  
  1875. decl String:modelName[128], String:langCode[4];
  1876. GetClientModel(client, modelName, sizeof(modelName));
  1877.  
  1878. if (!KvGotoFirstSubKey(kv))
  1879. {
  1880. return Plugin_Handled;
  1881. }
  1882.  
  1883. decl String:name[30], String:path[100], String:fullPath[100];
  1884. do
  1885. {
  1886. KvGetSectionName(kv, path, sizeof(path));
  1887. FormatEx(fullPath, sizeof(fullPath), "models/%s.mdl", path);
  1888. if(StrEqual(fullPath, modelName))
  1889. {
  1890. GetClientLanguageID(client, langCode, sizeof(langCode));
  1891. KvGetString(kv, langCode, name, sizeof(name));
  1892. PrintToChat(client, "%s%t\x01 %s.", PREFIX, "Model Changed", name);
  1893. }
  1894. } while (KvGotoNextKey(kv));
  1895. KvRewind(kv);
  1896.  
  1897. return Plugin_Handled;
  1898. }
  1899.  
  1900.  
  1901. // say /hidehelp
  1902. // Show the help menu
  1903. public Action:Display_Help(client,args)
  1904. {
  1905. if(!g_bEnableHnS)
  1906. return Plugin_Handled;
  1907.  
  1908. new Handle:menu = CreateMenu(Menu_Help);
  1909.  
  1910. decl String:buffer[512];
  1911. Format(buffer, sizeof(buffer), "%T", "HnS Help", client);
  1912. SetMenuTitle(menu, buffer);
  1913. SetMenuExitButton(menu, true);
  1914.  
  1915. Format(buffer, sizeof(buffer), "%T", "Running HnS", client);
  1916. AddMenuItem(menu, "", buffer);
  1917.  
  1918. Format(buffer, sizeof(buffer), "%T", "Instructions 1", client);
  1919. AddMenuItem(menu, "", buffer);
  1920.  
  1921. AddMenuItem(menu, "", "", ITEMDRAW_SPACER);
  1922.  
  1923. Format(buffer, sizeof(buffer), "%T", "Available Commands", client);
  1924. AddMenuItem(menu, "1", buffer);
  1925.  
  1926. Format(buffer, sizeof(buffer), "%T", "Howto CT", client);
  1927. AddMenuItem(menu, "2", buffer);
  1928.  
  1929. Format(buffer, sizeof(buffer), "%T", "Howto T", client);
  1930. AddMenuItem(menu, "3", buffer);
  1931.  
  1932. DisplayMenu(menu, client, MENU_TIME_FOREVER);
  1933. return Plugin_Handled;
  1934. }
  1935.  
  1936. // say /freeze
  1937. // Freeze hiders in position
  1938. public Action:Freeze_Cmd(client,args)
  1939. {
  1940. if(!g_bEnableHnS || !GetConVarInt(g_hCVHiderFreezeMode) || GetClientTeam(client) != CS_TEAM_T || !IsPlayerAlive(client))
  1941. return Plugin_Handled;
  1942.  
  1943. if(g_bIsFreezed[client])
  1944. {
  1945. if(GetConVarInt(g_hCVHiderFreezeMode) == 1)
  1946. {
  1947. if(!g_bClientIsHigher[client])
  1948. SetEntityMoveType(client, MOVETYPE_WALK);
  1949. }
  1950. else
  1951. {
  1952. SetEntData(client, g_Freeze, FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND, 4, true);
  1953. if(!g_bClientIsHigher[client])
  1954. SetEntityMoveType(client, MOVETYPE_WALK);
  1955. }
  1956.  
  1957. g_bIsFreezed[client] = false;
  1958. PrintToChat(client, "%s%t", PREFIX, "Hider Unfreezed");
  1959. }
  1960. else if (GetConVarBool(g_hCVHiderFreezeInAir) || (GetEntityFlags(client) & FL_ONGROUND || g_bClientIsHigher[client])) // only allow freezing when being on the ground!
  1961. {
  1962. // Don't allow fixed models to freeze while being bugged
  1963. // Put him up before freezing
  1964. if(g_iFixedModelHeight[client] > 0.0 && !g_bClientIsHigher[client] && GetEntityFlags(client) & FL_ONGROUND)
  1965. {
  1966. new Float:vecClientOrigin[3];
  1967. GetClientAbsOrigin(client, vecClientOrigin);
  1968. vecClientOrigin[2] += g_iFixedModelHeight[client];
  1969. TeleportEntity(client, vecClientOrigin, NULL_VECTOR, NULL_VECTOR);
  1970. g_bClientIsHigher[client] = true;
  1971. }
  1972.  
  1973. if(GetConVarInt(g_hCVHiderFreezeMode) == 1)
  1974. SetEntityMoveType(client, MOVETYPE_NONE); // Still able to move camera
  1975. else
  1976. {
  1977. SetEntData(client, g_Freeze, FL_CLIENT|FL_ATCONTROLS, 4, true); // Can't move anything
  1978. SetEntityMoveType(client, MOVETYPE_NONE);
  1979. }
  1980.  
  1981. // Stop him
  1982. TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, Float:{0.0,0.0,0.0});
  1983.  
  1984. g_bIsFreezed[client] = true;
  1985. PrintToChat(client, "%s%t", PREFIX, "Hider Freezed");
  1986. }
  1987.  
  1988. return Plugin_Handled;
  1989. }
  1990.  
  1991. public Action:Block_Cmd(client,args)
  1992. {
  1993. // only block if anticheat is enabled
  1994. if(g_bEnableHnS && GetConVarBool(g_hCVAntiCheat))
  1995. return Plugin_Handled;
  1996. else
  1997. return Plugin_Continue;
  1998. }
  1999.  
  2000. // Admin Command
  2001. // sm_hns_force_whistle
  2002. // Forces a terrorist player to whistle
  2003. public Action:ForceWhistle(client, args)
  2004. {
  2005. if(!g_bEnableHnS || !GetConVarBool(g_hCVWhistle))
  2006. {
  2007. ReplyToCommand(client, "Disabled.");
  2008. return Plugin_Handled;
  2009. }
  2010.  
  2011. if(GetCmdArgs() < 1)
  2012. {
  2013. ReplyToCommand(client, "Usage: sm_hns_force_whistle <#userid|steamid|name>");
  2014. return Plugin_Handled;
  2015. }
  2016.  
  2017. decl String:player[70];
  2018. GetCmdArg(1, player, sizeof(player));
  2019.  
  2020. new target = FindTarget(client, player);
  2021. if(target == -1)
  2022. return Plugin_Handled;
  2023.  
  2024. if(GetClientTeam(target) == CS_TEAM_T && IsPlayerAlive(target))
  2025. {
  2026. EmitSoundToAll(whistle_sounds[GetRandomInt(0, sizeof(whistle_sounds)-1)], target, SNDCHAN_AUTO, SNDLEVEL_GUNFIRE);
  2027. PrintToChatAll("%s%N %t", PREFIX, target, "whistled");
  2028. }
  2029. else
  2030. {
  2031. ReplyToCommand(client, "Hide and Seek: %t", "Only terrorists can use");
  2032. }
  2033.  
  2034. return Plugin_Handled;
  2035. }
  2036.  
  2037. public Action:ReloadModels(client, args)
  2038. {
  2039. if(!g_bEnableHnS)
  2040. {
  2041. ReplyToCommand(client, "Disabled.");
  2042. return Plugin_Handled;
  2043. }
  2044.  
  2045. // reset the model menu
  2046. OnMapEnd();
  2047.  
  2048. // rebuild it
  2049. BuildMainMenu();
  2050.  
  2051. ReplyToCommand(client, "Hide and Seek: Reloaded config.");
  2052.  
  2053. return Plugin_Handled;
  2054. }
  2055.  
  2056.  
  2057. /*
  2058. *
  2059. * Menu Handler
  2060. *
  2061. */
  2062. public Menu_Group(Handle:menu, MenuAction:action, client, param2)
  2063. {
  2064. // make sure again, the player is a Terrorist
  2065. if(client > 0 && IsClientInGame(client) && GetClientTeam(client) == CS_TEAM_T && g_bAllowModelChange[client])
  2066. {
  2067. if (action == MenuAction_Select)
  2068. {
  2069. decl String:info[100], String:info2[100], String:sModelPath[100];
  2070. new bool:found = GetMenuItem(menu, param2, info, sizeof(info), _, info2, sizeof(info2));
  2071. if(found)
  2072. {
  2073.  
  2074. if(StrEqual(info, "random"))
  2075. {
  2076. SetRandomModel(client);
  2077. }
  2078. else
  2079. {
  2080. // Check for enough money
  2081. decl String:sTax[32];
  2082. new iPosition;
  2083. if((iPosition = StrContains(info, "||t_")) != -1)
  2084. {
  2085. new iAccountValue = GetEntData(client, g_iAccount);
  2086.  
  2087. // Stupid string information storage-.-
  2088. new iPosition2 = StrContains(info[iPosition+4], "||hi_");
  2089. if(iPosition2 != -1)
  2090. strcopy(sTax, iPosition2-iPosition+3, info[iPosition+4]);
  2091. else
  2092. strcopy(sTax, sizeof(sTax), info[iPosition+4]);
  2093.  
  2094. new iTax = StringToInt(sTax);
  2095. // He doesn't have enough money?
  2096. if(iTax > iAccountValue)
  2097. {
  2098. PrintToChat(client, "%s%t", PREFIX, "not enough money");
  2099. // Show the menu again
  2100. Menu_SelectModel(client, 0);
  2101. return;
  2102. }
  2103.  
  2104. // Get the money
  2105. SetEntData(client, g_iAccount, (iAccountValue - iTax), 4, true);
  2106.  
  2107. PrintToChat(client, "%s%t", PREFIX, "tax charged", iTax);
  2108. }
  2109.  
  2110. // Put him down before changing the model again
  2111. if(g_bClientIsHigher[client])
  2112. {
  2113. new Float:vecClientOrigin[3];
  2114. GetClientAbsOrigin(client, vecClientOrigin);
  2115. vecClientOrigin[2] -= g_iFixedModelHeight[client];
  2116. TeleportEntity(client, vecClientOrigin, NULL_VECTOR, NULL_VECTOR);
  2117. SetEntityMoveType(client, MOVETYPE_WALK);
  2118. g_bClientIsHigher[client] = false;
  2119. }
  2120.  
  2121. // Modelheight fix
  2122. if((iPosition = StrContains(info, "||hi_")) != -1)
  2123. {
  2124. g_iFixedModelHeight[client] = StringToFloat(info[iPosition+5]);
  2125. PrintToChat(client, "%s%t", PREFIX, "is heightfixed");
  2126. }
  2127. else
  2128. {
  2129. g_iFixedModelHeight[client] = 0.0;
  2130. }
  2131.  
  2132. if(SplitString(info, "||", sModelPath, sizeof(sModelPath)) == -1)
  2133. strcopy(sModelPath, sizeof(sModelPath), info);
  2134.  
  2135. SetEntityModel(client, sModelPath);
  2136. PrintToChat(client, "%s%t \x01%s.", PREFIX, "Model Changed", info2);
  2137. }
  2138. g_iModelChangeCount[client]++;
  2139. }
  2140. } else if(action == MenuAction_Cancel)
  2141. {
  2142. PrintToChat(client, "%s%t", PREFIX, "Type !hide");
  2143. }
  2144.  
  2145. // display the help menu afterwards on first spawn
  2146. if(GetConVarBool(g_hCVShowHideHelp) && g_bFirstSpawn[client])
  2147. {
  2148. Display_Help(client, 0);
  2149. g_bFirstSpawn[client] = false;
  2150. }
  2151. }
  2152. }
  2153.  
  2154. // Display the different help menus
  2155. public Menu_Help(Handle:menu, MenuAction:action, param1, param2)
  2156. {
  2157. if (action == MenuAction_Select)
  2158. {
  2159. new String:info[32];
  2160. GetMenuItem(menu, param2, info, sizeof(info));
  2161. new iInfo = StringToInt(info);
  2162. switch(iInfo)
  2163. {
  2164. case 1:
  2165. {
  2166. // Available Commands
  2167. new Handle:menu2 = CreateMenu(Menu_Dummy);
  2168. decl String:buffer[512];
  2169. Format(buffer, sizeof(buffer), "%T", "Available Commands", param1);
  2170. SetMenuTitle(menu2, buffer);
  2171. SetMenuExitBackButton(menu2, true);
  2172.  
  2173. Format(buffer, sizeof(buffer), "/hide, /hidemenu - %T", "cmd hide", param1);
  2174. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2175. Format(buffer, sizeof(buffer), "/tp, /third, /thirdperson - %T", "cmd tp", param1);
  2176. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2177. if(GetConVarBool(g_hCVWhistle))
  2178. {
  2179. Format(buffer, sizeof(buffer), "/whistle - %T", "cmd whistle", param1);
  2180. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2181. }
  2182. if(GetConVarInt(g_hCVHiderFreezeMode))
  2183. {
  2184. Format(buffer, sizeof(buffer), "/freeze - %T", "cmd freeze", param1);
  2185. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2186. }
  2187. Format(buffer, sizeof(buffer), "/whoami - %T", "cmd whoami", param1);
  2188. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2189. Format(buffer, sizeof(buffer), "/hidehelp - %T", "cmd hidehelp", param1);
  2190. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2191.  
  2192. DisplayMenu(menu2, param1, MENU_TIME_FOREVER);
  2193. }
  2194. case 2:
  2195. {
  2196. // Howto CT
  2197. new Handle:menu2 = CreateMenu(Menu_Dummy);
  2198. decl String:buffer[512];
  2199. Format(buffer, sizeof(buffer), "%T", "Howto CT", param1);
  2200. SetMenuTitle(menu2, buffer);
  2201. SetMenuExitBackButton(menu2, true);
  2202.  
  2203. Format(buffer, sizeof(buffer), "%T", "Instructions CT 1", param1);
  2204. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2205.  
  2206. AddMenuItem(menu2, "", "", ITEMDRAW_SPACER);
  2207.  
  2208. Format(buffer, sizeof(buffer), "%T", "Instructions CT 2", param1, GetConVarInt(g_hCVHPSeekerDec));
  2209. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2210.  
  2211. Format(buffer, sizeof(buffer), "%T", "Instructions CT 3", param1, GetConVarInt(g_hCVHPSeekerInc), GetConVarInt(g_hCVHPSeekerBonus));
  2212. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2213.  
  2214. DisplayMenu(menu2, param1, MENU_TIME_FOREVER);
  2215. }
  2216. case 3:
  2217. {
  2218. // Howto T
  2219. new Handle:menu2 = CreateMenu(Menu_Dummy);
  2220. decl String:buffer[512];
  2221. Format(buffer, sizeof(buffer), "%T", "Howto T", param1);
  2222. SetMenuTitle(menu2, buffer);
  2223. SetMenuExitBackButton(menu2, true);
  2224.  
  2225. Format(buffer, sizeof(buffer), "%T", "Instructions T 1", param1);
  2226. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2227.  
  2228. Format(buffer, sizeof(buffer), "%T", "Instructions T 2", param1);
  2229. AddMenuItem(menu2, "", buffer, ITEMDRAW_DISABLED);
  2230.  
  2231. DisplayMenu(menu2, param1, MENU_TIME_FOREVER);
  2232. }
  2233. }
  2234. }
  2235. else if (action == MenuAction_End)
  2236. {
  2237. CloseHandle(menu);
  2238. }
  2239. }
  2240.  
  2241. public Menu_Dummy(Handle:menu, MenuAction:action, param1, param2)
  2242. {
  2243. if (action == MenuAction_Cancel && param2 != MenuCancel_Exit)
  2244. {
  2245. if(IsClientInGame(param1))
  2246. Display_Help(param1, 0);
  2247. }
  2248. else if (action == MenuAction_End)
  2249. {
  2250. CloseHandle(menu);
  2251. }
  2252. }
  2253.  
  2254. /*
  2255. *
  2256. * Helper Functions
  2257. *
  2258. */
  2259.  
  2260. // read the hide_and_seek map config
  2261. // add all models to the menus according to the language
  2262. BuildMainMenu()
  2263. {
  2264. g_iTotalModelsAvailable = 0;
  2265.  
  2266. kv = CreateKeyValues("Models");
  2267. new String:file[256], String:map[64], String:title[64], String:finalOutput[100];
  2268. GetCurrentMap(map, sizeof(map));
  2269. BuildPath(Path_SM, file, 255, "configs/hide_and_seek/maps/%s.cfg", map);
  2270. FileToKeyValues(kv, file);
  2271.  
  2272. if (!KvGotoFirstSubKey(kv))
  2273. {
  2274. SetFailState("Can't parse modelconfig file for map %s.", map);
  2275. return;
  2276. }
  2277.  
  2278. decl String:name[30];
  2279. decl String:lang[4];
  2280. decl String:path[100];
  2281. new langID, nextLangID = -1;
  2282. do
  2283. {
  2284. // get the model path and precache it
  2285. KvGetSectionName(kv, path, sizeof(path));
  2286. FormatEx(finalOutput, sizeof(finalOutput), "models/%s.mdl", path);
  2287. PrecacheModel(finalOutput, true);
  2288.  
  2289. // Check for heightfixed models
  2290. decl String:sHeightFix[32];
  2291. KvGetString(kv, "heightfix", sHeightFix, sizeof(sHeightFix), "noo");
  2292. if(!StrEqual(sHeightFix, "noo"))
  2293. {
  2294. Format(finalOutput, sizeof(finalOutput), "%s||hi_%s", finalOutput, sHeightFix);
  2295. }
  2296.  
  2297. // Check for tax
  2298. decl String:sTax[32];
  2299. KvGetString(kv, "tax", sTax, sizeof(sTax), "noo");
  2300. if(!StrEqual(sTax, "noo"))
  2301. {
  2302. Format(finalOutput, sizeof(finalOutput), "%s||t_%s", finalOutput, sTax);
  2303. }
  2304.  
  2305. // roll through all available languages
  2306. for(new i=0;i<GetLanguageCount();i++)
  2307. {
  2308. GetLanguageInfo(i, lang, sizeof(lang));
  2309. // search for the translation
  2310. KvGetString(kv, lang, name, sizeof(name));
  2311. if(strlen(name) > 0)
  2312. {
  2313. // Show the tax
  2314. if(!StrEqual(sTax, "noo"))
  2315. Format(name, sizeof(name), "%s ($%d)", name, StringToInt(sTax));
  2316.  
  2317. // language already in array, only in the wrong order in the file?
  2318. langID = GetLanguageID(lang);
  2319.  
  2320. // language new?
  2321. if(langID == -1)
  2322. {
  2323. nextLangID = GetNextLangID();
  2324. g_sModelMenuLanguage[nextLangID] = lang;
  2325. }
  2326.  
  2327. if(langID == -1 && g_hModelMenu[nextLangID] == INVALID_HANDLE)
  2328. {
  2329. // new language, create the menu
  2330. g_hModelMenu[nextLangID] = CreateMenu(Menu_Group);
  2331. Format(title, sizeof(title), "%T:", "Title Select Model", LANG_SERVER);
  2332.  
  2333. SetMenuTitle(g_hModelMenu[nextLangID], title);
  2334. SetMenuExitButton(g_hModelMenu[nextLangID], true);
  2335.  
  2336. // Add random option
  2337. Format(title, sizeof(title), "%T", "random", LANG_SERVER);
  2338. AddMenuItem(g_hModelMenu[nextLangID], "random", title);
  2339. }
  2340.  
  2341. // add it to the menu
  2342. if(langID == -1)
  2343. AddMenuItem(g_hModelMenu[nextLangID], finalOutput, name);
  2344. else
  2345. AddMenuItem(g_hModelMenu[langID], finalOutput, name);
  2346. }
  2347.  
  2348. }
  2349.  
  2350. g_iTotalModelsAvailable++;
  2351. } while (KvGotoNextKey(kv));
  2352. KvRewind(kv);
  2353.  
  2354. if (g_iTotalModelsAvailable == 0)
  2355. {
  2356. SetFailState("No models parsed in %s.cfg", map);
  2357. return;
  2358. }
  2359. }
  2360.  
  2361. GetLanguageID(const String:langCode[])
  2362. {
  2363. for(new i=0;i<MAX_LANGUAGES;i++)
  2364. {
  2365. if(StrEqual(g_sModelMenuLanguage[i], langCode))
  2366. return i;
  2367. }
  2368. return -1;
  2369. }
  2370.  
  2371. GetClientLanguageID(client, String:languageCode[]="", maxlen=0)
  2372. {
  2373. decl String:langCode[4];
  2374. GetLanguageInfo(GetClientLanguage(client), langCode, sizeof(langCode));
  2375. // is client's prefered language available?
  2376. new langID = GetLanguageID(langCode);
  2377. if(langID != -1)
  2378. {
  2379. strcopy(languageCode, maxlen, langCode);
  2380. return langID; // yes.
  2381. }
  2382. else
  2383. {
  2384. GetLanguageInfo(GetServerLanguage(), langCode, sizeof(langCode));
  2385. // is default server language available?
  2386. langID = GetLanguageID(langCode);
  2387. if(langID != -1)
  2388. {
  2389. strcopy(languageCode, maxlen, langCode);
  2390. return langID; // yes.
  2391. }
  2392. else
  2393. {
  2394. // default to english
  2395. for(new i=0;i<MAX_LANGUAGES;i++)
  2396. {
  2397. if(StrEqual(g_sModelMenuLanguage[i], "en"))
  2398. {
  2399. strcopy(languageCode, maxlen, "en");
  2400. return i;
  2401. }
  2402. }
  2403.  
  2404. // english not found? happens on custom map configs e.g.
  2405. // use the first language available
  2406. // this should always work, since we would have SetFailState() on parse
  2407. if(strlen(g_sModelMenuLanguage[0]) > 0)
  2408. {
  2409. strcopy(languageCode, maxlen, g_sModelMenuLanguage[0]);
  2410. return 0;
  2411. }
  2412. }
  2413. }
  2414. // this should never happen
  2415. return -1;
  2416. }
  2417.  
  2418. GetNextLangID()
  2419. {
  2420. for(new i=0;i<MAX_LANGUAGES;i++)
  2421. {
  2422. if(strlen(g_sModelMenuLanguage[i]) == 0)
  2423. return i;
  2424. }
  2425. SetFailState("Can't handle more than %d languages. Increase MAX_LANGUAGES and recompile.", MAX_LANGUAGES);
  2426. return -1;
  2427. }
  2428.  
  2429. // Check if a player has a bad convar value set
  2430. bool:IsConVarCheater(client)
  2431. {
  2432. for(new i=0;i<sizeof(cheat_commands);i++)
  2433. {
  2434. if(g_bConVarViolation[client][i])
  2435. {
  2436. return true;
  2437. }
  2438. }
  2439. return false;
  2440. }
  2441.  
  2442. // Fade a players screen to black (amount=0) or removes the fade (amount=255)
  2443. PerformBlind(client, amount)
  2444. {
  2445. new Handle:message = StartMessageOne("Fade", client);
  2446. BfWriteShort(message, 1536);
  2447. BfWriteShort(message, 1536);
  2448.  
  2449. if (amount == 0)
  2450. {
  2451. BfWriteShort(message, 0x0010);
  2452. }
  2453. else
  2454. {
  2455. BfWriteShort(message, 0x0008);
  2456. }
  2457.  
  2458. BfWriteByte(message, 0);
  2459. BfWriteByte(message, 0);
  2460. BfWriteByte(message, 0);
  2461. BfWriteByte(message, amount);
  2462. EndMessage();
  2463. }
  2464.  
  2465. // set a random model to a client
  2466. SetRandomModel(client)
  2467. {
  2468. // give him a random one.
  2469. decl String:ModelPath[80], String:finalPath[100], String:ModelName[60];
  2470. decl String:langCode[4], String:sHeightFix[35], String:sTax[32];
  2471. new RandomNumber = GetRandomInt(0, g_iTotalModelsAvailable-1);
  2472. new currentI = 0;
  2473. new iTax;
  2474. new iAccountValue = GetEntData(client, g_iAccount);
  2475. new bool:bUseTaxedInRandom = GetConVarBool(g_hCVUseTaxedInRandom);
  2476. KvGotoFirstSubKey(kv);
  2477. do
  2478. {
  2479. if(currentI == RandomNumber)
  2480. {
  2481. // Check for enough money
  2482. KvGetString(kv, "tax", sTax, sizeof(sTax), "noo");
  2483. if(!StrEqual(sTax, "noo"))
  2484. {
  2485. iTax = StringToInt(sTax);
  2486. // He doesn't have enough money? skip this one
  2487. if(!bUseTaxedInRandom || iTax > iAccountValue)
  2488. continue;
  2489.  
  2490. // Get the money
  2491. SetEntData(client, g_iAccount, iAccountValue - iTax, 4, true);
  2492.  
  2493. PrintToChat(client, "%s%t", PREFIX, "tax charged", iTax);
  2494. }
  2495.  
  2496. // set the model
  2497. KvGetSectionName(kv, ModelPath, sizeof(ModelPath));
  2498.  
  2499. FormatEx(finalPath, sizeof(finalPath), "models/%s.mdl", ModelPath);
  2500.  
  2501. // Put him down before changing the model again
  2502. if(g_bClientIsHigher[client])
  2503. {
  2504. new Float:vecClientOrigin[3];
  2505. GetClientAbsOrigin(client, vecClientOrigin);
  2506. vecClientOrigin[2] -= g_iFixedModelHeight[client];
  2507. TeleportEntity(client, vecClientOrigin, NULL_VECTOR, NULL_VECTOR);
  2508. SetEntityMoveType(client, MOVETYPE_WALK);
  2509. g_bClientIsHigher[client] = false;
  2510. }
  2511.  
  2512. SetEntityModel(client, finalPath);
  2513.  
  2514. // Check for heightfixed models
  2515. KvGetString(kv, "heightfix", sHeightFix, sizeof(sHeightFix), "noo");
  2516. if(!StrEqual(sHeightFix, "noo"))
  2517. {
  2518. g_iFixedModelHeight[client] = StringToFloat(sHeightFix);
  2519. PrintToChat(client, "%s%t", PREFIX, "is heightfixed");
  2520. }
  2521. else
  2522. {
  2523. g_iFixedModelHeight[client] = 0.0;
  2524. }
  2525.  
  2526. if(!IsFakeClient(client))
  2527. {
  2528. // print name in chat
  2529. GetClientLanguageID(client, langCode, sizeof(langCode));
  2530. KvGetString(kv, langCode, ModelName, sizeof(ModelName));
  2531. PrintToChat(client, "%s%t \x01%s.", PREFIX, "Model Changed", ModelName);
  2532. }
  2533. break;
  2534. }
  2535. currentI++;
  2536. } while (KvGotoNextKey(kv));
  2537.  
  2538. KvRewind(kv);
  2539. g_iModelChangeCount[client]++;
  2540.  
  2541. // display the help menu afterwards on first spawn
  2542. if(GetConVarBool(g_hCVShowHideHelp) && g_bFirstSpawn[client])
  2543. {
  2544. Display_Help(client, 0);
  2545. g_bFirstSpawn[client] = false;
  2546. }
  2547. }
  2548.  
  2549. bool:SetThirdPersonView(client, bool:third)
  2550. {
  2551. if(third && !g_bInThirdPersonView[client])
  2552. {
  2553. SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", 0);
  2554. SetEntProp(client, Prop_Send, "m_iObserverMode", 1);
  2555. SetEntProp(client, Prop_Send, "m_bDrawViewmodel", 0);
  2556. SetEntProp(client, Prop_Send, "m_iFOV", 120);
  2557. g_bInThirdPersonView[client] = true;
  2558. return true;
  2559. }
  2560. else if(!third && g_bInThirdPersonView[client])
  2561. {
  2562. SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", -1);
  2563. SetEntProp(client, Prop_Send, "m_iObserverMode", 0);
  2564. SetEntProp(client, Prop_Send, "m_bDrawViewmodel", 1);
  2565. SetEntProp(client, Prop_Send, "m_iFOV", 90);
  2566. g_bInThirdPersonView[client] = false;
  2567. return true;
  2568. }
  2569. return false;
  2570. }
  2571.  
  2572. stock StripPlayerWeapons(client)
  2573. {
  2574. new iWeapon = -1;
  2575. for(new i=CS_SLOT_PRIMARY;i<=CS_SLOT_C4;i++)
  2576. {
  2577. while((iWeapon = GetPlayerWeaponSlot(client, i)) != -1)
  2578. {
  2579. RemovePlayerItem(client, iWeapon);
  2580. RemoveEdict(iWeapon);
  2581. }
  2582. }
  2583. }
  2584.  
  2585. /*
  2586. *
  2587. * Handle ConVars
  2588. *
  2589. */
  2590. // Monitor the protected cvars and... well protect them ;)
  2591. public OnCvarChange(Handle:convar, const String:oldValue[], const String:newValue[])
  2592. {
  2593. if(!g_bEnableHnS)
  2594. return;
  2595.  
  2596. decl String:cvarName[50];
  2597. GetConVarName(convar, cvarName, sizeof(cvarName));
  2598. for(new i=0;i<sizeof(protected_cvars);i++)
  2599. {
  2600. if(StrEqual(protected_cvars[i], cvarName) && StringToInt(newValue) != forced_values[i])
  2601. {
  2602. SetConVarInt(convar, forced_values[i]);
  2603. PrintToServer("Hide and Seek: %T", "protected cvar", LANG_SERVER);
  2604. break;
  2605. }
  2606. }
  2607. }
  2608.  
  2609. // directly change the hider speed on change
  2610. public OnChangeHiderSpeed(Handle:convar, const String:oldValue[], const String:newValue[])
  2611. {
  2612. if(!g_bEnableHnS)
  2613. return;
  2614.  
  2615. for(new i=1;i<=MaxClients;i++)
  2616. {
  2617. if(IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == CS_TEAM_T)
  2618. SetEntDataFloat(i, g_flLaggedMovementValue, GetConVarFloat(g_hCVHiderSpeed), true);
  2619. }
  2620. }
  2621.  
  2622. // directly change the hider speed on change
  2623. public OnChangeAntiCheat(Handle:convar, const String:oldValue[], const String:newValue[])
  2624. {
  2625. if(!g_bEnableHnS)
  2626. return;
  2627.  
  2628. if(StrEqual(oldValue, newValue))
  2629. return;
  2630.  
  2631. // disable anticheat
  2632. if(StrEqual(newValue, "0"))
  2633. {
  2634. for(new i=1;i<=MaxClients;i++)
  2635. {
  2636. if(IsClientInGame(i) && !IsFakeClient(i))
  2637. {
  2638. if(g_hCheckVarTimer[i] != INVALID_HANDLE)
  2639. {
  2640. KillTimer(g_hCheckVarTimer[i]);
  2641. g_hCheckVarTimer[i] = INVALID_HANDLE;
  2642. }
  2643. if(g_hCheatPunishTimer[i] != INVALID_HANDLE)
  2644. {
  2645. KillTimer(g_hCheatPunishTimer[i]);
  2646. g_hCheatPunishTimer[i] = INVALID_HANDLE;
  2647. }
  2648. }
  2649. }
  2650. }
  2651. // enable anticheat
  2652. else if(StrEqual(newValue, "1"))
  2653. {
  2654. for(new i=1;i<=MaxClients;i++)
  2655. {
  2656. if(IsClientInGame(i) && !IsFakeClient(i) && g_hCheckVarTimer[i] == INVALID_HANDLE)
  2657. {
  2658. g_hCheckVarTimer[i] = CreateTimer(1.0, StartVarChecker, i, TIMER_REPEAT);
  2659. }
  2660. }
  2661. }
  2662. }
  2663.  
  2664. // disable/enable plugin and restart round
  2665. public RestartGame(Handle:convar, const String:oldValue[], const String:newValue[])
  2666. {
  2667. if(!g_bEnableHnS)
  2668. return;
  2669.  
  2670. // don't execute if it's unchanged
  2671. if(StrEqual(oldValue, newValue))
  2672. return;
  2673.  
  2674. // disable - it's been enabled before.
  2675. if(!StrEqual(newValue, "0"))
  2676. {
  2677. // round has ended. used to not decrease seekers hp on shoot
  2678. g_bRoundEnded = true;
  2679.  
  2680. g_iFirstCTSpawn = 0;
  2681. g_iFirstTSpawn = 0;
  2682.  
  2683. if(g_hShowCountdownTimer != INVALID_HANDLE)
  2684. {
  2685. KillTimer(g_hShowCountdownTimer);
  2686. g_hShowCountdownTimer = INVALID_HANDLE;
  2687. }
  2688.  
  2689. if(g_hRoundTimeTimer != INVALID_HANDLE)
  2690. {
  2691. KillTimer(g_hRoundTimeTimer);
  2692. g_hRoundTimeTimer = INVALID_HANDLE;
  2693. }
  2694.  
  2695. if(g_hWhistleDelay != INVALID_HANDLE)
  2696. {
  2697. KillTimer(g_hWhistleDelay);
  2698. g_hWhistleDelay = INVALID_HANDLE;
  2699. }
  2700.  
  2701. // Switch the flagged players to CT
  2702. CreateTimer(0.1, Timer_SwitchTeams, _, TIMER_FLAG_NO_MAPCHANGE);
  2703. }
  2704. }
  2705. // disable/enable plugin and restart round
  2706. public Cfg_OnChangeEnable(Handle:convar, const String:oldValue[], const String:newValue[])
  2707. {
  2708. // don't execute if it's unchanged
  2709. if(StrEqual(oldValue, newValue))
  2710. return;
  2711.  
  2712. // disable - it's been enabled before.
  2713. if(StrEqual(newValue, "0"))
  2714. {
  2715. UnhookConVarChange(g_hCVAntiCheat, OnChangeAntiCheat);
  2716. UnhookConVarChange(g_hCVHiderSpeed, OnChangeHiderSpeed);
  2717.  
  2718. // Unhooking events
  2719. UnhookEvent("player_spawn", Event_OnPlayerSpawn);
  2720. UnhookEvent("weapon_fire", Event_OnWeaponFire);
  2721. UnhookEvent("player_death", Event_OnPlayerDeath);
  2722. UnhookEvent("player_blind", Event_OnPlayerBlind);
  2723. UnhookEvent("round_start", Event_OnRoundStart);
  2724. UnhookEvent("round_end", Event_OnRoundEnd);
  2725. UnhookEvent("player_team", Event_OnPlayerTeam);
  2726. UnhookEvent("item_pickup", Event_OnItemPickup);
  2727.  
  2728. // unprotect the cvars
  2729. for(new i=0;i<sizeof(protected_cvars);i++)
  2730. {
  2731. // reset old cvar values
  2732. UnhookConVarChange(g_hProtectedConvar[i], OnCvarChange);
  2733. SetConVarInt(g_hProtectedConvar[i], previous_values[i], true);
  2734. }
  2735.  
  2736. // stop advertising spam
  2737. if(g_hSpamCommandsTimer != INVALID_HANDLE)
  2738. {
  2739. KillTimer(g_hSpamCommandsTimer);
  2740. g_hSpamCommandsTimer = INVALID_HANDLE;
  2741. }
  2742.  
  2743. // stop countdown
  2744. if(g_hShowCountdownTimer != INVALID_HANDLE)
  2745. {
  2746. KillTimer(g_hShowCountdownTimer);
  2747. g_hShowCountdownTimer = INVALID_HANDLE;
  2748. }
  2749.  
  2750. // stop roundtime counter
  2751. if(g_hRoundTimeTimer != INVALID_HANDLE)
  2752. {
  2753. KillTimer(g_hRoundTimeTimer);
  2754. g_hRoundTimeTimer = INVALID_HANDLE;
  2755. }
  2756.  
  2757. // close handles
  2758. if(kv != INVALID_HANDLE)
  2759. CloseHandle(kv);
  2760. for(new i=0;i<MAX_LANGUAGES;i++)
  2761. {
  2762. if(g_hModelMenu[i] != INVALID_HANDLE)
  2763. {
  2764. CloseHandle(g_hModelMenu[i]);
  2765. g_hModelMenu[i] = INVALID_HANDLE;
  2766. }
  2767. Format(g_sModelMenuLanguage[i], 4, "");
  2768. }
  2769.  
  2770. for(new c=1;c<=MaxClients;c++)
  2771. {
  2772. if(!IsClientInGame(c))
  2773. continue;
  2774.  
  2775. // stop cheat checking
  2776. if(!IsFakeClient(c))
  2777. {
  2778. if(g_hCheckVarTimer[c] != INVALID_HANDLE)
  2779. {
  2780. KillTimer(g_hCheckVarTimer[c]);
  2781. g_hCheckVarTimer[c] = INVALID_HANDLE;
  2782. }
  2783. if(g_hCheatPunishTimer[c] != INVALID_HANDLE)
  2784. {
  2785. KillTimer(g_hCheatPunishTimer[c]);
  2786. g_hCheatPunishTimer[c] = INVALID_HANDLE;
  2787. }
  2788. }
  2789.  
  2790. // Unhook weapon pickup
  2791. SDKUnhook(c, SDKHook_WeaponCanUse, OnWeaponCanUse);
  2792.  
  2793. // Unhook attacking
  2794. SDKUnhook(c, SDKHook_TraceAttack, OnTraceAttack);
  2795.  
  2796. // reset every players vars
  2797. OnClientDisconnect(c);
  2798. }
  2799.  
  2800. g_bEnableHnS = false;
  2801. // restart game to reset the models and scores
  2802. ServerCommand("mp_restartgame 1");
  2803. }
  2804. else if(StrEqual(newValue, "1"))
  2805. {
  2806. // hook the convars again
  2807. HookConVarChange(g_hCVHiderSpeed, OnChangeHiderSpeed);
  2808. HookConVarChange(g_hCVAntiCheat, OnChangeAntiCheat);
  2809.  
  2810. // Hook events again
  2811. HookEvent("player_spawn", Event_OnPlayerSpawn);
  2812. HookEvent("weapon_fire", Event_OnWeaponFire);
  2813. HookEvent("player_death", Event_OnPlayerDeath);
  2814. HookEvent("player_blind", Event_OnPlayerBlind);
  2815. HookEvent("round_start", Event_OnRoundStart);
  2816. HookEvent("round_end", Event_OnRoundEnd);
  2817. HookEvent("player_team", Event_OnPlayerTeam);
  2818. HookEvent("item_pickup", Event_OnItemPickup);
  2819.  
  2820. // set bad server cvars
  2821. for(new i=0;i<sizeof(protected_cvars);i++)
  2822. {
  2823. g_hProtectedConvar[i] = FindConVar(protected_cvars[i]);
  2824. previous_values[i] = GetConVarInt(g_hProtectedConvar[i]);
  2825. SetConVarInt(g_hProtectedConvar[i], forced_values[i], true);
  2826. HookConVarChange(g_hProtectedConvar[i], OnCvarChange);
  2827. }
  2828. // start advertising spam
  2829. g_hSpamCommandsTimer = CreateTimer(120.0, SpamCommands, 0);
  2830.  
  2831. for(new c=1;c<=MaxClients;c++)
  2832. {
  2833. if(!IsClientInGame(c))
  2834. continue;
  2835.  
  2836. // start cheat checking
  2837. if(!IsFakeClient(c) && GetConVarBool(g_hCVAntiCheat) && g_hCheckVarTimer[c] == INVALID_HANDLE)
  2838. {
  2839. g_hCheckVarTimer[c] = CreateTimer(1.0, StartVarChecker, c, TIMER_REPEAT);
  2840. }
  2841.  
  2842. // Hook weapon pickup
  2843. SDKHook(c, SDKHook_WeaponCanUse, OnWeaponCanUse);
  2844.  
  2845. // Hook attack to hide blood
  2846. SDKHook(c, SDKHook_TraceAttack, OnTraceAttack);
  2847. }
  2848.  
  2849. g_bEnableHnS = true;
  2850. // build the menu and setup the hostage_rescue zone
  2851. OnMapStart();
  2852.  
  2853. // restart game to reset the models and scores
  2854. ServerCommand("mp_restartgame 1");
  2855. }
  2856. }
  2857.  
  2858. // check the given cheat cvars on every client
  2859. public ClientConVar(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])
  2860. {
  2861. if(!IsClientInGame(client))
  2862. return;
  2863.  
  2864. new bool:match = StrEqual(cvarValue, "0");
  2865.  
  2866. for(new i=0;i<sizeof(cheat_commands);i++)
  2867. {
  2868. if(!StrEqual(cheat_commands[i], cvarName))
  2869. continue;
  2870.  
  2871. if(!match)
  2872. {
  2873. g_bConVarViolation[client][i] = true;
  2874. // only spam the message every 5 checks
  2875. if(g_iConVarMessage[client][i] == 0)
  2876. {
  2877. PrintToChat(client, "%s%t\x04 %s 0", PREFIX, "Print to console", cvarName);
  2878. PrintHintText(client, "%t %s 0", "Print to console", cvarName);
  2879. }
  2880. g_iConVarMessage[client][i]++;
  2881. if(g_iConVarMessage[client][i] > 5)
  2882. g_iConVarMessage[client][i] = 0;
  2883. }
  2884. else
  2885. g_bConVarViolation[client][i] = false;
  2886. }
  2887. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement