Advertisement
Azelphur

Untitled

Jun 26th, 2011
498
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 64.50 KB | None | 0 0
  1. //  PropHunt by Darkimmortal
  2. //   - GamingMasters.co.uk -
  3.  
  4. #pragma semicolon 1
  5. #include <sourcemod>
  6. #include <sdktools>
  7. #include <tf2>
  8. #include <tf2_stocks>
  9. #include <sdkhooks>
  10.  
  11. #define PL_VERSION "1.7.14"
  12. //--------------------------------------------------------------------------------------------------------------------------------
  13. //-------------------------------------------- MAIN PROPHUNT CONFIGURATION -------------------------------------------------------
  14. //--------------------------------------------------------------------------------------------------------------------------------
  15.  
  16. // Enable for global stats support (.inc file available on request due to potential for cheating and database abuse)
  17. // Default: OFF
  18. //#define STATS
  19.  
  20. // Give last prop a scattergun and apply jarate to all pyros on last prop alive
  21. // Default: ON
  22. #define SCATTERGUN
  23.  
  24. // Prop Lock/Unlock sounds
  25. // Default: ON
  26. #define LOCKSOUND
  27.  
  28. // Extra classes
  29. // Default: ON
  30. #define SHINX
  31.  
  32. // Event and query logging for debugging purposes
  33. // Default: OFF
  34. //#define LOG
  35.  
  36. // Allow props to Targe Charge with enemy collisions disabled by pressing reload - pretty shit tbh.
  37. // Default: OFF
  38. //#define CHARGE
  39.  
  40. // Max ammo in Pyro shotgun
  41. // Default: 2
  42. #define SHOTGUN_MAX_AMMO 2
  43.  
  44. // Airblast permitted
  45. // Default: NO
  46. //#define AIRBLAST
  47.  
  48. // Anti-exploit system
  49. // Default: ON
  50. #define ANTIHACK
  51.  
  52. //--------------------------------------------------------------------------------------------------------------------------------
  53. //--------------------------------------------------------------------------------------------------------------------------------
  54. //--------------------------------------------------------------------------------------------------------------------------------
  55.  
  56. #define TEAM_BLUE 3
  57. #define TEAM_RED 2
  58. #define TEAM_SPEC 1
  59. #define TEAM_UNASSIGNED 0
  60.  
  61. #define SOUND_BEGIN "vo/announcer_am_gamestarting04.wav"
  62. #define SOUND_LASTPLAYER "vo/announcer_am_lastmanalive01.wav"
  63. #define SOUND_BONUS "vo/demoman_positivevocalization04.wav"
  64. #define SOUND_INTERNET "vo/pyro_positivevocalization01.wav"
  65. #define SOUND_SNAAAKE "prophunt/snaaake.mp3"
  66. #define SOUND_FOUND "prophunt/found.mp3"
  67. #define SOUND_ONEANDONLY "prophunt/oneandonly.mp3"
  68. #define SOUND_COUNT30 "vo/announcer_begins_30sec.wav"
  69. #define SOUND_COUNT20 "vo/announcer_begins_20sec.wav"
  70. #define SOUND_COUNT10 "vo/announcer_begins_10sec.wav"
  71. #define SOUND_COUNT5 "vo/announcer_begins_5sec.wav"
  72. #define SOUND_COUNT4 "vo/announcer_begins_4sec.wav"
  73. #define SOUND_COUNT3 "vo/announcer_begins_3sec.wav"
  74. #define SOUND_COUNT2 "vo/announcer_begins_2sec.wav"
  75. #define SOUND_COUNT1 "vo/announcer_begins_1sec.wav"
  76. #define SOUND_REMAIN30 "vo/announcer_ends_30sec.wav"
  77. #define SOUND_REMAIN10 "vo/announcer_ends_10sec.wav"
  78. #define SOUND_REMAIN5 "vo/announcer_ends_5sec.wav"
  79. #define SOUND_REMAIN4 "vo/announcer_ends_4sec.wav"
  80. #define SOUND_REMAIN3 "vo/announcer_ends_3sec.wav"
  81. #define SOUND_REMAIN2 "vo/announcer_ends_2sec.wav"
  82. #define SOUND_REMAIN1 "vo/announcer_ends_1sec.wav"
  83. #define SOUND_TIMEADDED1 "vo/announcer_time_awarded.wav"
  84. #define SOUND_TIMEADDED2 "vo/announcer_time_added.wav"
  85. #define SOUND_BUTTON_DISABLED "buttons/button10.wav"
  86. #define SOUND_BUTTON_UNLOCK "buttons/button24.wav"
  87. #define SOUND_BUTTON_LOCK "buttons/button3.wav"
  88.  
  89. #define FLAMETHROWER "models/weapons/w_models/w_flamethrower.mdl"
  90.  
  91. #define STATE_WAT -1
  92. #define STATE_IDLE 0
  93. #define STATE_RUNNING 1
  94. #define STATE_SWING 2
  95. #define STATE_CROUCH 3
  96.  
  97. #define CLASS_BLU TFClass_Pyro
  98. #define CLASS_RED 1
  99. #define PLAYER_ONFIRE (1 << 14)
  100.  
  101. // Weapon Indexes
  102. #define WEP_SHOTGUN_UNIQUE 199
  103. #define WEP_PISTOL_UNIQUE 209
  104.  
  105. //Pyro
  106. #define WEP_FIREAXE 2
  107. #define WEP_FIREAXE_UNIQUE 192
  108. #define WEP_SHOTGUNPYRO 12
  109.  
  110. #define WEP_FLAMETHROWER 21
  111. #define WEP_AXTINGUISHER 38
  112. #define WEP_FLAREGUN 39
  113. #define WEP_BACKBURNER 40
  114. #define WEP_HOMEWRECKER 153
  115. #define WEP_DETONATOR 351
  116.  
  117. //Heavy
  118. #define WEP_FISTS 5
  119. #define WEP_FISTS_UNIQUE 195
  120. #define WEP_SHOTGUNHEAVY 11
  121. #define WEP_MINIGUN 15
  122. #define WEP_MINIGUN_UNIQUE 202
  123. #define WEP_NATASCHA 41
  124. #define WEP_SANDVICH 42
  125. #define WEP_KGB 43
  126. #define WEP_BRASSBEAST 312
  127. #define WEP_IRONCURTAIN 298
  128. #define WEP_TOMISLAV 424
  129.  
  130. //Demoman
  131. #define WEP_BOTTLE 1
  132. #define WEP_BOTTLE_UNIQUE 191
  133. #define WEP_TARGE 131
  134. #define WEP_EYELANDER 132
  135. #define WEP_PAINTRAIN 154
  136. #define WEP_SKULLCUTTER 172
  137. #define WEP_SCREEN 406
  138.  
  139. //Sniper
  140. #define WEP_SNIPER 14
  141. #define WEP_SNIPER_UNIQUE 201
  142. #define WEP_SMG 16
  143. #define WEP_SMG_UNIQUE 203
  144. #define WEP_HUNTSMAN 56
  145. #define WEP_JARATE 58
  146. #define WEP_SHIV 171
  147. #define WEP_SYDNEYSLEEPER 230
  148. #define WEP_BARGIN 402
  149.  
  150. //Medic
  151. #define WEP_BONESAW 8
  152. #define WEP_BONESAW_UNIQUE 198
  153. #define WEP_NEEDLEGUN 17
  154. #define WEP_NEEDLEGUN_UNIQUE 204
  155. #define WEP_BLUTSAUGER 36
  156. #define WEP_UBERSAW 37
  157. #define WEP_AMPUTATOR 304
  158. #define WEP_CRUSADERSCROSSBOW 305
  159. #define WEP_VOW 413
  160.  
  161. //Scout
  162. #define WEP_BAT 0
  163. #define WEP_BAT_UNIQUE 190
  164. #define WEP_SCATTERGUN 13
  165. #define WEP_SCATTERGUN_UNIQUE 200
  166. #define WEP_SCOUTPISTOL 23
  167. #define WEP_SANDMAN 44
  168. #define WEP_FORCEANATURE 45
  169.  
  170. //Soldier
  171. #define WEP_SHOVEL 6
  172. #define WEP_SHOVEL_UNIQUE 196
  173. #define WEP_SHOTGUNSOLLY 10
  174. #define WEP_ROCKETLAUNCHER 18
  175. #define WEP_ROCKETLAUNCHER_UNIQUE 205
  176. #define WEP_DIRECTHIT 127
  177. #define WEP_EQUALIZER 128
  178. #define WEP_BLACKBOX 228
  179. #define WEP_LIBERTY 414
  180. #define WEP_RESERVE 415
  181.  
  182. //Engineer
  183. #define WEP_WRENCH 7
  184. #define WEP_WRENCH_UNIQUE 197
  185. #define WEP_SHOTGUNENGINEER 9
  186. #define WEP_ENGINIEERPISTOL 22
  187. #define WEP_FRONTIERJUSTICE 141
  188. #define WEP_LUGERMORPH 160
  189. #define WEP_LUGERMORPH_2 294
  190.  
  191. #define LOCKVOL 0.7
  192. #define UNBALANCE_LIMIT 1
  193. #define MAXMODELNAME 96
  194. #define TF2_PLAYERCOND_ONFIREALERT    (1<<20)
  195.  
  196. enum ScReason
  197. {
  198.     ScReason_TeamWin = 0,
  199.     ScReason_TeamLose,
  200.     ScReason_Death,
  201.     ScReason_Kill,
  202.     ScReason_Time,
  203.     ScReason_Friendly
  204. };
  205.  
  206. new bool:g_RoundOver = true;
  207.  
  208. new bool:g_LastProp;
  209. new bool:g_Attacking[MAXPLAYERS+1];
  210. new bool:g_SetClass[MAXPLAYERS+1];
  211. new bool:g_Spawned[MAXPLAYERS+1];
  212. new bool:g_TouchingCP[MAXPLAYERS+1];
  213. new bool:g_Charge[MAXPLAYERS+1];
  214. new bool:g_First[MAXPLAYERS+1];
  215. new bool:g_HoldingLMB[MAXPLAYERS+1];
  216. new bool:g_HoldingRMB[MAXPLAYERS+1];
  217. new bool:g_AllowedSpawn[MAXPLAYERS+1];
  218. new bool:g_RotLocked[MAXPLAYERS+1];
  219. new bool:g_Hit[MAXPLAYERS+1];
  220. new bool:g_Spec[MAXPLAYERS+1];
  221. new String:g_PlayerModel[MAXPLAYERS+1][MAXMODELNAME];
  222.  
  223. new String:g_Mapname[128];
  224. new String:g_ServerIP[32];
  225. new String:g_Version[8];
  226. #if defined CHARGE
  227. new g_offsCollisionGroup;
  228. #endif
  229. new g_Message_red;
  230. new g_Heavy_count;
  231. new g_Message_blue;
  232. new g_RoundTime = 175;
  233. new g_Message_bit = 0;
  234. new g_iVelocity = -1;
  235. #if defined STATS
  236. new bool:g_MapChanging = false;
  237. new g_StartTime;
  238. #endif
  239.  
  240. new Handle:g_TimerSound30 = INVALID_HANDLE;
  241. new Handle:g_TimerSound20 = INVALID_HANDLE;
  242. new Handle:g_TimerSound10 = INVALID_HANDLE;
  243. new Handle:g_TimerSound5 = INVALID_HANDLE;
  244. new Handle:g_TimerSound4 = INVALID_HANDLE;
  245. new Handle:g_TimerSound3 = INVALID_HANDLE;
  246. new Handle:g_TimerSound2 = INVALID_HANDLE;
  247. new Handle:g_TimerSound1 = INVALID_HANDLE;
  248. new Handle:g_TimerStart = INVALID_HANDLE;
  249.  
  250. new bool:g_Doors = false;
  251. new bool:g_Relay = false;
  252. new bool:g_Freeze = true;
  253.  
  254. new g_oFOV;
  255. new g_oDefFOV;
  256.  
  257. new Handle:g_PropNames = INVALID_HANDLE;
  258. new Handle:g_ModelName = INVALID_HANDLE;
  259. new Handle:g_ModelOffset = INVALID_HANDLE;
  260. new Handle:g_Text1 = INVALID_HANDLE;
  261. new Handle:g_Text2 = INVALID_HANDLE;
  262. new Handle:g_Text3 = INVALID_HANDLE;
  263. new Handle:g_Text4 = INVALID_HANDLE;
  264.  
  265. new Handle:g_RoundTimer = INVALID_HANDLE;
  266. new Handle:g_PropMenu = INVALID_HANDLE;
  267. new Handle:g_SelfDamageTrie = INVALID_HANDLE;
  268.  
  269. new Handle:g_PHEnable = INVALID_HANDLE;
  270. new Handle:g_PHPropMenu = INVALID_HANDLE;
  271. new Handle:g_PHAdmFlag = INVALID_HANDLE;
  272. new Handle:g_PHAdvertisements = INVALID_HANDLE;
  273.  
  274. new String:g_AdText[128] = "GamingMasters.co.uk";
  275.  
  276. public Plugin:myinfo =
  277. {
  278.     name = "PropHunt",
  279.     author = "Darkimmortal",
  280.     description = "GamingMasters.co.uk",
  281.     version = PL_VERSION,
  282.     url = "https://forums.alliedmods.net/showthread.php?t=107104"
  283. }
  284.  
  285. enum
  286. {
  287.     COLLISION_GROUP_NONE  = 0,
  288.     COLLISION_GROUP_DEBRIS,       // Collides with nothing but world and static stuff
  289.     COLLISION_GROUP_DEBRIS_TRIGGER, // Same as debris, but hits triggers
  290.     COLLISION_GROUP_INTERACTIVE_DEB, // Collides with everything except other interactive debris or debris
  291.     COLLISION_GROUP_INTERACTIVE,  // Collides with everything except interactive debris or debris
  292.     COLLISION_GROUP_PLAYER,
  293.     COLLISION_GROUP_BREAKABLE_GLASS,
  294.     COLLISION_GROUP_VEHICLE,
  295.     COLLISION_GROUP_PLAYER_MOVEMENT, // For HL2, same as Collision_Group_Player
  296.     COLLISION_GROUP_NPC,          // Generic NPC group
  297.     COLLISION_GROUP_IN_VEHICLE,   // for any entity inside a vehicle
  298.     COLLISION_GROUP_WEAPON,       // for any weapons that need collision detection
  299.     COLLISION_GROUP_VEHICLE_CLIP, // vehicle clip brush to restrict vehicle movement
  300.     COLLISION_GROUP_PROJECTILE,   // Projectiles!
  301.     COLLISION_GROUP_DOOR_BLOCKER, // Blocks entities not permitted to get near moving doors
  302.     COLLISION_GROUP_PASSABLE_DOOR, // Doors that the player shouldn't collide with
  303.     COLLISION_GROUP_DISSOLVING,   // Things that are dissolving are in this group
  304.     COLLISION_GROUP_PUSHAWAY,     // Nonsolid on client and server, pushaway in player code
  305.     COLLISION_GROUP_NPC_ACTOR,        // Used so NPCs in scripts ignore the player.
  306. }
  307.  
  308. #if defined STATS
  309.  
  310. #include "prophunt\stats2.inc"
  311.  
  312. public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
  313. {
  314.     decl String:hostname[255], String:ip[32], String:port[8]; //, String:map[92];
  315.     GetConVarString(FindConVar("hostname"), hostname, sizeof(hostname));
  316.     GetConVarString(FindConVar("ip"), ip, sizeof(ip));
  317.     GetConVarString(FindConVar("hostport"), port, sizeof(port));
  318.  
  319.     if(StrContains(hostname, "GamingMasters.co.uk", false) != -1)
  320.     {
  321.         if(StrContains(hostname, "PropHunt", false) == -1 && StrContains(hostname, "Arena", false) == -1 && StrContains(hostname, "Dark", false) == -1 &&
  322.            StrContains(ip, "8.9.4.169", false) == -1)
  323.             return APLRes_SilentFailure;
  324.     }
  325.     return APLRes_Success;
  326. }
  327.  
  328. #endif
  329.  
  330. public OnPluginStart()
  331. {
  332.     if (!IsPropHuntMap())
  333.         Unload();
  334.  
  335.     decl String:hostname[255], String:ip[32], String:port[8]; //, String:map[92];
  336.     GetConVarString(FindConVar("hostname"), hostname, sizeof(hostname));
  337.     GetConVarString(FindConVar("ip"), ip, sizeof(ip));
  338.     GetConVarString(FindConVar("hostport"), port, sizeof(port));
  339.  
  340.     Format(g_ServerIP, sizeof(g_ServerIP), "%s:%s", ip, port);
  341.  
  342.  
  343.     if(GetExtensionFileStatus("sdkhooks.ext") < 1)
  344.         SetFailState("SDK Hooks is not loaded.");
  345.  
  346.     new bool:statsbool = false;
  347. #if defined STATS
  348.     statsbool = true;
  349. #endif
  350.  
  351.     Format(g_Version, sizeof(g_Version), "%s%s", PL_VERSION, statsbool ? "s":"");
  352.     CreateConVar("sm_prophunt_version", g_Version, "PropHunt Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
  353.  
  354.     g_PHAdmFlag = CreateConVar("ph_propmenu_flag", "c", "Flag to use for the PropMenu");
  355.     g_PHEnable = CreateConVar("ph_enable", "1", "Enables the plugin");
  356.     g_PHPropMenu = CreateConVar("ph_propmenu", "0", "Control use of the propmenu command: -1 = Disabled, 0 = admin only, 1 = all players");
  357.     g_PHAdvertisements = CreateConVar("ph_adtext", g_AdText, "Controls the text used for Advertisements");
  358.  
  359.     HookConVarChange(g_PHEnable, OnConVarChanged);
  360.     HookConVarChange(g_PHAdvertisements, OnConVarChanged);
  361.  
  362.     g_Text1 = CreateHudSynchronizer();
  363.     g_Text2 = CreateHudSynchronizer();
  364.     g_Text3 = CreateHudSynchronizer();
  365.     g_Text4 = CreateHudSynchronizer();
  366.  
  367.     AddServerTag("PropHunt");
  368.  
  369.  
  370.     HookEvent("player_spawn", Event_player_spawn);
  371.     HookEvent("player_team", Event_player_team);
  372.     HookEvent("player_death", Event_player_death, EventHookMode_Pre);
  373.     HookEvent("arena_round_start", Event_arena_round_start, EventHookMode_Post);
  374.     HookEvent("arena_win_panel", Event_arena_win_panel);
  375.     HookEvent("player_changeclass", Event_player_changeclass);
  376.     HookEvent("post_inventory_application", CallCheckInventory, EventHookMode_Post);
  377.  
  378. #if defined STATS
  379.     Stats_Init();
  380. #endif
  381.  
  382.     RegConsoleCmd("help", Command_motd);
  383.     RegConsoleCmd("motd", Command_motd);
  384.     RegConsoleCmd("propmenu", Command_propmenu);
  385.  
  386.     AddFileToDownloadsTable("sound/prophunt/found.mp3");
  387.     AddFileToDownloadsTable("sound/prophunt/snaaake.mp3");
  388.     AddFileToDownloadsTable("sound/prophunt/oneandonly.mp3");
  389.  
  390.     SoundLoad();
  391. #if defined CHARGE
  392.     g_offsCollisionGroup = FindSendPropOffs("CBaseEntity", "m_CollisionGroup");
  393. #endif
  394.     LoadTranslations("prophunt.phrases");
  395.  
  396.     g_oFOV = FindSendPropOffs("CBasePlayer", "m_iFOV");
  397.     g_oDefFOV = FindSendPropOffs("CBasePlayer", "m_iDefaultFOV");
  398.  
  399.     g_SelfDamageTrie = CreateTrie();
  400.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_flamethrower", 1);
  401.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_minigun", 3);
  402.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_shotgun_hwg", 8);
  403.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_shotgun_soldier", 8);
  404.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_shotgun_pyro", 8);
  405.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_pistol_scout", 1);
  406.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_pistol", 8);
  407.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_syringegun_medic", 4);
  408.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_smg", 1);
  409.     SetTrieValue(g_SelfDamageTrie, "tf_weapon_flaregun", 5);
  410.  
  411.     RegAdminCmd("ph_respawn", Command_respawn, ADMFLAG_ROOT, "Respawns you");
  412.     RegAdminCmd("ph_switch", Command_switch, ADMFLAG_KICK, "Switches to RED");
  413.     RegAdminCmd("ph_internet", Command_internet, ADMFLAG_KICK, "Spams Internet");
  414.     RegAdminCmd("ph_pyro", Command_pyro, ADMFLAG_KICK, "Switches to BLU");
  415.     RegAdminCmd("ph_debug", Command_debug, ADMFLAG_KICK, "");
  416.  
  417.     if((g_iVelocity = FindSendPropOffs("CBasePlayer", "m_vecVelocity[0]")) == -1)
  418.         LogError("Could not find offset for CBasePlayer::m_vecVelocity[0]");
  419.  
  420.     CreateTimer(7.0, Timer_AntiHack, 0, TIMER_REPEAT);
  421.     CreateTimer(0.6, Timer_Locked, 0, TIMER_REPEAT);
  422.     CreateTimer(55.0, Timer_Score, 0, TIMER_REPEAT);
  423.  
  424.  
  425.     for(new client=1; client <= MaxClients; client++)
  426.     {
  427.         if(IsClientInGame(client))
  428.         {
  429.             ForcePlayerSuicide(client);
  430. #if defined STATS
  431.             OnClientPostAdminCheck(client);
  432. #endif
  433.         }
  434.     }
  435.     decl String:Path[256];
  436.     BuildPath(Path_SM, Path, sizeof(Path), "data/prophunt/propnames.txt");
  437.     g_PropNames = CreateKeyValues("g_PropNames");
  438.     if (!FileToKeyValues(g_PropNames, Path))
  439.         LogError("Could not load the g_PropNames file!");
  440.  
  441.     SetCVars();
  442. }
  443.  
  444. SetCVars(){
  445.  
  446.     new Handle:cvar = INVALID_HANDLE;
  447.     cvar = FindConVar("tf_arena_round_time");
  448.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  449.     cvar = FindConVar("tf_arena_use_queue");
  450.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  451.     cvar = FindConVar("tf_arena_max_streak");
  452.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  453.     cvar = FindConVar("mp_tournament");
  454.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  455.     cvar = FindConVar("mp_tournament_stopwatch");
  456.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  457.     cvar = FindConVar("tf_tournament_hide_domination_icons");
  458.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  459.     cvar = FindConVar("mp_teams_unbalance_limit");
  460.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  461.     cvar = FindConVar("tf_arena_preround_time");
  462.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  463.     cvar = FindConVar("mp_autoteambalance");
  464.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  465.     cvar = FindConVar("mp_autoteambalance");
  466.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  467.  
  468.     SetConVarInt(FindConVar("tf_weapon_criticals"), 1, true);
  469.     SetConVarInt(FindConVar("mp_idlemaxtime"), 0, true);
  470.     SetConVarInt(FindConVar("mp_tournament_stopwatch"), 0, true);
  471.     SetConVarInt(FindConVar("mp_idledealmethod"), 0, true);
  472.     SetConVarInt(FindConVar("tf_tournament_hide_domination_icons"), 0, true);
  473.     SetConVarInt(FindConVar("mp_maxrounds"), 0, true);
  474.     SetConVarInt(FindConVar("sv_alltalk"), 1, true);
  475.     SetConVarInt(FindConVar("mp_friendlyfire"), 0, true);
  476.     SetConVarInt(FindConVar("sv_gravity"), 500, true);
  477.     SetConVarInt(FindConVar("mp_forcecamera"), 1, true);
  478.     SetConVarInt(FindConVar("tf_arena_override_cap_enable_time"), 1, true);
  479.     SetConVarInt(FindConVar("mp_teams_unbalance_limit"), UNBALANCE_LIMIT, true);
  480.     SetConVarInt(FindConVar("mp_autoteambalance"), 0, true);
  481.     SetConVarInt(FindConVar("tf_arena_max_streak"), 5, true);
  482.     SetConVarInt(FindConVar("mp_enableroundwaittime"), 0, true);
  483.     SetConVarInt(FindConVar("mp_stalemate_timelimit"), 5, true);
  484.     SetConVarInt(FindConVar("tf_weapon_criticals"), 1, true);
  485.     SetConVarInt(FindConVar("mp_waitingforplayers_time"), 40, true);
  486.     SetConVarInt(FindConVar("tf_arena_use_queue"), 0, true);
  487.     SetConVarInt(FindConVar("mp_stalemate_enable"), 1, true);
  488.     SetConVarInt(FindConVar("tf_show_voice_icons"), 0, true);
  489.     SetConVarInt(FindConVar("mp_bonusroundtime"), 5, true);
  490.     SetConVarInt(FindConVar("tf_solidobjects"), 0, true);
  491.     SetConVarInt(FindConVar("tf_arena_preround_time"), IsDedicatedServer() ? 15:5, true);
  492. #if !defined AIRBLAST
  493.     SetConVarInt(FindConVar("tf_flamethrower_burstammo"), 201, true);
  494. #endif
  495.    
  496.     cvar = FindConVar("mp_idledealmethod");
  497.     if(GetConVarInt(cvar) == 1)
  498.     {
  499.         SetConVarInt(cvar, 2, true);
  500.     }
  501.    
  502.     if(GetExtensionFileStatus("runteamlogic.ext") == 1)
  503.     {
  504.     cvar = FindConVar("rtl_arenateamsize");
  505.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  506.     SetConVarInt(FindConVar("rtl_arenateamsize"), 16);
  507.     }
  508. }
  509.  
  510. ResetCVars()
  511. {
  512.  
  513.     new Handle:cvar = INVALID_HANDLE;
  514.     cvar = FindConVar("tf_arena_round_time");
  515.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  516.     cvar = FindConVar("tf_arena_use_queue");
  517.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  518.     cvar = FindConVar("tf_arena_max_streak");
  519.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  520.     cvar = FindConVar("mp_teams_unbalance_limit");
  521.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  522.     cvar = FindConVar("tf_arena_preround_time");
  523.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  524.     cvar = FindConVar("mp_autoteambalance");
  525.     SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  526.  
  527.     SetConVarInt(FindConVar("mp_idlemaxtime"), 3, true);
  528.     SetConVarInt(FindConVar("mp_maxrounds"), 0, true);
  529.     SetConVarInt(FindConVar("sv_alltalk"), 0, true);
  530.     SetConVarInt(FindConVar("sv_gravity"), 800, true);
  531.     SetConVarInt(FindConVar("mp_forcecamera"), 0, true);
  532.     SetConVarInt(FindConVar("tf_arena_override_cap_enable_time"), 0, true);
  533.     SetConVarInt(FindConVar("mp_teams_unbalance_limit"), 1, true);
  534.     SetConVarInt(FindConVar("mp_autoteambalance"), 1, true);
  535.     SetConVarInt(FindConVar("tf_arena_max_streak"), 5, true);
  536.     SetConVarInt(FindConVar("mp_enableroundwaittime"), 1, true);
  537.     SetConVarInt(FindConVar("mp_stalemate_timelimit"), 5, true);
  538.     SetConVarInt(FindConVar("mp_waitingforplayers_time"), 30, true);
  539.     SetConVarInt(FindConVar("mp_stalemate_enable"), 0, true);
  540.     SetConVarInt(FindConVar("tf_show_voice_icons"), 1, true);
  541.     SetConVarInt(FindConVar("mp_bonusroundtime"), 15, true);
  542.     SetConVarInt(FindConVar("tf_arena_preround_time"), 5, true);
  543.     SetConVarInt(FindConVar("tf_solidobjects"), 1, true);
  544.    
  545. #if !defined AIRBLAST
  546.     SetConVarInt(FindConVar("tf_flamethrower_burstammo"), 20, true);
  547. #endif
  548.  
  549.    
  550.     if(GetExtensionFileStatus("runteamlogic.ext") == 1)
  551.     {
  552.         cvar = FindConVar("rtl_arenateamsize");
  553.         SetConVarFlags(cvar, GetConVarFlags(cvar) & ~(FCVAR_NOTIFY));
  554.         SetConVarInt(FindConVar("rtl_arenateamsize"), 16);
  555.     }
  556. }
  557.  
  558. public OnConfigsExecuted()
  559. {
  560.     SetCVars();
  561. }
  562.  
  563. public OnConVarChanged(Handle:hCvar, const String:oldValue[], const String:newValue[])
  564. {
  565.     if (hCvar == g_PHEnable)
  566.     {
  567.         if(StringToInt(newValue) != 1)
  568.         {
  569.             Unload();
  570.         }
  571.     }
  572.     else if (hCvar == g_PHAdvertisements)
  573.     {
  574.         strcopy(g_AdText, sizeof(g_AdText), newValue);
  575.     }
  576. }
  577.  
  578. public Unload()
  579. {
  580.     /// @TODO: Some fancy GetPluginFilename stuff
  581.     if (g_PropNames != INVALID_HANDLE)
  582.         CloseHandle(g_PropNames);
  583.     ResetCVars();
  584.     ServerCommand("sm plugins unload prophunt");
  585. }
  586.  
  587. public Action:CallCheckInventory(Handle:event, const String:name[], bool:dontBroadcast)
  588. {
  589.     CreateTimer(0.5, CheckInventory, GetEventInt(event, "userid"));
  590. }
  591.  
  592. public Action:CheckInventory(Handle:timer, any:userid)
  593. {
  594.     new entity;
  595.     new prev = 0;
  596.     new client = GetClientOfUserId(userid);
  597.     if(client)
  598.     {
  599.         while((entity = FindEntityByClassname(entity, "tf_wearable")) != -1 && IsValidEntity(entity))
  600.         {
  601.             if(IsClientInGame(client) && GetClientTeam(client) == TEAM_RED && IsValidEntity(entity) && GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity") == client)
  602.             {
  603.                 SetEntityRenderMode(entity, RENDER_TRANSCOLOR);
  604.                 SetEntityRenderColor(entity, 255, 255, 255, 0);
  605.                 if (prev && IsValidEdict(prev))
  606.                     RemoveEdict(prev);
  607.                 prev = entity;
  608.             }
  609.             else
  610.             if(IsValidEdict(entity) && GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity") == client)
  611.             {
  612.                 SetEntityRenderMode(entity, RENDER_TRANSCOLOR);
  613.                 SetEntityRenderColor(entity, 255, 255, 255, 255);
  614.                 SetVariantString("");
  615.                 AcceptEntityInput(client, "EnableShadow");
  616.             }
  617.         }
  618.         if (prev && IsValidEdict(prev))
  619.             RemoveEdict(prev);
  620.     }
  621. }
  622.  
  623. public StartTouchHook(entity, other)
  624. {
  625.     if(other <= MaxClients && other > 0 && !g_TouchingCP[other] && IsClientInGame(other) && IsPlayerAlive(other))
  626.     {
  627.         FillHealth(other);
  628.         ExtinguishPlayer(other);
  629.         PrintToChat(other, "%t", "cpbonus");
  630.         EmitSoundToClient(other, SOUND_BONUS, _, _, SNDLEVEL_AIRCRAFT);
  631.         g_TouchingCP[other] = true;
  632.     }
  633. }
  634.  
  635. stock FillHealth (entity){
  636.     switch(TF2_GetPlayerClass(entity))
  637.     {
  638.     case TFClass_Heavy:
  639.         SetEntityHealth(entity, 300);
  640.     case TFClass_Sniper:
  641.         SetEntityHealth(entity, 150);
  642.     case TFClass_Pyro:
  643.         SetEntityHealth(entity, 175);
  644.     case TFClass_Scout:
  645.         SetEntityHealth(entity, 150);
  646.     case TFClass_Soldier:
  647.         SetEntityHealth(entity, 200);
  648.     case TFClass_Engineer:
  649.         {
  650.             if (GetEntProp(GetPlayerWeaponSlot(entity, 2), Prop_Send, "m_iEntityLevel") >= 5)
  651.             {
  652.             SetEntityHealth(entity, 150);
  653.             }
  654.             else
  655.                 SetEntityHealth(entity, 125);
  656.         }
  657.     case TFClass_DemoMan:
  658.         SetEntityHealth(entity, 175);
  659.     case TFClass_Spy:
  660.         SetEntityHealth(entity, 125);
  661.     case TFClass_Medic:
  662.         SetEntityHealth(entity, 150);
  663.     }
  664. }
  665.  
  666. stock bool:IsValidAdmin(client)
  667. {
  668.     decl String:flags[26];
  669.     GetConVarString(g_PHAdmFlag, flags, sizeof(flags));
  670.     if (GetUserFlagBits(client) & ADMFLAG_ROOT)
  671.     {
  672.         return true;
  673.     }
  674.     new iFlags = ReadFlagString(flags);
  675.     if (GetUserFlagBits(client) & iFlags)
  676.     {
  677.         return true;
  678.     }
  679.     return false;
  680. }
  681.  
  682. stock ExtinguishPlayer (client){
  683.     if(IsClientInGame(client) && IsPlayerAlive(client) && IsValidEntity(client))
  684.     {
  685.         ExtinguishEntity(client);
  686.         TF2_RemoveCondition(client, TFCond_OnFire);
  687.     }
  688. }
  689.  
  690. public OnEntityCreated(entity, const String:classname[])
  691. {
  692.     if(strcmp(classname, "team_control_point") == 0 ||
  693.        strcmp(classname, "team_control_point_round") == 0 ||
  694.        strcmp(classname, "trigger_capture_area") == 0 ||
  695.        strcmp(classname, "func_respawnroom") == 0 ||
  696.        strcmp(classname, "func_respawnroomvisualizer") == 0 ||
  697.        strcmp(classname, "obj_sentrygun") == 0)
  698.     {
  699.         SDKHook(entity, SDKHook_Spawn, OnBullshitEntitySpawned);
  700.     }
  701.     else
  702.     if(strcmp(classname, "prop_dynamic") == 0 || strcmp(classname, "prop_static") == 0)
  703.     {
  704.         SDKHook(entity, SDKHook_Spawn, OnCPEntitySpawned);
  705.     }
  706. }
  707.  
  708. public OnBullshitEntitySpawned(entity)
  709. {
  710.     if(IsValidEntity(entity))
  711.         AcceptEntityInput(entity, "Kill");
  712. }
  713.  
  714. public OnCPEntitySpawned(entity)
  715. {
  716.     decl String:propName[500];
  717.     GetEntPropString(entity, Prop_Data, "m_ModelName", propName, sizeof(propName));
  718.     if(StrEqual(propName, "models/props_gameplay/cap_point_base.mdl"))
  719.     {
  720.         SDKHook(entity, SDKHook_StartTouch, StartTouchHook);
  721.     }
  722. }
  723.  
  724.  
  725. public SoundLoad()
  726. {
  727.     PrecacheSound(SOUND_BEGIN);
  728.     PrecacheSound(SOUND_LASTPLAYER);
  729.     PrecacheSound(SOUND_BONUS);
  730.     PrecacheSound(SOUND_INTERNET);
  731.     PrecacheSound(SOUND_SNAAAKE);
  732.     PrecacheSound(SOUND_FOUND);
  733.     PrecacheSound(SOUND_ONEANDONLY);
  734.     PrecacheSound(SOUND_COUNT30);
  735.     PrecacheSound(SOUND_COUNT20);
  736.     PrecacheSound(SOUND_COUNT10);
  737.     PrecacheSound(SOUND_COUNT5);
  738.     PrecacheSound(SOUND_COUNT4);
  739.     PrecacheSound(SOUND_COUNT3);
  740.     PrecacheSound(SOUND_COUNT2);
  741.     PrecacheSound(SOUND_COUNT1);
  742.     PrecacheSound(SOUND_TIMEADDED1);
  743.     PrecacheSound(SOUND_TIMEADDED2);
  744.     PrecacheSound(SOUND_BUTTON_DISABLED);
  745.     PrecacheSound(SOUND_BUTTON_LOCK);
  746.     PrecacheSound(SOUND_BUTTON_UNLOCK);
  747. }
  748.  
  749. public OnMapEnd()
  750. {
  751. #if defined STATS
  752.     g_MapChanging = true;
  753. #endif
  754.  
  755.     // workaround no win panel event - admin changes, rtv, etc.
  756.     g_RoundOver = true;
  757. }
  758.  
  759. public OnMapStart()
  760. {
  761.  
  762.     GetCurrentMap(g_Mapname, sizeof(g_Mapname));
  763.  
  764.     new arraySize = ByteCountToCells(100);
  765.     g_ModelName = CreateArray(arraySize);
  766.     g_ModelOffset = CreateArray(arraySize);
  767.     PushArrayString(g_ModelName, "models/props_gameplay/cap_point_base.mdl");
  768.     PushArrayString(g_ModelOffset, "0 0 0");
  769.    
  770. #if defined STATS
  771.     g_MapChanging = false;
  772. #endif
  773.  
  774.     if (g_PropMenu != INVALID_HANDLE)
  775.     {
  776.         CloseHandle(g_PropMenu);
  777.         g_PropMenu = INVALID_HANDLE;
  778.     }
  779.     g_PropMenu = CreateMenu(Handler_PropMenu);
  780.     SetMenuTitle(g_PropMenu, "PropHunt Prop Menu");
  781.     SetMenuExitButton(g_PropMenu, true);
  782.     AddMenuItem(g_PropMenu, "models/player/pyro.mdl", "models/player/pyro.mdl");
  783.     AddMenuItem(g_PropMenu, "models/props_halloween/ghost.mdl", "models/props_halloween/ghost.mdl");
  784.  
  785.     decl String:confil[192], String:buffer[256], String:offset[32], String:tidyname[2][32], String:maptidyname[128];
  786.     ExplodeString(g_Mapname, "_", tidyname, 2, 32);
  787.     Format(maptidyname, sizeof(maptidyname), "%s_%s", tidyname[0], tidyname[1]);
  788.     BuildPath(Path_SM, confil, sizeof(confil), "data/prophunt/%s.cfg", maptidyname);
  789.     new Handle:fl = CreateKeyValues("prophuntmapconfig");
  790.  
  791.     if(!FileToKeyValues(fl, confil))
  792.     {
  793.         LogMessage("[PH] Config file for map %s not found at %s. Unloading plugin.", maptidyname, confil);
  794.         CloseHandle(fl);
  795.         Unload();
  796.         return;
  797.     }
  798.     else
  799.     {
  800.         PrintToServer("Successfully loaded %s", confil);
  801.         KvGotoFirstSubKey(fl);
  802.         KvJumpToKey(fl, "Props", false);
  803.         KvGotoFirstSubKey(fl);
  804.         do
  805.         {
  806.             KvGetSectionName(fl, buffer, sizeof(buffer));
  807.             PushArrayString(g_ModelName, buffer);
  808.             AddMenuItem(g_PropMenu, buffer, buffer);
  809.             KvGetString(fl, "offset", offset, sizeof(offset), "0 0 0");
  810.             PushArrayString(g_ModelOffset, offset);
  811.         }
  812.         while (KvGotoNextKey(fl));
  813.         KvRewind(fl);
  814.         KvJumpToKey(fl, "Settings", false);
  815.  
  816.         KvGetString(fl, "doors", buffer, sizeof(buffer), "0");
  817.         g_Doors = strcmp(buffer, "1") == 0;
  818.  
  819.         KvGetString(fl, "relay", buffer, sizeof(buffer), "0");
  820.         g_Relay = strcmp(buffer, "1") == 0;
  821.  
  822.         KvGetString(fl, "freeze", buffer, sizeof(buffer), "1");
  823.         g_Freeze = strcmp(buffer, "1") == 0;
  824.  
  825.         KvGetString(fl, "round", buffer, sizeof(buffer), "175");
  826.         g_RoundTime = StringToInt(buffer);
  827.  
  828.         PrintToServer("Successfully parsed %s", confil);
  829.         PrintToServer("Loaded %i models, doors: %i, relay: %i, freeze: %i, round time: %i.", GetArraySize(g_ModelName)-1, g_Doors ? 1:0, g_Relay ? 1:0, g_Freeze ? 1:0, g_RoundTime);
  830.     }
  831.     CloseHandle(fl);
  832.  
  833.     SoundLoad();
  834.  
  835.     decl String:model[100];
  836.  
  837.     for(new i = 0; i < GetArraySize(g_ModelName); i++)
  838.     {
  839.         GetArrayString(g_ModelName, i, model, sizeof(model));
  840.         PrecacheModel(model, true);
  841.     }
  842.  
  843.     PrecacheModel(FLAMETHROWER, true);
  844.    
  845.     /*new ent = FindEntityByClassname(-1, "team_control_point_master");
  846.     if (ent == 1)
  847.     {
  848.         AcceptEntityInput(ent, "Kill");
  849.     }
  850.     ent = CreateEntityByName("team_control_point_master");
  851.     DispatchKeyValue(ent, "switch_teams", "1");
  852.     DispatchSpawn(ent);
  853.     AcceptEntityInput(ent, "Enable");*/
  854. }
  855.  
  856. public Action:OnGetGameDescription(String:gameDesc[64])
  857. {
  858.     if (strlen(g_AdText) > 0)
  859.         Format(gameDesc, sizeof(gameDesc), "PropHunt %s (%s)", g_Version, g_AdText);
  860.     else
  861.         Format(gameDesc, sizeof(gameDesc), "PropHunt %s", g_Version);
  862.        
  863.     return Plugin_Changed;
  864. }
  865.  
  866. public Action:Timer_TimeUp(Handle:timer, any:lol)
  867. {
  868. #if defined LOG
  869.     LogMessage("[PH] Time Up");
  870. #endif
  871.     if(!g_RoundOver)
  872.     {
  873.         ForceTeamWin(TEAM_RED);
  874.         g_RoundOver = true;
  875.     }
  876.     g_RoundTimer = INVALID_HANDLE;
  877.     return Plugin_Handled;
  878. }
  879.  
  880. public Action:Timer_AfterWinPanel(Handle:timer, any:lol)
  881. {
  882. #if defined LOG
  883.     LogMessage("[PH] After Win Panel");
  884. #endif
  885.     StopTimer(g_RoundTimer);
  886. }
  887.  
  888. public OnPluginEnd()
  889. {
  890.     PrintCenterTextAll("%t", "plugin reload");
  891. #if defined STATS
  892.     Stats_Uninit();
  893. #endif
  894. }
  895.  
  896. public Action:TakeDamageHook(client, &attacker, &inflictor, &Float:damage, &damagetype)
  897. {
  898.     if(client > 0 && attacker > 0 && client < MaxClients && attacker < MaxClients && IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == TEAM_RED
  899.        && IsClientInGame(attacker) && GetClientTeam(attacker) == TEAM_BLUE)
  900.     {
  901.  
  902.         if(!g_Hit[client])
  903.         {
  904.             new Float:pos[3];
  905.             GetClientAbsOrigin(client, pos);
  906.             EmitSoundToClient(client, SOUND_FOUND, _, SNDCHAN_WEAPON, _, _, 0.8, _, client, pos);
  907.             EmitSoundToClient(attacker, SOUND_FOUND, _, SNDCHAN_WEAPON, _, _, 0.8, _, client, pos);
  908.             g_Hit[client] = true;
  909.         }
  910.  
  911.         if(IsValidEntity(GetEntPropEnt(attacker, Prop_Send, "m_hActiveWeapon")) )
  912.         {
  913.             switch(GetEntProp(GetEntPropEnt(attacker, Prop_Send, "m_hActiveWeapon"), Prop_Send, "m_iItemDefinitionIndex"))
  914.             {
  915.                 case WEP_DETONATOR:
  916.                 {
  917.                     damage = FloatMul(damage, 0.95);
  918.                 }
  919.                 case WEP_HUNTSMAN, WEP_FRONTIERJUSTICE:
  920.                 {
  921.                 damage = FloatMul(damage, 0.85);
  922.                 }
  923.                 case WEP_SHOTGUNHEAVY, WEP_SHOTGUNSOLLY, WEP_SHOTGUNENGINEER, WEP_BACKBURNER, WEP_SHOTGUNPYRO, WEP_SHOTGUN_UNIQUE, WEP_RESERVE:
  924.                 {
  925.                     damage = FloatMul(damage, 0.8);
  926.                 }
  927.                 case WEP_MINIGUN, WEP_MINIGUN_UNIQUE, WEP_ROCKETLAUNCHER, WEP_ROCKETLAUNCHER_UNIQUE, WEP_DIRECTHIT, WEP_BLACKBOX, WEP_BRASSBEAST, WEP_IRONCURTAIN, WEP_TOMISLAV, WEP_LIBERTY, WEP_SCREEN:
  928.                 {
  929.                     damage = FloatMul(damage, 0.75);
  930.                 }
  931.             }
  932.             return Plugin_Changed;
  933.         }
  934.  
  935.     }
  936.  
  937.     //block prop drowning
  938.     if(damagetype == DMG_DROWN && client > 0 && client < MaxClients && IsClientInGame(client) && GetClientTeam(client) == TEAM_RED && attacker == 0)
  939.     {
  940.         damage = 0.0;
  941.         return Plugin_Changed;
  942.     }
  943.     return Plugin_Continue;
  944. }
  945.  
  946.  
  947. stock RemoveAnimeModel (client){
  948.     if(IsClientInGame(client) && IsPlayerAlive(client) && IsValidEntity(client))
  949.     {
  950.         SetVariantString("");
  951.         AcceptEntityInput(client, "SetCustomModel");
  952.     }
  953. }
  954.  
  955. public OnClientDisconnect(client)
  956. {
  957. #if defined STATS
  958.     OCD(client);
  959. #endif
  960. }
  961.  
  962. public OnClientDisconnect_Post(client)
  963. {
  964.     ResetPlayer(client);
  965. #if defined STATS
  966.     OCD_Post(client);
  967. #endif
  968. }
  969.  
  970. stock SwitchView (target, bool:observer, bool:viewmodel){
  971.     g_First[target] = !observer;
  972.     SetEntPropEnt(target, Prop_Send, "m_hObserverTarget", observer ? target:-1);
  973.     SetEntProp(target, Prop_Send, "m_iObserverMode", observer ? 1:0);
  974.     SetEntData(target, g_oFOV, observer ? 100:GetEntData(target, g_oDefFOV, 4), 4, true);
  975.     SetEntProp(target, Prop_Send, "m_bDrawViewmodel", viewmodel ? 1:0);
  976.  
  977.     SetVariantBool(observer);
  978.     AcceptEntityInput(target, "SetCustomModelVisibletoSelf");
  979. }
  980.  
  981.  
  982. stock ForceTeamWin (team){
  983.     new ent = FindEntityByClassname(-1, "team_control_point_master");
  984.     if (ent == -1)
  985.     {
  986.         ent = CreateEntityByName("team_control_point_master");
  987.         DispatchSpawn(ent);
  988.         AcceptEntityInput(ent, "Enable");
  989.     }
  990.     SetVariantInt(team);
  991.     AcceptEntityInput(ent, "SetWinner");
  992. }
  993.  
  994. public Action:Event_player_team(Handle:event, const String:name[], bool:dontBroadcast)
  995. {
  996.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  997.     if(GetEventInt(event, "team") > 1)
  998.     {
  999.         g_Spec[client] = false;
  1000.     }
  1001. }
  1002.  
  1003. public Action:Command_jointeam(client, args)
  1004. {
  1005.     decl String:argstr[16];
  1006.     GetCmdArgString(argstr, sizeof(argstr));
  1007.     if(StrEqual(argstr, "spectatearena"))
  1008.     {
  1009.         g_Spec[client] = true;
  1010.     }
  1011.     else
  1012.     {
  1013.         g_Spec[client] = false;
  1014.     }
  1015.     return Plugin_Continue;
  1016. }
  1017.  
  1018. public Action:Command_propmenu(client, args)
  1019. {
  1020.     if(GetConVarInt(g_PHPropMenu) == 1 || IsValidAdmin(client) && GetConVarInt(g_PHPropMenu) == 0)
  1021.     {
  1022.         if(GetClientTeam(client) == TEAM_RED && IsPlayerAlive(client))
  1023.         {
  1024.             if (GetCmdArgs() == 1)
  1025.             {
  1026.                 decl String:model[MAXMODELNAME];
  1027.                 GetCmdArg(1, model, MAXMODELNAME);
  1028.                 strcopy(g_PlayerModel[client], MAXMODELNAME, model);
  1029.                 Timer_DoEquip(INVALID_HANDLE, client);
  1030.             }
  1031.             else
  1032.             {
  1033.                 DisplayMenu(g_PropMenu, client, MENU_TIME_FOREVER);
  1034.             }
  1035.         }
  1036.         else
  1037.         {
  1038.             PrintToChat(client, "You must be alive on RED to access the prop menu.");
  1039.         }
  1040.     }
  1041.     else
  1042.     {
  1043.         PrintToChat(client, "You do not have access to the prop menu.");
  1044.     }
  1045.     return Plugin_Handled;
  1046. }
  1047.  
  1048.  
  1049. public Handler_PropMenu(Handle:menu, MenuAction:action, param1, param2)
  1050. {
  1051.     switch (action)
  1052.     {
  1053.     case MenuAction_Select:{
  1054.             if(IsClientInGame(param1))
  1055.             {
  1056.                 if(GetConVarInt(g_PHPropMenu) == 1 || IsValidAdmin(param1))
  1057.                 {
  1058.                     if(GetClientTeam(param1) == TEAM_RED && IsPlayerAlive(param1))
  1059.                     {
  1060.                         GetMenuItem(menu, param2, g_PlayerModel[param1], MAXMODELNAME);
  1061.                         Timer_DoEquip(INVALID_HANDLE, param1);
  1062.                     }
  1063.                     else
  1064.                     {
  1065.                         PrintToChat(param1, "You must be alive on RED to access the prop menu.");
  1066.                     }
  1067.                 }
  1068.                 else
  1069.                 {
  1070.                     PrintToChat(param1, "You do not have access to the prop menu.");
  1071.                 }
  1072.             }
  1073.     }
  1074.     }
  1075. }
  1076.  
  1077. public OnClientPutInServer(client)
  1078. {
  1079.     ResetPlayer(client);
  1080. }
  1081.  
  1082. public ResetPlayer(client)
  1083. {
  1084.     g_Spawned[client] = false;
  1085.     g_Charge[client] = false;
  1086.     g_AllowedSpawn[client] = false;
  1087.     g_Hit[client] = false;
  1088.     g_Attacking[client] = false;
  1089.     g_RotLocked[client] = false;
  1090.     g_Spec[client] = false;
  1091.     g_TouchingCP[client] = false;
  1092.     g_First[client] = false;
  1093.     g_PlayerModel[client] = "";
  1094.     g_SetClass[client] = false;
  1095. }
  1096.  
  1097. public Action: Command_respawn(client, args)
  1098. {
  1099.     TF2_RespawnPlayer(client);
  1100.     return Plugin_Handled;
  1101. }
  1102.  
  1103. public Action:Command_debug(client, args)
  1104. {
  1105.     GetAnimeEnt(client);
  1106.     PrintToChat(client, "g_RoundOver = %s", g_RoundOver ? "true":"false");
  1107. }
  1108.  
  1109. public Action:Command_internet(client, args)
  1110. {
  1111.     decl String:name[255];
  1112.     for(new i = 0; i < 3; i++)
  1113.     {
  1114.         EmitSoundToAll(SOUND_INTERNET, _, _, SNDLEVEL_AIRCRAFT);
  1115.     }
  1116.     GetClientName(client, name, sizeof(name));
  1117.     return Plugin_Handled;
  1118. }
  1119.  
  1120. public Action:Command_switch(client, args)
  1121. {
  1122.     g_AllowedSpawn[client] = true;
  1123.     ChangeClientTeam(client, TEAM_RED);
  1124.     TF2_RespawnPlayer(client);
  1125.     CreateTimer(0.5, Timer_Move, client);
  1126.     return Plugin_Handled;
  1127. }
  1128.  
  1129. public Action:Command_pyro(client, args)
  1130. {
  1131.     g_PlayerModel[client] = "";
  1132.     g_AllowedSpawn[client] = true;
  1133.     ChangeClientTeam(client, TEAM_BLUE);
  1134.     TF2_RespawnPlayer(client);
  1135.     CreateTimer(0.5, Timer_Move, client);
  1136.     CreateTimer(0.8, Timer_Unfreeze, client);
  1137.     return Plugin_Handled;
  1138. }
  1139.  
  1140. public Action:Timer_Unfreeze(Handle:timer, any:client)
  1141. {
  1142.     if(IsClientInGame(client) && IsPlayerAlive(client))
  1143.         SetEntityMoveType(client, MOVETYPE_WALK);
  1144.     return Plugin_Handled;
  1145. }
  1146.  
  1147. public Action:Timer_Move(Handle:timer, any:client)
  1148. {
  1149.     g_AllowedSpawn[client] = false;
  1150.     if(IsClientInGame(client) && IsPlayerAlive(client))
  1151.     {
  1152.         new rag = GetEntPropEnt(client, Prop_Send, "m_hRagdoll");
  1153.         if(IsValidEntity(rag))
  1154.             AcceptEntityInput(rag, "Kill");
  1155.         SetEntityMoveType(client, MOVETYPE_WALK);
  1156.         if(GetClientTeam(client) == TEAM_BLUE)
  1157.         {
  1158.             CreateTimer(0.1, Timer_DoEquipBlu, client);
  1159.         }
  1160.         else
  1161.         {
  1162.             CreateTimer(0.1, Timer_DoEquip, client);
  1163.         }
  1164.     }
  1165.     return Plugin_Handled;
  1166. }
  1167.  
  1168. // much more reliable than an entity index array for cross-round code, since indexes are fucked with between rounds on srcds (only?)
  1169. stock GetAnimeEnt (client){
  1170.     new client2, ent;
  1171.     while(IsValidEntity(ent) && (ent = FindEntityByClassname(ent, "prop_dynamic")) != -1)
  1172.     {
  1173.         client2 = GetEntPropEnt(ent, Prop_Send, "m_hOwnerEntity");
  1174.         if(client2 == client)
  1175.         {
  1176.             return ent;
  1177.         }
  1178.     }
  1179.     return -1;
  1180. }
  1181.  
  1182. stock PlayersAlive (){
  1183.     new alive = 0;
  1184.     for(new i=1; i <= MaxClients; i++)
  1185.     {
  1186.         if(IsClientInGame(i) && IsPlayerAlive(i))
  1187.             alive++;
  1188.     }
  1189.     return alive;
  1190. }
  1191.  
  1192. public Action:Event_arena_win_panel(Handle:event, const String:name[], bool:dontBroadcast)
  1193. {
  1194. #if defined LOG
  1195.     LogMessage("[PH] round end");
  1196. #endif
  1197.     g_Heavy_count=0;
  1198.  
  1199.  
  1200.     g_RoundOver = true;
  1201.  
  1202. #if defined STATS
  1203.     new winner = GetEventInt(event, "winning_team");
  1204.     DbRound(winner);
  1205. #endif
  1206.  
  1207.     SetConVarInt(FindConVar("mp_teams_unbalance_limit"), 0, true);
  1208.  
  1209.     new team, client;
  1210.     for(client=1; client <= MaxClients; client++)
  1211.     {
  1212.         if(IsClientInGame(client))
  1213.         {
  1214. #if defined STATS
  1215.             if(GetClientTeam(client) == winner)
  1216.             {
  1217.                 AlterScore(client, 3, ScReason_TeamWin, 0);
  1218.             }
  1219.             else
  1220.             if(GetClientTeam(client) != TEAM_SPEC)
  1221.             {
  1222.                 AlterScore(client, -1, ScReason_TeamLose, 0);
  1223.             }
  1224. #endif
  1225.             ResetPlayer(client);
  1226.             // bit annoying when testing the plugin and/or maps on a listen server
  1227.             if(IsDedicatedServer())
  1228.             {
  1229.                 team = GetClientTeam(client);
  1230.                 if(team == TEAM_RED || team == TEAM_BLUE)
  1231.                 {
  1232.                     team = team == TEAM_RED ? TEAM_BLUE:TEAM_RED;
  1233.                     ChangeClientTeamAlive(client, team);
  1234.                 }
  1235.             }
  1236.         }
  1237.     }
  1238.  
  1239. #if defined LOG
  1240.     LogMessage("Team balancing...");
  1241. #endif
  1242.     decl String:cname[64];
  1243.     while(GetTeamClientCount(TEAM_RED) > GetTeamClientCount(TEAM_BLUE) )
  1244.     {
  1245.         client = GetRandomPlayer(TEAM_RED);
  1246.         GetClientName(client, cname, sizeof(cname));
  1247.         PrintToChatAll("%t", "balance blu", cname);
  1248.         ChangeClientTeamAlive(client, TEAM_BLUE);
  1249.     }
  1250.     while(GetTeamClientCount(TEAM_BLUE) > GetTeamClientCount(TEAM_RED) +1 )
  1251.     {
  1252.         client = GetRandomPlayer(TEAM_BLUE);
  1253.         GetClientName(client, cname, sizeof(cname));
  1254.         PrintToChatAll("%t", "balance red", cname);
  1255.         ChangeClientTeamAlive(client, TEAM_RED);
  1256.     }
  1257. #if defined LOG
  1258.     LogMessage("Complete");
  1259. #endif
  1260.  
  1261.     SetConVarFlags(FindConVar("mp_teams_unbalance_limit"), GetConVarFlags(FindConVar("mp_teams_unbalance_limit")) & ~(FCVAR_NOTIFY));
  1262.     SetConVarInt(FindConVar("mp_teams_unbalance_limit"), UNBALANCE_LIMIT, true);
  1263.  
  1264.     StopPreroundTimers(false);
  1265. }
  1266.  
  1267. public StopPreroundTimers(bool:instant)
  1268. {
  1269.     StopTimer(g_TimerStart);
  1270.     StopTimer(g_TimerSound30);
  1271.     StopTimer(g_TimerSound20);
  1272.     StopTimer(g_TimerSound10);
  1273.     StopTimer(g_TimerSound5);
  1274.     StopTimer(g_TimerSound4);
  1275.     StopTimer(g_TimerSound3);
  1276.     StopTimer(g_TimerSound2);
  1277.     StopTimer(g_TimerSound1);
  1278.     if(instant)
  1279.         StopTimer(g_RoundTimer);
  1280.     else
  1281.         CreateTimer(2.0, Timer_AfterWinPanel);
  1282. }
  1283.  
  1284. stock ChangeClientTeamAlive (client, team)
  1285. {
  1286.     SetEntProp(client, Prop_Send, "m_lifeState", 2);
  1287.     ChangeClientTeam(client, team);
  1288.     SetEntProp(client, Prop_Send, "m_lifeState", 0);
  1289. }
  1290.  
  1291. stock GetRandomPlayer (team)
  1292. {
  1293.     new client, totalclients;
  1294.  
  1295.     for(client=1; client <= MaxClients; client++)
  1296.     {
  1297.         if(IsClientInGame(client))
  1298.         {
  1299.             totalclients++;
  1300.         }
  1301.     }
  1302.  
  1303.     new clientarray[totalclients], i;
  1304.     for(client=1; client <= MaxClients; client++)
  1305.     {
  1306.         if(IsClientInGame(client))
  1307.         {
  1308.             clientarray[i] = client;
  1309.             i++;
  1310.         }
  1311.     }
  1312.  
  1313.     do
  1314.     {
  1315.         client = clientarray[GetRandomInt(0, totalclients-1)];
  1316.     }
  1317.     while( !(IsClientInGame(client) && GetClientTeam(client) == team) );
  1318.     return client;
  1319. }
  1320.  
  1321. stock StopTimer (Handle:timer)
  1322. {
  1323.     if(timer != INVALID_HANDLE) CloseHandle(timer);
  1324.     timer = INVALID_HANDLE;
  1325. }
  1326.  
  1327. stock IsPropHuntMap ()
  1328. {
  1329.     GetCurrentMap(g_Mapname, sizeof(g_Mapname));
  1330.  
  1331.     new String:confil[192], String:tidyname[2][32], String:maptidyname[128];
  1332.     ExplodeString(g_Mapname, "_", tidyname, 2, 32);
  1333.     Format(maptidyname, sizeof(maptidyname), "%s_%s", tidyname[0], tidyname[1]);
  1334.     BuildPath(Path_SM, confil, sizeof(confil), "data/prophunt/%s.cfg", maptidyname);
  1335.     new Handle:fl = CreateKeyValues("prophuntmapconfig");
  1336.  
  1337.     if(!FileToKeyValues(fl, confil))
  1338.     {
  1339.         LogMessage("[PH] Config file for map %s not found at %s. Unloading plugin.", maptidyname, confil);
  1340.         CloseHandle(fl);
  1341.         return false;
  1342.     }
  1343.     else
  1344.     {
  1345.         CloseHandle(fl);
  1346.         return true;
  1347.     }
  1348. }
  1349.  
  1350. public Action:Timer_Locked(Handle:timer, any:entity)
  1351. {
  1352.     for(new client=1; client <= MaxClients; client++)
  1353.     {
  1354.         if(g_RotLocked[client] && IsClientInGame(client) && !IsFakeClient(client) && IsPlayerAlive(client) && GetClientTeam(client) == TEAM_RED)
  1355.         {
  1356.             SetHudTextParamsEx(0.05, 0.05, 0.7, { /*0,204,255*/ 220, 90, 0, 255}, {0,0,0,0}, 1, 0.2, 0.2, 0.2);
  1357.             ShowSyncHudText(client, g_Text4, "PropLock Engaged");
  1358.         }
  1359.     }
  1360. }
  1361.  
  1362. public Action:Timer_AntiHack(Handle:timer, any:entity)
  1363. {
  1364. #if defined ANTIHACK
  1365.     if(!g_RoundOver && !g_LastProp)
  1366.     {
  1367.         decl String:name[64];
  1368.         for(new client=1; client <= MaxClients; client++)
  1369.         {
  1370.             if(IsClientInGame(client) && IsPlayerAlive(client))
  1371.             {
  1372.                 if(GetClientTeam(client) == TEAM_RED && TF2_GetPlayerClass(client) == TFClass_Scout)
  1373.                 {
  1374.                     if(GetPlayerWeaponSlot(client, 1) != -1 || GetPlayerWeaponSlot(client, 0) != -1 || GetPlayerWeaponSlot(client, 2) != -1)
  1375.                     {
  1376.                         GetClientName(client, name, sizeof(name));
  1377.                         PrintToChatAll("\x04%t", "weapon punish", name);
  1378.                         SwitchView(client, false, true);
  1379.                         //ForcePlayerSuicide(client);
  1380.                         TF2_RemoveAllWeapons(client);
  1381.                     }
  1382.                 }
  1383.             }
  1384.         }
  1385.     }
  1386. #endif
  1387. }
  1388.  
  1389. public Action:Timer_Score(Handle:timer, any:entity)
  1390. {
  1391.     for(new client=1; client <= MaxClients; client++)
  1392.     {
  1393. #if defined STATS
  1394.         if(IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == TEAM_RED)
  1395.         {
  1396.             AlterScore(client, 2, ScReason_Time, 0);
  1397.         }
  1398. #endif
  1399.         g_TouchingCP[client] = false;
  1400.     }
  1401.     PrintToChatAll("\x03%t", "cpbonus refreshed");
  1402. }
  1403.  
  1404.  
  1405. public Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &bool:result)
  1406. {
  1407.  
  1408.     if(g_RoundOver)
  1409.         return Plugin_Continue;
  1410.  
  1411.     if(IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == TEAM_BLUE)
  1412.     {
  1413.         new damage = 10, damage2 = 10;
  1414.  
  1415.         if(GetTrieValue(g_SelfDamageTrie, weaponname, damage2))
  1416.             damage = damage2;
  1417.  
  1418.         new helf = GetClientHealth(client)-damage;
  1419.         if(helf < 1)
  1420.             ForcePlayerSuicide(client);
  1421.         else
  1422.             SetEntityHealth(client, helf);
  1423.  
  1424.         if(strcmp(weaponname, "tf_weapon_flamethrower") == 0) AddVelocity(client, 1.0);
  1425.  
  1426.         result = false;
  1427.         return Plugin_Handled;
  1428.     }
  1429.     return Plugin_Continue;
  1430. }
  1431.  
  1432. stock AddVelocity (client, Float:speed){
  1433.     new Float:velocity[3];
  1434.     GetEntDataVector(client, g_iVelocity, velocity);
  1435.  
  1436.     // fucking win
  1437.     if(velocity[0] < 200 && velocity[0] > -200)
  1438.         velocity[0] *= (1.08 * speed);
  1439.     if(velocity[1] < 200 && velocity[1] > -200)
  1440.         velocity[1] *= (1.08 * speed);
  1441.     if(velocity[2] > 0 && velocity[2] < 400)
  1442.         velocity[2] = velocity[2] * 1.15 * speed;
  1443.  
  1444.     TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, velocity);
  1445. }
  1446.  
  1447. public Action:SetTransmitHook(entity, client)
  1448. {
  1449.     if(g_First[client] && client == entity)
  1450.     {
  1451.         return Plugin_Stop;
  1452.     }
  1453.     return Plugin_Continue;
  1454. }
  1455.  
  1456. public PreThinkHook(client)
  1457. {
  1458.  
  1459.     if(IsClientInGame(client))
  1460.     {
  1461.  
  1462.         if(IsPlayerAlive(client))
  1463.         {
  1464.             new buttons = GetClientButtons(client);
  1465.             if((buttons & IN_ATTACK) == IN_ATTACK && GetClientTeam(client) == TEAM_BLUE)
  1466.             {
  1467.                 g_Attacking[client] = true;
  1468.             }
  1469.             else
  1470.             {
  1471.                 g_Attacking[client] = false;
  1472.             }
  1473.  
  1474.             if(GetClientTeam(client) == TEAM_RED)
  1475.             {
  1476.                 // tl;dr - (LMB and not crouching OR any movement key while locked) AND not holding key
  1477.                 if(((((buttons & IN_ATTACK) == IN_ATTACK && (buttons & IN_DUCK) != IN_DUCK) ||
  1478.                      ((buttons & IN_FORWARD) == IN_FORWARD || (buttons & IN_MOVELEFT) == IN_MOVELEFT || (buttons & IN_MOVERIGHT) == IN_MOVERIGHT ||
  1479.                       (buttons & IN_BACK) == IN_BACK || (buttons & IN_JUMP) == IN_JUMP) && g_RotLocked[client])) && !g_HoldingLMB[client]
  1480.                    )
  1481.                 {
  1482.                     g_HoldingLMB[client] = true;
  1483.                     if(GetPlayerWeaponSlot(client, 0) == -1)
  1484.                     {
  1485.  
  1486.                         if(!g_RotLocked[client])
  1487.                         {
  1488.                             new Float:velocity[3];
  1489.                             GetEntDataVector(client, g_iVelocity, velocity);
  1490.                             // if the client is moving, don't allow them to lock in place
  1491.                             if(velocity[0] > -5 && velocity[1] > -5 && velocity[2] > -5 && velocity[0] < 5 && velocity[1] < 5 && velocity[2] < 5)
  1492.                             {
  1493.                                 SetVariantInt(0);
  1494.                                 AcceptEntityInput(client, "SetCustomModelRotates");
  1495.                                 g_RotLocked[client] = true;
  1496. #if defined LOCKSOUND
  1497.                                 EmitSoundToClient(client, SOUND_BUTTON_LOCK, _, _, _, _, LOCKVOL);
  1498. #endif
  1499.                             }
  1500.  
  1501.                         }
  1502.                         else
  1503.                         if(g_RotLocked[client])
  1504.                         {
  1505.                             SetVariantInt(1);
  1506.                             AcceptEntityInput(client, "SetCustomModelRotates");
  1507. #if defined LOCKSOUND
  1508.                             EmitSoundToClient(client, SOUND_BUTTON_UNLOCK, _, _, _, _, LOCKVOL);
  1509. #endif
  1510.                             g_RotLocked[client] = false;
  1511.                         }
  1512.                     }
  1513.                 }
  1514.                 else if((buttons & IN_ATTACK) != IN_ATTACK)
  1515.                 {
  1516.                     g_HoldingLMB[client] = false;
  1517.                 }
  1518.  
  1519.                 if((buttons & IN_ATTACK2) == IN_ATTACK2 && !g_HoldingRMB[client])
  1520.                 {
  1521.                     g_HoldingRMB[client] = true;
  1522.                     if(g_First[client])
  1523.                     {
  1524.                         PrintHintText(client, "Third Person mode selected");
  1525.                         SwitchView(client, true, false);
  1526.                     }
  1527.                     else
  1528.                     {
  1529.                         PrintHintText(client, "First Person mode selected");
  1530.                         SwitchView(client, false, false);
  1531.                     }
  1532.  
  1533.                 }
  1534.                 else
  1535.                 if((buttons & IN_ATTACK2) != IN_ATTACK2)
  1536.                 {
  1537.                     g_HoldingRMB[client] = false;
  1538.                 }
  1539. #if defined CHARGE
  1540.                 if((buttons & IN_RELOAD) == IN_RELOAD)
  1541.                 {
  1542.                     if(!g_Charge[client])
  1543.                     {
  1544.                         g_Charge[client] = true;
  1545.                         SetEntData(client, g_offsCollisionGroup, COLLISION_GROUP_DEBRIS_TRIGGER, _, true);
  1546.                         TF2_SetPlayerClass(client, TFClass_DemoMan, false);
  1547.                         //TF2_AddCondition(client, TFCond_Charging);
  1548.                         CreateTimer(2.5, Timer_Charge, client);
  1549.                     }
  1550.                 }
  1551. #endif
  1552.             }
  1553.             else
  1554.             if(GetClientTeam(client) == TEAM_BLUE && TF2_GetPlayerClass(client) == TFClass_Pyro)
  1555.             {
  1556.                 if(IsValidEntity(GetPlayerWeaponSlot(client, 1)) && GetEntProp(GetPlayerWeaponSlot(client, 1), Prop_Send, "m_iItemDefinitionIndex") == WEP_SHOTGUNPYRO || IsValidEntity(GetPlayerWeaponSlot(client, 1)) && GetEntProp(GetPlayerWeaponSlot(client, 1), Prop_Send, "m_iItemDefinitionIndex") == WEP_SHOTGUN_UNIQUE)
  1557.                 {
  1558.                     SetEntData(client, FindDataMapOffs(client, "m_iAmmo") + 8, SHOTGUN_MAX_AMMO-GetEntData(GetPlayerWeaponSlot(client, 1), FindSendPropInfo("CBaseCombatWeapon", "m_iClip1")));
  1559.                     if(GetEntData(GetPlayerWeaponSlot(client, 1), FindSendPropInfo("CBaseCombatWeapon", "m_iClip1")) > SHOTGUN_MAX_AMMO)
  1560.                     {
  1561.                         SetEntData(GetPlayerWeaponSlot(client, 1), FindSendPropInfo("CBaseCombatWeapon", "m_iClip1"), SHOTGUN_MAX_AMMO);
  1562.                     }
  1563.                 }
  1564.             }
  1565.  
  1566.         } // alive
  1567.     } // in game
  1568. }
  1569.  
  1570. #if defined CHARGE
  1571. public Action:Timer_Charge(Handle:timer, any:client)
  1572. {
  1573.     if(IsClientInGame(client) && IsPlayerAlive(client))
  1574.     {
  1575.         g_Charge[client] = false;
  1576.         SetEntData(client, g_offsCollisionGroup, COLLISION_GROUP_PLAYER, _, true);
  1577.         TF2_SetPlayerClass(client, TFClass_Scout, false);
  1578.     }
  1579.     return Plugin_Handled;
  1580. }
  1581. #endif
  1582.  
  1583. public Action:Event_teamplay_round_start_pre(Handle:event, const String:name[], bool:dontBroadcast)
  1584. {
  1585.     new bool:reset = GetEventBool(event, "full_reset");
  1586. #if defined LOG
  1587.     LogMessage("[PH] teamplay round start: %i, %i", reset, g_RoundOver);
  1588. #endif
  1589.     // checking for the first time this calls (pre-setup), i think
  1590.     if(reset && g_RoundOver)
  1591.     {
  1592.         new team, zteam=TEAM_BLUE;
  1593.         for(new client=1; client <= MaxClients; client++)
  1594.         {
  1595.             if(IsClientInGame(client))
  1596.             {
  1597.  
  1598.                 team = GetClientTeam(client);
  1599.  
  1600.                 // prevent sitting out
  1601.                 if(team == TEAM_SPEC && !g_Spec[client])
  1602.                 {
  1603.                     ChangeClientTeam(client, zteam);
  1604.                     zteam = zteam == TEAM_BLUE ? TEAM_RED:TEAM_BLUE;
  1605.                 }
  1606.  
  1607.             }
  1608.         }
  1609.     }
  1610. }
  1611.  
  1612. public Action:Event_arena_round_start(Handle:event, const String:name[], bool:dontBroadcast)
  1613. {
  1614. #if defined LOG
  1615.     LogMessage("[PH] round start - %i", g_RoundOver );
  1616. #endif
  1617.     g_LastProp = false;
  1618.     if(g_RoundOver)
  1619.     {
  1620.  
  1621.         for(new client=1; client <= MaxClients; client++)
  1622.         {
  1623.             if(IsClientInGame(client) && IsPlayerAlive(client))
  1624.             {
  1625.                 if(GetClientTeam(client) == TEAM_RED)
  1626.                     Timer_DoEquip(INVALID_HANDLE, client);
  1627.                 if(GetClientTeam(client) == TEAM_BLUE)
  1628.                     Timer_DoEquipBlu(INVALID_HANDLE, client);
  1629.             }
  1630.         }
  1631.        
  1632.         SetupRoundTime(g_RoundTime);
  1633.        
  1634.         //GameMode Explanation
  1635.         decl String:message[256];
  1636.         new ent;
  1637.         ent=FindEntityByClassname(-1, "tf_gamerules");
  1638.  
  1639.         //BLU
  1640.         Format(message, sizeof(message), "%T", "message blu", LANG_SERVER);
  1641.         SetVariantString(message);
  1642.         AcceptEntityInput(ent, "SetBlueTeamGoalString");
  1643.         SetVariantString("2");
  1644.         AcceptEntityInput(ent, "SetRedTeamRole");
  1645.  
  1646.         //RED
  1647.         Format(message, sizeof(message), "%T", "message red", LANG_SERVER);
  1648.         SetVariantString(message);
  1649.         AcceptEntityInput(ent, "SetRedTeamGoalString");
  1650.         SetVariantString("1");
  1651.         AcceptEntityInput(ent, "SetRedTeamRole");
  1652.  
  1653.         CreateTimer(0.1, Timer_Info);
  1654.  
  1655.         g_TimerSound30 = CreateTimer(0.1, Timer_Sound30, _, TIMER_FLAG_NO_MAPCHANGE);
  1656.         g_TimerSound20 = CreateTimer(10.0, Timer_Sound20, _, TIMER_FLAG_NO_MAPCHANGE);
  1657.         g_TimerSound10 = CreateTimer(20.0, Timer_Sound10, _, TIMER_FLAG_NO_MAPCHANGE);
  1658.         g_TimerSound5 = CreateTimer(25.0, Timer_Sound5, _, TIMER_FLAG_NO_MAPCHANGE);
  1659.         g_TimerSound4 = CreateTimer(26.0, Timer_Sound4, _, TIMER_FLAG_NO_MAPCHANGE);
  1660.         g_TimerSound3 = CreateTimer(27.0, Timer_Sound3, _, TIMER_FLAG_NO_MAPCHANGE);
  1661.         g_TimerSound2 = CreateTimer(28.0, Timer_Sound2, _, TIMER_FLAG_NO_MAPCHANGE);
  1662.         g_TimerSound1 = CreateTimer(29.0, Timer_Sound1, _, TIMER_FLAG_NO_MAPCHANGE);
  1663.         g_TimerStart = CreateTimer(30.0, Timer_Start, _, TIMER_FLAG_NO_MAPCHANGE);
  1664.        
  1665. #if defined STATS
  1666.         g_StartTime = GetTime();
  1667. #endif
  1668.     }
  1669. }
  1670.  
  1671. public SetupRoundTime(time)
  1672. {
  1673.     g_RoundTimer = CreateTimer(float(time-1), Timer_TimeUp, _, TIMER_FLAG_NO_MAPCHANGE);
  1674.     SetConVarInt(FindConVar("tf_arena_round_time"), time, true, false);
  1675. }
  1676.  
  1677. public Action:Timer_Sound30(Handle:timer, any:client)
  1678. {
  1679.     EmitSoundToAll(SOUND_COUNT30, _, _, SNDLEVEL_AIRCRAFT);
  1680.     g_TimerSound30 = INVALID_HANDLE;
  1681.     return Plugin_Handled;
  1682. }
  1683. public Action:Timer_Sound20(Handle:timer, any:client)
  1684. {
  1685.     EmitSoundToAll(SOUND_COUNT20, _, _, SNDLEVEL_AIRCRAFT);
  1686.     g_TimerSound20 = INVALID_HANDLE;
  1687.     return Plugin_Handled;
  1688. }
  1689. public Action:Timer_Sound10(Handle:timer, any:client)
  1690. {
  1691.     EmitSoundToAll(SOUND_COUNT10, _, _, SNDLEVEL_AIRCRAFT);
  1692.     g_TimerSound10 = INVALID_HANDLE;
  1693.     return Plugin_Handled;
  1694. }
  1695. public Action:Timer_Sound5(Handle:timer, any:client)
  1696. {
  1697.     EmitSoundToAll(SOUND_COUNT5, _, _, SNDLEVEL_AIRCRAFT);
  1698.     g_TimerSound5 = INVALID_HANDLE;
  1699.     return Plugin_Handled;
  1700. }
  1701. public Action:Timer_Sound4(Handle:timer, any:client)
  1702. {
  1703.     EmitSoundToAll(SOUND_COUNT4, _, _, SNDLEVEL_AIRCRAFT);
  1704.     g_TimerSound4 = INVALID_HANDLE;
  1705.     return Plugin_Handled;
  1706. }
  1707. public Action:Timer_Sound3(Handle:timer, any:client)
  1708. {
  1709.     EmitSoundToAll(SOUND_COUNT3, _, _, SNDLEVEL_AIRCRAFT);
  1710.     g_TimerSound3 = INVALID_HANDLE;
  1711.     return Plugin_Handled;
  1712. }
  1713. public Action:Timer_Sound2(Handle:timer, any:client)
  1714. {
  1715.     EmitSoundToAll(SOUND_COUNT2, _, _, SNDLEVEL_AIRCRAFT);
  1716.     g_TimerSound2 = INVALID_HANDLE;
  1717.     return Plugin_Handled;
  1718. }
  1719. public Action:Timer_Sound1(Handle:timer, any:client)
  1720. {
  1721.     EmitSoundToAll(SOUND_COUNT1, _, _, SNDLEVEL_AIRCRAFT);
  1722.     g_TimerSound1 = INVALID_HANDLE;
  1723.     return Plugin_Handled;
  1724. }
  1725.  
  1726. public Action:Timer_Info(Handle:timer, any:client)
  1727. {
  1728.     g_Message_bit++;
  1729.  
  1730.     if(g_Message_bit == 2)
  1731.     {
  1732.         SetHudTextParamsEx(-1.0, 0.22, 5.0, {0,204,255,255}, {0,0,0,255}, 2, 1.0, 0.05, 0.5);
  1733.         for(new i=1; i <= MaxClients; i++)
  1734.         {
  1735.             if(IsClientInGame(i) && !IsFakeClient(i))
  1736.             {
  1737.                 ShowSyncHudText(i, g_Text1, "PropHunt %s", g_Version);
  1738.             }
  1739.         }
  1740.     }
  1741.     else if(g_Message_bit == 3)
  1742.     {
  1743.         SetHudTextParamsEx(-1.0, 0.25, 4.0, {255,128,0,255}, {0,0,0,255}, 2, 1.0, 0.05, 0.5);
  1744.         for(new i=1; i <= MaxClients; i++)
  1745.         {
  1746.             if(IsClientInGame(i) && !IsFakeClient(i))
  1747.             {
  1748.                 ShowSyncHudText(i, g_Text2, "By Darkimmortal");
  1749.             }
  1750.         }
  1751.     }
  1752.     else if(g_Message_bit == 4 && strlen(g_AdText) > 0)
  1753.     {
  1754.         SetHudTextParamsEx(-1.0, 0.3, 3.0, {0,220,0,255}, {0,0,0,255}, 2, 1.0, 0.05, 0.5);
  1755.         for(new i=1; i <= MaxClients; i++)
  1756.         {
  1757.             if(IsClientInGame(i) && !IsFakeClient(i))
  1758.             {
  1759.                 ShowSyncHudText(i, g_Text3, g_AdText);
  1760.             }
  1761.         }
  1762.     }
  1763.    
  1764.     if(g_Message_bit < 10 && IsValidEntity(g_Message_red) && IsValidEntity(g_Message_blue))
  1765.     {
  1766.         AcceptEntityInput(g_Message_red, "Display");
  1767.         AcceptEntityInput(g_Message_blue, "Display");
  1768.         CreateTimer(1.0, Timer_Info);
  1769.     }
  1770. }
  1771.  
  1772.  
  1773.  
  1774. public Action:Timer_Start(Handle:timer, any:client)
  1775. {
  1776. #if defined LOG
  1777.     LogMessage("[PH] Timer_Start");
  1778. #endif
  1779.     g_RoundOver = false;
  1780.  
  1781.     for(new client2=1; client2 <= MaxClients; client2++)
  1782.     {
  1783.         if(IsClientInGame(client2) && IsPlayerAlive(client2) && GetClientTeam(client2) == TEAM_BLUE)
  1784.         {
  1785.             SetEntityMoveType(client2, MOVETYPE_WALK);
  1786.         }
  1787.     }
  1788.     PrintToChatAll("%t", "ready");
  1789.     EmitSoundToAll(SOUND_BEGIN, _, _, SNDLEVEL_AIRCRAFT);
  1790.  
  1791.     new ent;
  1792.     if(g_Doors)
  1793.     {
  1794.         while ((ent = FindEntityByClassname(ent, "func_door")) != -1)
  1795.         {
  1796.             AcceptEntityInput(ent, "Open");
  1797.         }
  1798.     }
  1799.  
  1800.     if(g_Relay)
  1801.     {
  1802.         decl String:name[128];
  1803.         while ((ent = FindEntityByClassname(ent, "logic_relay")) != -1)
  1804.         {
  1805.             GetEntPropString(ent, Prop_Data, "m_iName", name, sizeof(name));
  1806.             if(strcmp(name, "hidingover", false) == 0)
  1807.                 AcceptEntityInput(ent, "Trigger");
  1808.         }
  1809.     }
  1810.     g_TimerStart = INVALID_HANDLE;
  1811.     return Plugin_Handled;
  1812.  
  1813. }
  1814.  
  1815. public Action:Event_player_changeclass(Handle:event, const String:name[], bool:dontBroadcast)
  1816. {
  1817.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  1818.     new class = GetEventInt(event, "class");
  1819.     if(GetClientTeam(client) == TEAM_BLUE)
  1820.     {
  1821.         if (TFClassType:class == TFClass_Heavy && g_Heavy_count <= 2)
  1822.             g_Heavy_count++;
  1823.         else
  1824.         if (TFClassType:class == TFClass_Heavy)
  1825.         {
  1826.             TF2_SetPlayerClass(client, TFClassType:TFClass_Pyro);
  1827.             PrintToChat(client, "There are too many Heavies!");
  1828.             EmitSoundToClient(client, SOUND_BUTTON_DISABLED);
  1829.         }
  1830.  
  1831.         if (TF2_GetPlayerClass(client) == TFClass_Heavy)
  1832.             g_Heavy_count--;
  1833.     }
  1834.     return Plugin_Handled;
  1835. }
  1836.  
  1837. public Action:Event_player_spawn(Handle:event, const String:name[], bool:dontBroadcast)
  1838. {
  1839.  
  1840.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  1841.  
  1842.  
  1843.     if(IsClientInGame(client) && IsPlayerAlive(client))
  1844.     {
  1845.         // stupid glitch fix
  1846.         if(!g_RoundOver && !g_AllowedSpawn[client])
  1847.         {
  1848.             ForcePlayerSuicide(client);
  1849.             return Plugin_Continue;
  1850.         }
  1851.         RemoveAnimeModel(client);
  1852.         SDKHook(client, SDKHook_OnTakeDamage, TakeDamageHook);
  1853.         SDKHook(client, SDKHook_PreThink, PreThinkHook);
  1854. #if defined LOG
  1855.         LogMessage("[PH] Player spawn %N", client);
  1856. #endif
  1857.         g_Hit[client] = false;
  1858.  
  1859.         if(GetClientTeam(client) == TEAM_BLUE)
  1860.         {
  1861.  
  1862.             PrintToChat(client, "%t", "wait");
  1863. #if defined SHINX
  1864.             if(TF2_GetPlayerClass(client) != TFClass_Pyro && TF2_GetPlayerClass(client) != TFClass_Heavy && TF2_GetPlayerClass(client) != TFClass_Sniper &&
  1865.                TF2_GetPlayerClass(client) != TFClass_DemoMan && TF2_GetPlayerClass(client) != TFClass_Soldier &&
  1866.                TF2_GetPlayerClass(client) != TFClass_Medic && TF2_GetPlayerClass(client) != TFClass_Engineer)
  1867.             {
  1868.                 TF2_SetPlayerClass(client, TFClassType:TFClass_Pyro);
  1869.                 TF2_RespawnPlayer(client);
  1870.                 return Plugin_Continue;
  1871.             }
  1872. #else
  1873.             if(TF2_GetPlayerClass(client) != TFClass_Pyro)
  1874.             {
  1875.                 TF2_SetPlayerClass(client, TFClassType:TFClass_Pyro);
  1876.                 TF2_RespawnPlayer(client);
  1877.                 return Plugin_Continue;
  1878.             }
  1879. #endif
  1880.             CreateTimer(0.1, Timer_DoEquipBlu, client);
  1881.  
  1882.         }
  1883.         else
  1884.         if(GetClientTeam(client) == TEAM_RED)
  1885.         {
  1886.             SetVariantString("");
  1887.             AcceptEntityInput(client, "DisableShadow");
  1888.  
  1889.             if(_:TF2_GetPlayerClass(client) != CLASS_RED)
  1890.             {
  1891.                 TF2_SetPlayerClass(client, TFClassType:CLASS_RED);
  1892.                 TF2_RespawnPlayer(client);
  1893.                 return Plugin_Continue;
  1894.             }
  1895.  
  1896.         }
  1897.  
  1898.     }
  1899.     return Plugin_Continue;
  1900. }
  1901.  
  1902. public Action:Timer_DoEquipBlu(Handle:timer, any:client)
  1903. {
  1904.     if(IsClientInGame(client) && IsPlayerAlive(client))
  1905.     {
  1906.         if(g_Freeze)
  1907.             SetEntityMoveType(client, MOVETYPE_NONE);
  1908.  
  1909.         SwitchView(client, false, true);
  1910.         SetAlpha(client, 255);
  1911.  
  1912.         new slot0 = GetPlayerWeaponSlot(client, 0);
  1913.         new slot1 = GetPlayerWeaponSlot(client, 1);
  1914.         new slot2 = GetPlayerWeaponSlot(client, 2);
  1915.  
  1916.         if(TF2_GetPlayerClass(client) == TFClass_Sniper)
  1917.         {
  1918.             if(slot0 > MaxClients && IsValidEntity(slot0) && GetEntProp(slot0, Prop_Send, "m_iItemDefinitionIndex") == WEP_SNIPER || slot0 > MaxClients && IsValidEntity(slot0) && GetEntProp(slot0, Prop_Send, "m_iItemDefinitionIndex") == WEP_SNIPER_UNIQUE || slot0 > MaxClients && IsValidEntity(slot0) && GetEntProp(slot0, Prop_Send, "m_iItemDefinitionIndex") == WEP_SYDNEYSLEEPER || slot0 > MaxClients && IsValidEntity(slot0) && GetEntProp(slot0, Prop_Send, "m_iItemDefinitionIndex") == WEP_BARGIN)
  1919.             {
  1920.                 TF2_RemoveWeaponSlot(client, 0);
  1921.             }
  1922.             if(slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_SMG || slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_SMG_UNIQUE)
  1923.             {
  1924.                 TF2_RemoveWeaponSlot(client, 1);
  1925.             }
  1926.         }
  1927.         else
  1928.         if(TF2_GetPlayerClass(client) == TFClass_Pyro)
  1929.         {
  1930.             if(slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_SHOTGUNPYRO || slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_SHOTGUN_UNIQUE)
  1931.             {
  1932.                 SetEntData(GetPlayerWeaponSlot(client, 1), FindSendPropInfo("CBaseCombatWeapon", "m_iClip1"), SHOTGUN_MAX_AMMO);
  1933.             }
  1934.         }
  1935.         else
  1936.         if(TF2_GetPlayerClass(client) == TFClass_DemoMan)
  1937.         {
  1938.             TF2_RemoveWeaponSlot(client, 0);
  1939.             TF2_RemoveWeaponSlot(client, 1);
  1940.         }
  1941.         else
  1942.         if(TF2_GetPlayerClass(client) == TFClass_Heavy)
  1943.         {
  1944.             if(slot0 > MaxClients && IsValidEntity(slot0) && GetEntProp(slot0, Prop_Send, "m_iItemDefinitionIndex") == WEP_NATASCHA)
  1945.             {
  1946.                 TF2_RemoveWeaponSlot(client, 0);
  1947.             }
  1948.         }
  1949.         else
  1950.         if(TF2_GetPlayerClass(client) == TFClass_Medic)
  1951.         {
  1952.             if(slot0 > MaxClients && IsValidEntity(slot0) && GetEntProp(slot0, Prop_Send, "m_iItemDefinitionIndex") == WEP_BLUTSAUGER)
  1953.             {
  1954.                 TF2_RemoveWeaponSlot(client, 0);
  1955.             }
  1956.             if(slot0 > MaxClients && IsValidEntity(slot0) && GetEntProp(slot0, Prop_Send, "m_iItemDefinitionIndex") == WEP_CRUSADERSCROSSBOW)
  1957.             {
  1958.                 TF2_RemoveWeaponSlot(client, 0);
  1959.             }
  1960.             if(slot2 > MaxClients && IsValidEntity(slot2) && GetEntProp(slot2, Prop_Send, "m_iItemDefinitionIndex") == WEP_AMPUTATOR || slot2 > MaxClients && IsValidEntity(slot2) && GetEntProp(slot2, Prop_Send, "m_iItemDefinitionIndex") == WEP_VOW)
  1961.             {
  1962.                 TF2_RemoveWeaponSlot(client, 2);
  1963.             }
  1964.             TF2_RemoveWeaponSlot(client, 1);
  1965.         }
  1966.         else
  1967.         if(TF2_GetPlayerClass(client) == TFClass_Engineer)
  1968.         {
  1969.             if(slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_LUGERMORPH || slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_ENGINIEERPISTOL || slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_PISTOL_UNIQUE || slot1 > MaxClients && IsValidEntity(slot1) && GetEntProp(slot1, Prop_Send, "m_iItemDefinitionIndex") == WEP_LUGERMORPH_2)
  1970.             {
  1971.                 TF2_RemoveWeaponSlot(client, 1);
  1972.             }
  1973.         }
  1974.     }
  1975.     return Plugin_Handled;
  1976. }
  1977.  
  1978. public Action:Command_motd(client, args)
  1979. {
  1980.     if(IsClientInGame(client))
  1981.     {
  1982.         ShowMOTDPanel(client, "PropHunt Stats", "http://www.gamingmasters.co.uk/prophunt/index.php", MOTDPANEL_TYPE_URL);
  1983.     }
  1984.     return Plugin_Handled;
  1985. }
  1986.  
  1987. public Action:Timer_DoEquip(Handle:timer, any:client)
  1988. {
  1989.  
  1990.     if(IsClientInGame(client))
  1991.     {
  1992. #if defined LOG
  1993.         LogMessage("[PH] do equip %N", client);
  1994. #endif
  1995.         // slot commands fix "remember last weapon" glitch, despite their client console spam
  1996.         FakeClientCommand(client, "slot0");
  1997.         FakeClientCommand(client, "slot3");
  1998.         TF2_RemoveAllWeapons(client);
  1999.         FakeClientCommand(client, "slot3");
  2000.         FakeClientCommand(client, "slot0");
  2001.     }
  2002.  
  2003.     if(IsClientInGame(client) && IsPlayerAlive(client))
  2004.     {
  2005.  
  2006.         decl String:pname[32];
  2007.         Format(pname, sizeof(pname), "ph_player_%i", client);
  2008.         DispatchKeyValue(client, "targetname", pname);
  2009.  
  2010.         // fire in a nice random model
  2011.         decl String:model[MAXMODELNAME], String:offset[32];
  2012.         new RandomInt = GetRandomInt(0, GetArraySize(g_ModelName)-1);
  2013.         if(strlen(g_PlayerModel[client]) > 1)
  2014.         {
  2015.             model = g_PlayerModel[client];
  2016.         }
  2017.         else
  2018.         {
  2019.             GetArrayString(g_ModelName, RandomInt, model, sizeof(model));
  2020.         }
  2021.         decl String:nicemodel[MAXMODELNAME], String:nicemodel2[MAXMODELNAME];
  2022.        
  2023.         new lastslash = FindCharInString(model, '/', true)+1;
  2024.         strcopy(nicemodel, sizeof(nicemodel), model[lastslash]);
  2025.         ReplaceString(nicemodel, sizeof(nicemodel), ".mdl", "");
  2026.        
  2027.         KvGotoFirstSubKey(g_PropNames);
  2028.         KvJumpToKey(g_PropNames, "names", false);
  2029.         KvGetString(g_PropNames, nicemodel, nicemodel2, sizeof(nicemodel2));
  2030.         if (strlen(nicemodel2) > 0)
  2031.             strcopy(nicemodel, sizeof(nicemodel), nicemodel2);
  2032.         PrintToChat(client, "%t", "now disguised", nicemodel);
  2033.         GetArrayString(g_ModelOffset, RandomInt, offset, sizeof(offset));
  2034.         g_PlayerModel[client] = model;
  2035.         SetVariantString(model);
  2036.         AcceptEntityInput(client, "SetCustomModel");
  2037.         SetVariantString(offset);
  2038.         AcceptEntityInput(client, "SetCustomModelOffset");
  2039.         SetVariantInt(1);
  2040.         AcceptEntityInput(client, "SetCustomModelRotates");
  2041.         SwitchView(client, true, false);
  2042.     }
  2043.     return Plugin_Handled;
  2044. }
  2045.  
  2046. stock SetAlpha (target, alpha){
  2047.     SetWeaponsAlpha(target,alpha);
  2048.     SetEntityRenderMode(target, RENDER_TRANSCOLOR);
  2049.     SetEntityRenderColor(target, 255, 255, 255, alpha);
  2050. }
  2051.  
  2052. public Action:Timer_Ragdoll(Handle:timer, any:client)
  2053. {
  2054.     if(IsClientInGame(client))
  2055.     {
  2056.         new rag = GetEntPropEnt(client, Prop_Send, "m_hRagdoll");
  2057.         if(rag > MaxClients && IsValidEntity(rag))
  2058.             AcceptEntityInput(rag, "Kill");
  2059.     }
  2060.     return Plugin_Handled;
  2061. }
  2062.  
  2063. stock SetWeaponsAlpha (target, alpha){
  2064.     if(IsPlayerAlive(target))
  2065.     {
  2066.         decl String:classname[64];
  2067.         new m_hMyWeapons = FindSendPropOffs("CBasePlayer", "m_hMyWeapons");
  2068.         for(new i = 0, weapon; i < 47; i += 4)
  2069.         {
  2070.             weapon = GetEntDataEnt2(target, m_hMyWeapons + i);
  2071.             if(weapon > -1 && IsValidEdict(weapon))
  2072.             {
  2073.                 GetEdictClassname(weapon, classname, sizeof(classname));
  2074.                 if(StrContains(classname, "tf_weapon", false) != -1)
  2075.                 {
  2076.                     SetEntityRenderMode(weapon, RENDER_TRANSCOLOR);
  2077.                     SetEntityRenderColor(weapon, 255, 255, 255, alpha);
  2078.                 }
  2079.             }
  2080.         }
  2081.     }
  2082. }
  2083.  
  2084. public Action:Event_player_death(Handle:event, const String:name[], bool:dontBroadcast)
  2085. {
  2086.  
  2087.     if (GetEventInt(event, "weaponid") == TF_WEAPON_BAT_FISH && GetEventInt(event, "customkill") == TF_CUSTOM_FISH_KILL)
  2088.     {
  2089.         return Plugin_Continue;
  2090.     }
  2091.    
  2092.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  2093.  
  2094.     if(IsClientInGame(client))
  2095.     {
  2096. #if defined LOG
  2097.         LogMessage("[PH] Player death %N", client);
  2098. #endif
  2099.         //RemoveAnimeModel(client);
  2100.  
  2101.         CreateTimer(0.1, Timer_Ragdoll, client);
  2102.  
  2103.         SDKUnhook(client, SDKHook_OnTakeDamage, TakeDamageHook);
  2104.         SDKUnhook(client, SDKHook_PreThink, PreThinkHook);
  2105.     }
  2106.  
  2107.     new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
  2108.     new assister = GetClientOfUserId(GetEventInt(event, "assister"));
  2109.    
  2110. #if defined STATS
  2111.     decl String:weapon[64];
  2112.     new assisterID = GetEventInt(event, "assister");
  2113.     new attackerID = GetEventInt(event, "attacker");
  2114.     new clientID = GetEventInt(event, "userid");
  2115.     new weaponid = GetEventInt(event, "weaponid");
  2116.     GetEventString(event, "weapon", weapon, sizeof(weapon));
  2117. #endif
  2118.  
  2119.     if(!g_RoundOver)
  2120.         g_Spawned[client] = false;
  2121.  
  2122.     g_Hit[client] = false;
  2123.  
  2124.     new playas = 0;
  2125.     for(new i=1; i <= MaxClients; i++)
  2126.     {
  2127.         if(IsClientInGame(i) /*&& !IsFakeClient(i)*/ && IsPlayerAlive(i) && GetClientTeam(i) == TEAM_RED)
  2128.         {
  2129.             playas++;
  2130.         }
  2131.     }
  2132.  
  2133.  
  2134.     if(!g_RoundOver && GetClientTeam(client) == TEAM_RED)
  2135.     {
  2136.  
  2137.         EmitSoundToClient(client, SOUND_SNAAAKE);
  2138.     }
  2139.  
  2140.     if(!g_RoundOver)
  2141.     {
  2142.         if(client > 0 && attacker > 0 && IsClientInGame(client) && IsClientInGame(attacker) && client != attacker)
  2143.         {
  2144.             if(GetClientTeam(client) == GetClientTeam(attacker))
  2145.             {
  2146.             }
  2147.             else
  2148.             {
  2149. #if defined STATS
  2150.                 PlayerKilled(clientID, attackerID, assisterID, weaponid, weapon);
  2151. #endif
  2152.                 if(IsPlayerAlive(attacker))
  2153.                 {
  2154.                     Speedup(attacker, 50);
  2155.                     FillHealth(attacker);
  2156.                 }
  2157.             }
  2158.             if(assister > 0 && IsClientInGame(assister))
  2159.             {
  2160.                 if(IsPlayerAlive(assister))
  2161.                 {
  2162.                     Speedup(assister, 50);
  2163.                     FillHealth(assister);
  2164.                 }
  2165.             }
  2166.         }
  2167.     }
  2168.  
  2169.     if(playas == 2 && !g_RoundOver && GetClientTeam(client) == TEAM_RED)
  2170.     {
  2171.         g_LastProp = true;
  2172.         EmitSoundToAll(SOUND_ONEANDONLY, _, _, SNDLEVEL_AIRCRAFT);
  2173. #if defined SCATTERGUN
  2174.         for(new client2=1; client2 <= MaxClients; client2++)
  2175.         {
  2176.             if(IsClientInGame(client2) && !IsFakeClient(client2) && IsPlayerAlive(client2))
  2177.             {
  2178.                 if(GetClientTeam(client2) == TEAM_RED)
  2179.                 {
  2180.                     TF2_RegeneratePlayer(client2);
  2181.                     CreateTimer(0.2, Timer_WeaponAlpha, client2);
  2182.                 }
  2183.                 else
  2184.                 if(GetClientTeam(client2) == TEAM_BLUE)
  2185.                 {
  2186.                     //TF2_AddCondition(client2, TFCond_Jarated, 15.0);
  2187.                 }
  2188.             }
  2189.         }
  2190. #endif
  2191.     }
  2192.     SetVariantString("ParticleEffectStop");
  2193.     AcceptEntityInput(client, "DispatchEffect");
  2194.     return Plugin_Continue;
  2195. }
  2196.  
  2197. public Action:Timer_WeaponAlpha(Handle:timer, any:client)
  2198. {
  2199.     if(IsClientInGame(client) && IsPlayerAlive(client))
  2200.         SetWeaponsAlpha(client, 0);
  2201. }
  2202.  
  2203. stock Speedup (client, inc){
  2204.     new Float:speed = GetEntDataFloat(client, FindSendPropInfo("CTFPlayer", "m_flMaxspeed")) + inc;
  2205.     if(speed > 400) speed = 400.0;
  2206.     SetEntDataFloat(client, FindSendPropInfo("CTFPlayer", "m_flMaxspeed"), speed);
  2207. }
  2208.  
  2209. public bool:TraceRayDontHitSelf(entity, mask, any:data)
  2210. {
  2211.     return entity != data;
  2212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement