Advertisement
FlacoBey

Untitled

Jan 19th, 2019
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 130.79 KB | None | 0 0
  1. #define PLUGIN_VERSION "1.1"
  2.  
  3. /*=======================================================================================
  4. Plugin Info:
  5.  
  6. * Name : [L4D & L4D2] Special Infected Ability Movement
  7. * Author : SilverShot
  8. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  9. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  10.  
  11. ========================================================================================
  12. Change Log:
  13.  
  14. 1.1 (23-Aug-2018)
  15. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  16.  
  17. 1.0 (05-May-2018)
  18. - Initial release.
  19.  
  20. ======================================================================================*/
  21.  
  22. #pragma semicolon 1
  23. #pragma newdecls required
  24.  
  25. #include <sourcemod>
  26. #include <sdktools>
  27. #include <sdkhooks>
  28.  
  29. #define CVAR_FLAGS FCVAR_NOTIFY
  30.  
  31.  
  32. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  33. int g_iCvarAllow, g_iCvarType;
  34. bool g_bCvarAllow, g_bLeft4Dead2;
  35. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  36.  
  37. enum ()
  38. {
  39. ENUM_SMOKE = 1,
  40. ENUM_SPITS = 2,
  41. ENUM_TANKS = 4
  42. }
  43.  
  44.  
  45.  
  46. // ====================================================================================================
  47. // PLUGIN INFO / START / END
  48. // ====================================================================================================
  49. public Plugin myinfo =
  50. {
  51. name = "[L4D & L4D2] Special Infected Ability Movement",
  52. author = "SilverShot",
  53. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  54. version = PLUGIN_VERSION,
  55. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  56. }
  57.  
  58. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  59. {
  60. EngineVersion test = GetEngineVersion();
  61. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  62. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  63. else
  64. {
  65. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  66. return APLRes_SilentFailure;
  67. }
  68. return APLRes_Success;
  69. }
  70.  
  71. public void OnPluginStart()
  72. {
  73. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  74. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  75. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  76. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  77. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  78. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  79. AutoExecConfig(true, "l4d_infected_movement");
  80.  
  81. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  82. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  83. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  84. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  85. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  86. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  87. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  88.  
  89. g_hSpeedTank = FindConVar("z_tank_speed");
  90. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  91. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  92. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  93.  
  94. if( g_bLeft4Dead2 )
  95. {
  96. g_hSpeedSpit = FindConVar("z_spitter_speed");
  97. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  98. }
  99. }
  100.  
  101.  
  102.  
  103. // ====================================================================================================
  104. // CVARS
  105. // ====================================================================================================
  106. public void OnConfigsExecuted()
  107. {
  108. IsAllowed();
  109. }
  110.  
  111. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  112. {
  113. IsAllowed();
  114. }
  115.  
  116. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  117. {
  118. GetCvars();
  119. }
  120.  
  121. void GetCvars()
  122. {
  123. if( g_bLeft4Dead2 )
  124. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  125. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  126. g_fSpeedTank = g_hSpeedTank.FloatValue;
  127. g_iCvarType = g_hCvarType.IntValue;
  128. }
  129.  
  130. void IsAllowed()
  131. {
  132. g_iCvarAllow = g_hCvarAllow.IntValue;
  133. bool bAllowMode = IsAllowedGameMode();
  134. GetCvars();
  135.  
  136. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  137. {
  138. g_bCvarAllow = true;
  139. HookEvent("round_end", Event_Reset);
  140. HookEvent("round_start", Event_Reset);
  141. HookEvent("ability_use", Event_Use);
  142. }
  143. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  144. {
  145. g_bCvarAllow = false;
  146. UnhookEvent("round_end", Event_Reset);
  147. UnhookEvent("round_start", Event_Reset);
  148. UnhookEvent("ability_use", Event_Use);
  149. }
  150. }
  151.  
  152. int g_iCurrentMode;
  153. bool IsAllowedGameMode()
  154. {
  155. if( g_hCvarMPGameMode == null )
  156. return false;
  157.  
  158. int iCvarModesTog = g_hCvarModesTog.IntValue;
  159. if( iCvarModesTog != 0 )
  160. {
  161. g_iCurrentMode = 0;
  162.  
  163. int entity = CreateEntityByName("info_gamemode");
  164. DispatchSpawn(entity);
  165. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  166. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  167. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  168. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  169. ActivateEntity(entity);
  170. AcceptEntityInput(entity, "PostSpawnActivate");
  171. AcceptEntityInput(entity, "Kill");
  172.  
  173. if( g_iCurrentMode == 0 )
  174. return false;
  175.  
  176. if( !(iCvarModesTog & g_iCurrentMode) )
  177. return false;
  178. }
  179.  
  180. char sGameModes[64], sGameMode[64];
  181. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  182. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  183.  
  184. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  185. if( strcmp(sGameModes, "") )
  186. {
  187. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  188. if( StrContains(sGameModes, sGameMode, false) == -1 )
  189. return false;
  190. }
  191.  
  192. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  193. if( strcmp(sGameModes, "") )
  194. {
  195. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  196. if( StrContains(sGameModes, sGameMode, false) != -1 )
  197. return false;
  198. }
  199.  
  200. return true;
  201. }
  202.  
  203. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  204. {
  205. if( strcmp(output, "OnCoop") == 0 )
  206. g_iCurrentMode = 1;
  207. else if( strcmp(output, "OnSurvival") == 0 )
  208. g_iCurrentMode = 2;
  209. else if( strcmp(output, "OnVersus") == 0 )
  210. g_iCurrentMode = 4;
  211. else if( strcmp(output, "OnScavenge") == 0 )
  212. g_iCurrentMode = 8;
  213. }
  214.  
  215.  
  216.  
  217. // ====================================================================================================
  218. // EVENTS
  219. // ====================================================================================================
  220. static float g_fTime[MAXPLAYERS+1];
  221.  
  222. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  223. {
  224. ResetPlugin();
  225. }
  226.  
  227. void ResetPlugin()
  228. {
  229. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  230. {
  231. g_fTime[i] = 0.0;
  232. }
  233. }
  234.  
  235. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  236. {
  237. int client = GetClientOfUserId(event.GetInt("userid"));
  238. if( !client || !IsClientInGame(client) ) return;
  239.  
  240.  
  241. // Class check
  242. // Smoker = 1; Spitter = 4; Tank = 8
  243. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  244. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  245. switch( class )
  246. {
  247. case 1: class = 0;
  248. case 4: class = 1;
  249. case 8: class = 2;
  250. default: class = 99;
  251. }
  252. if( !(g_iCvarType & (1 << class)) ) return;
  253.  
  254.  
  255. // Bots check
  256. if( g_iCvarAllow != 3 )
  257. {
  258. bool fake = IsFakeClient(client);
  259. if( g_iCvarAllow == 1 && fake ) return;
  260. if( g_iCvarAllow == 2 && !fake ) return;
  261. }
  262.  
  263.  
  264. // Event check
  265. char sUse[16];
  266. event.GetString("ability", sUse, sizeof(sUse));
  267. if(
  268. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  269. || strcmp(sUse, "ability_throw") == 0
  270. || strcmp(sUse, "ability_tongue") == 0
  271. )
  272. {
  273. if( GetGameTime() - g_fTime[client] >= 3.0 )
  274. {
  275. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  276. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  277. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  278. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  279. }
  280. g_fTime[client] = GetGameTime();
  281. }
  282. }
  283.  
  284. public void onThinkFunk(int client) //Dance
  285. {
  286. if( IsClientInGame(client) )
  287. {
  288. if( GetGameTime() - g_fTime[client] < 3.0 )
  289. {
  290. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  291.  
  292. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  293. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  294. {
  295. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  296. }
  297. } else {
  298. g_fTime[client] = 0.0;
  299. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  300. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  301. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  302. }
  303. }
  304. }#define PLUGIN_VERSION "1.1"
  305.  
  306. /*=======================================================================================
  307. Plugin Info:
  308.  
  309. * Name : [L4D & L4D2] Special Infected Ability Movement
  310. * Author : SilverShot
  311. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  312. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  313.  
  314. ========================================================================================
  315. Change Log:
  316.  
  317. 1.1 (23-Aug-2018)
  318. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  319.  
  320. 1.0 (05-May-2018)
  321. - Initial release.
  322.  
  323. ======================================================================================*/
  324.  
  325. #pragma semicolon 1
  326. #pragma newdecls required
  327.  
  328. #include <sourcemod>
  329. #include <sdktools>
  330. #include <sdkhooks>
  331.  
  332. #define CVAR_FLAGS FCVAR_NOTIFY
  333.  
  334.  
  335. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  336. int g_iCvarAllow, g_iCvarType;
  337. bool g_bCvarAllow, g_bLeft4Dead2;
  338. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  339.  
  340. enum ()
  341. {
  342. ENUM_SMOKE = 1,
  343. ENUM_SPITS = 2,
  344. ENUM_TANKS = 4
  345. }
  346.  
  347.  
  348.  
  349. // ====================================================================================================
  350. // PLUGIN INFO / START / END
  351. // ====================================================================================================
  352. public Plugin myinfo =
  353. {
  354. name = "[L4D & L4D2] Special Infected Ability Movement",
  355. author = "SilverShot",
  356. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  357. version = PLUGIN_VERSION,
  358. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  359. }
  360.  
  361. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  362. {
  363. EngineVersion test = GetEngineVersion();
  364. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  365. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  366. else
  367. {
  368. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  369. return APLRes_SilentFailure;
  370. }
  371. return APLRes_Success;
  372. }
  373.  
  374. public void OnPluginStart()
  375. {
  376. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  377. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  378. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  379. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  380. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  381. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  382. AutoExecConfig(true, "l4d_infected_movement");
  383.  
  384. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  385. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  386. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  387. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  388. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  389. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  390. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  391.  
  392. g_hSpeedTank = FindConVar("z_tank_speed");
  393. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  394. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  395. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  396.  
  397. if( g_bLeft4Dead2 )
  398. {
  399. g_hSpeedSpit = FindConVar("z_spitter_speed");
  400. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  401. }
  402. }
  403.  
  404.  
  405.  
  406. // ====================================================================================================
  407. // CVARS
  408. // ====================================================================================================
  409. public void OnConfigsExecuted()
  410. {
  411. IsAllowed();
  412. }
  413.  
  414. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  415. {
  416. IsAllowed();
  417. }
  418.  
  419. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  420. {
  421. GetCvars();
  422. }
  423.  
  424. void GetCvars()
  425. {
  426. if( g_bLeft4Dead2 )
  427. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  428. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  429. g_fSpeedTank = g_hSpeedTank.FloatValue;
  430. g_iCvarType = g_hCvarType.IntValue;
  431. }
  432.  
  433. void IsAllowed()
  434. {
  435. g_iCvarAllow = g_hCvarAllow.IntValue;
  436. bool bAllowMode = IsAllowedGameMode();
  437. GetCvars();
  438.  
  439. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  440. {
  441. g_bCvarAllow = true;
  442. HookEvent("round_end", Event_Reset);
  443. HookEvent("round_start", Event_Reset);
  444. HookEvent("ability_use", Event_Use);
  445. }
  446. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  447. {
  448. g_bCvarAllow = false;
  449. UnhookEvent("round_end", Event_Reset);
  450. UnhookEvent("round_start", Event_Reset);
  451. UnhookEvent("ability_use", Event_Use);
  452. }
  453. }
  454.  
  455. int g_iCurrentMode;
  456. bool IsAllowedGameMode()
  457. {
  458. if( g_hCvarMPGameMode == null )
  459. return false;
  460.  
  461. int iCvarModesTog = g_hCvarModesTog.IntValue;
  462. if( iCvarModesTog != 0 )
  463. {
  464. g_iCurrentMode = 0;
  465.  
  466. int entity = CreateEntityByName("info_gamemode");
  467. DispatchSpawn(entity);
  468. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  469. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  470. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  471. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  472. ActivateEntity(entity);
  473. AcceptEntityInput(entity, "PostSpawnActivate");
  474. AcceptEntityInput(entity, "Kill");
  475.  
  476. if( g_iCurrentMode == 0 )
  477. return false;
  478.  
  479. if( !(iCvarModesTog & g_iCurrentMode) )
  480. return false;
  481. }
  482.  
  483. char sGameModes[64], sGameMode[64];
  484. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  485. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  486.  
  487. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  488. if( strcmp(sGameModes, "") )
  489. {
  490. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  491. if( StrContains(sGameModes, sGameMode, false) == -1 )
  492. return false;
  493. }
  494.  
  495. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  496. if( strcmp(sGameModes, "") )
  497. {
  498. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  499. if( StrContains(sGameModes, sGameMode, false) != -1 )
  500. return false;
  501. }
  502.  
  503. return true;
  504. }
  505.  
  506. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  507. {
  508. if( strcmp(output, "OnCoop") == 0 )
  509. g_iCurrentMode = 1;
  510. else if( strcmp(output, "OnSurvival") == 0 )
  511. g_iCurrentMode = 2;
  512. else if( strcmp(output, "OnVersus") == 0 )
  513. g_iCurrentMode = 4;
  514. else if( strcmp(output, "OnScavenge") == 0 )
  515. g_iCurrentMode = 8;
  516. }
  517.  
  518.  
  519.  
  520. // ====================================================================================================
  521. // EVENTS
  522. // ====================================================================================================
  523. static float g_fTime[MAXPLAYERS+1];
  524.  
  525. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  526. {
  527. ResetPlugin();
  528. }
  529.  
  530. void ResetPlugin()
  531. {
  532. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  533. {
  534. g_fTime[i] = 0.0;
  535. }
  536. }
  537.  
  538. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  539. {
  540. int client = GetClientOfUserId(event.GetInt("userid"));
  541. if( !client || !IsClientInGame(client) ) return;
  542.  
  543.  
  544. // Class check
  545. // Smoker = 1; Spitter = 4; Tank = 8
  546. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  547. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  548. switch( class )
  549. {
  550. case 1: class = 0;
  551. case 4: class = 1;
  552. case 8: class = 2;
  553. default: class = 99;
  554. }
  555. if( !(g_iCvarType & (1 << class)) ) return;
  556.  
  557.  
  558. // Bots check
  559. if( g_iCvarAllow != 3 )
  560. {
  561. bool fake = IsFakeClient(client);
  562. if( g_iCvarAllow == 1 && fake ) return;
  563. if( g_iCvarAllow == 2 && !fake ) return;
  564. }
  565.  
  566.  
  567. // Event check
  568. char sUse[16];
  569. event.GetString("ability", sUse, sizeof(sUse));
  570. if(
  571. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  572. || strcmp(sUse, "ability_throw") == 0
  573. || strcmp(sUse, "ability_tongue") == 0
  574. )
  575. {
  576. if( GetGameTime() - g_fTime[client] >= 3.0 )
  577. {
  578. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  579. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  580. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  581. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  582. }
  583. g_fTime[client] = GetGameTime();
  584. }
  585. }
  586.  
  587. public void onThinkFunk(int client) //Dance
  588. {
  589. if( IsClientInGame(client) )
  590. {
  591. if( GetGameTime() - g_fTime[client] < 3.0 )
  592. {
  593. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  594.  
  595. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  596. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  597. {
  598. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  599. }
  600. } else {
  601. g_fTime[client] = 0.0;
  602. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  603. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  604. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  605. }
  606. }
  607. }#define PLUGIN_VERSION "1.1"
  608.  
  609. /*=======================================================================================
  610. Plugin Info:
  611.  
  612. * Name : [L4D & L4D2] Special Infected Ability Movement
  613. * Author : SilverShot
  614. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  615. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  616.  
  617. ========================================================================================
  618. Change Log:
  619.  
  620. 1.1 (23-Aug-2018)
  621. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  622.  
  623. 1.0 (05-May-2018)
  624. - Initial release.
  625.  
  626. ======================================================================================*/
  627.  
  628. #pragma semicolon 1
  629. #pragma newdecls required
  630.  
  631. #include <sourcemod>
  632. #include <sdktools>
  633. #include <sdkhooks>
  634.  
  635. #define CVAR_FLAGS FCVAR_NOTIFY
  636.  
  637.  
  638. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  639. int g_iCvarAllow, g_iCvarType;
  640. bool g_bCvarAllow, g_bLeft4Dead2;
  641. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  642.  
  643. enum ()
  644. {
  645. ENUM_SMOKE = 1,
  646. ENUM_SPITS = 2,
  647. ENUM_TANKS = 4
  648. }
  649.  
  650.  
  651.  
  652. // ====================================================================================================
  653. // PLUGIN INFO / START / END
  654. // ====================================================================================================
  655. public Plugin myinfo =
  656. {
  657. name = "[L4D & L4D2] Special Infected Ability Movement",
  658. author = "SilverShot",
  659. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  660. version = PLUGIN_VERSION,
  661. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  662. }
  663.  
  664. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  665. {
  666. EngineVersion test = GetEngineVersion();
  667. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  668. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  669. else
  670. {
  671. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  672. return APLRes_SilentFailure;
  673. }
  674. return APLRes_Success;
  675. }
  676.  
  677. public void OnPluginStart()
  678. {
  679. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  680. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  681. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  682. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  683. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  684. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  685. AutoExecConfig(true, "l4d_infected_movement");
  686.  
  687. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  688. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  689. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  690. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  691. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  692. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  693. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  694.  
  695. g_hSpeedTank = FindConVar("z_tank_speed");
  696. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  697. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  698. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  699.  
  700. if( g_bLeft4Dead2 )
  701. {
  702. g_hSpeedSpit = FindConVar("z_spitter_speed");
  703. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  704. }
  705. }
  706.  
  707.  
  708.  
  709. // ====================================================================================================
  710. // CVARS
  711. // ====================================================================================================
  712. public void OnConfigsExecuted()
  713. {
  714. IsAllowed();
  715. }
  716.  
  717. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  718. {
  719. IsAllowed();
  720. }
  721.  
  722. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  723. {
  724. GetCvars();
  725. }
  726.  
  727. void GetCvars()
  728. {
  729. if( g_bLeft4Dead2 )
  730. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  731. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  732. g_fSpeedTank = g_hSpeedTank.FloatValue;
  733. g_iCvarType = g_hCvarType.IntValue;
  734. }
  735.  
  736. void IsAllowed()
  737. {
  738. g_iCvarAllow = g_hCvarAllow.IntValue;
  739. bool bAllowMode = IsAllowedGameMode();
  740. GetCvars();
  741.  
  742. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  743. {
  744. g_bCvarAllow = true;
  745. HookEvent("round_end", Event_Reset);
  746. HookEvent("round_start", Event_Reset);
  747. HookEvent("ability_use", Event_Use);
  748. }
  749. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  750. {
  751. g_bCvarAllow = false;
  752. UnhookEvent("round_end", Event_Reset);
  753. UnhookEvent("round_start", Event_Reset);
  754. UnhookEvent("ability_use", Event_Use);
  755. }
  756. }
  757.  
  758. int g_iCurrentMode;
  759. bool IsAllowedGameMode()
  760. {
  761. if( g_hCvarMPGameMode == null )
  762. return false;
  763.  
  764. int iCvarModesTog = g_hCvarModesTog.IntValue;
  765. if( iCvarModesTog != 0 )
  766. {
  767. g_iCurrentMode = 0;
  768.  
  769. int entity = CreateEntityByName("info_gamemode");
  770. DispatchSpawn(entity);
  771. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  772. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  773. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  774. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  775. ActivateEntity(entity);
  776. AcceptEntityInput(entity, "PostSpawnActivate");
  777. AcceptEntityInput(entity, "Kill");
  778.  
  779. if( g_iCurrentMode == 0 )
  780. return false;
  781.  
  782. if( !(iCvarModesTog & g_iCurrentMode) )
  783. return false;
  784. }
  785.  
  786. char sGameModes[64], sGameMode[64];
  787. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  788. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  789.  
  790. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  791. if( strcmp(sGameModes, "") )
  792. {
  793. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  794. if( StrContains(sGameModes, sGameMode, false) == -1 )
  795. return false;
  796. }
  797.  
  798. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  799. if( strcmp(sGameModes, "") )
  800. {
  801. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  802. if( StrContains(sGameModes, sGameMode, false) != -1 )
  803. return false;
  804. }
  805.  
  806. return true;
  807. }
  808.  
  809. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  810. {
  811. if( strcmp(output, "OnCoop") == 0 )
  812. g_iCurrentMode = 1;
  813. else if( strcmp(output, "OnSurvival") == 0 )
  814. g_iCurrentMode = 2;
  815. else if( strcmp(output, "OnVersus") == 0 )
  816. g_iCurrentMode = 4;
  817. else if( strcmp(output, "OnScavenge") == 0 )
  818. g_iCurrentMode = 8;
  819. }
  820.  
  821.  
  822.  
  823. // ====================================================================================================
  824. // EVENTS
  825. // ====================================================================================================
  826. static float g_fTime[MAXPLAYERS+1];
  827.  
  828. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  829. {
  830. ResetPlugin();
  831. }
  832.  
  833. void ResetPlugin()
  834. {
  835. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  836. {
  837. g_fTime[i] = 0.0;
  838. }
  839. }
  840.  
  841. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  842. {
  843. int client = GetClientOfUserId(event.GetInt("userid"));
  844. if( !client || !IsClientInGame(client) ) return;
  845.  
  846.  
  847. // Class check
  848. // Smoker = 1; Spitter = 4; Tank = 8
  849. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  850. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  851. switch( class )
  852. {
  853. case 1: class = 0;
  854. case 4: class = 1;
  855. case 8: class = 2;
  856. default: class = 99;
  857. }
  858. if( !(g_iCvarType & (1 << class)) ) return;
  859.  
  860.  
  861. // Bots check
  862. if( g_iCvarAllow != 3 )
  863. {
  864. bool fake = IsFakeClient(client);
  865. if( g_iCvarAllow == 1 && fake ) return;
  866. if( g_iCvarAllow == 2 && !fake ) return;
  867. }
  868.  
  869.  
  870. // Event check
  871. char sUse[16];
  872. event.GetString("ability", sUse, sizeof(sUse));
  873. if(
  874. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  875. || strcmp(sUse, "ability_throw") == 0
  876. || strcmp(sUse, "ability_tongue") == 0
  877. )
  878. {
  879. if( GetGameTime() - g_fTime[client] >= 3.0 )
  880. {
  881. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  882. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  883. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  884. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  885. }
  886. g_fTime[client] = GetGameTime();
  887. }
  888. }
  889.  
  890. public void onThinkFunk(int client) //Dance
  891. {
  892. if( IsClientInGame(client) )
  893. {
  894. if( GetGameTime() - g_fTime[client] < 3.0 )
  895. {
  896. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  897.  
  898. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  899. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  900. {
  901. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  902. }
  903. } else {
  904. g_fTime[client] = 0.0;
  905. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  906. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  907. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  908. }
  909. }
  910. }#define PLUGIN_VERSION "1.1"
  911.  
  912. /*=======================================================================================
  913. Plugin Info:
  914.  
  915. * Name : [L4D & L4D2] Special Infected Ability Movement
  916. * Author : SilverShot
  917. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  918. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  919.  
  920. ========================================================================================
  921. Change Log:
  922.  
  923. 1.1 (23-Aug-2018)
  924. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  925.  
  926. 1.0 (05-May-2018)
  927. - Initial release.
  928.  
  929. ======================================================================================*/
  930.  
  931. #pragma semicolon 1
  932. #pragma newdecls required
  933.  
  934. #include <sourcemod>
  935. #include <sdktools>
  936. #include <sdkhooks>
  937.  
  938. #define CVAR_FLAGS FCVAR_NOTIFY
  939.  
  940.  
  941. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  942. int g_iCvarAllow, g_iCvarType;
  943. bool g_bCvarAllow, g_bLeft4Dead2;
  944. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  945.  
  946. enum ()
  947. {
  948. ENUM_SMOKE = 1,
  949. ENUM_SPITS = 2,
  950. ENUM_TANKS = 4
  951. }
  952.  
  953.  
  954.  
  955. // ====================================================================================================
  956. // PLUGIN INFO / START / END
  957. // ====================================================================================================
  958. public Plugin myinfo =
  959. {
  960. name = "[L4D & L4D2] Special Infected Ability Movement",
  961. author = "SilverShot",
  962. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  963. version = PLUGIN_VERSION,
  964. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  965. }
  966.  
  967. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  968. {
  969. EngineVersion test = GetEngineVersion();
  970. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  971. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  972. else
  973. {
  974. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  975. return APLRes_SilentFailure;
  976. }
  977. return APLRes_Success;
  978. }
  979.  
  980. public void OnPluginStart()
  981. {
  982. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  983. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  984. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  985. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  986. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  987. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  988. AutoExecConfig(true, "l4d_infected_movement");
  989.  
  990. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  991. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  992. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  993. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  994. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  995. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  996. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  997.  
  998. g_hSpeedTank = FindConVar("z_tank_speed");
  999. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  1000. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  1001. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  1002.  
  1003. if( g_bLeft4Dead2 )
  1004. {
  1005. g_hSpeedSpit = FindConVar("z_spitter_speed");
  1006. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  1007. }
  1008. }
  1009.  
  1010.  
  1011.  
  1012. // ====================================================================================================
  1013. // CVARS
  1014. // ====================================================================================================
  1015. public void OnConfigsExecuted()
  1016. {
  1017. IsAllowed();
  1018. }
  1019.  
  1020. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  1021. {
  1022. IsAllowed();
  1023. }
  1024.  
  1025. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  1026. {
  1027. GetCvars();
  1028. }
  1029.  
  1030. void GetCvars()
  1031. {
  1032. if( g_bLeft4Dead2 )
  1033. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  1034. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  1035. g_fSpeedTank = g_hSpeedTank.FloatValue;
  1036. g_iCvarType = g_hCvarType.IntValue;
  1037. }
  1038.  
  1039. void IsAllowed()
  1040. {
  1041. g_iCvarAllow = g_hCvarAllow.IntValue;
  1042. bool bAllowMode = IsAllowedGameMode();
  1043. GetCvars();
  1044.  
  1045. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  1046. {
  1047. g_bCvarAllow = true;
  1048. HookEvent("round_end", Event_Reset);
  1049. HookEvent("round_start", Event_Reset);
  1050. HookEvent("ability_use", Event_Use);
  1051. }
  1052. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  1053. {
  1054. g_bCvarAllow = false;
  1055. UnhookEvent("round_end", Event_Reset);
  1056. UnhookEvent("round_start", Event_Reset);
  1057. UnhookEvent("ability_use", Event_Use);
  1058. }
  1059. }
  1060.  
  1061. int g_iCurrentMode;
  1062. bool IsAllowedGameMode()
  1063. {
  1064. if( g_hCvarMPGameMode == null )
  1065. return false;
  1066.  
  1067. int iCvarModesTog = g_hCvarModesTog.IntValue;
  1068. if( iCvarModesTog != 0 )
  1069. {
  1070. g_iCurrentMode = 0;
  1071.  
  1072. int entity = CreateEntityByName("info_gamemode");
  1073. DispatchSpawn(entity);
  1074. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  1075. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  1076. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  1077. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  1078. ActivateEntity(entity);
  1079. AcceptEntityInput(entity, "PostSpawnActivate");
  1080. AcceptEntityInput(entity, "Kill");
  1081.  
  1082. if( g_iCurrentMode == 0 )
  1083. return false;
  1084.  
  1085. if( !(iCvarModesTog & g_iCurrentMode) )
  1086. return false;
  1087. }
  1088.  
  1089. char sGameModes[64], sGameMode[64];
  1090. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  1091. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  1092.  
  1093. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  1094. if( strcmp(sGameModes, "") )
  1095. {
  1096. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  1097. if( StrContains(sGameModes, sGameMode, false) == -1 )
  1098. return false;
  1099. }
  1100.  
  1101. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  1102. if( strcmp(sGameModes, "") )
  1103. {
  1104. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  1105. if( StrContains(sGameModes, sGameMode, false) != -1 )
  1106. return false;
  1107. }
  1108.  
  1109. return true;
  1110. }
  1111.  
  1112. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  1113. {
  1114. if( strcmp(output, "OnCoop") == 0 )
  1115. g_iCurrentMode = 1;
  1116. else if( strcmp(output, "OnSurvival") == 0 )
  1117. g_iCurrentMode = 2;
  1118. else if( strcmp(output, "OnVersus") == 0 )
  1119. g_iCurrentMode = 4;
  1120. else if( strcmp(output, "OnScavenge") == 0 )
  1121. g_iCurrentMode = 8;
  1122. }
  1123.  
  1124.  
  1125.  
  1126. // ====================================================================================================
  1127. // EVENTS
  1128. // ====================================================================================================
  1129. static float g_fTime[MAXPLAYERS+1];
  1130.  
  1131. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  1132. {
  1133. ResetPlugin();
  1134. }
  1135.  
  1136. void ResetPlugin()
  1137. {
  1138. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  1139. {
  1140. g_fTime[i] = 0.0;
  1141. }
  1142. }
  1143.  
  1144. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  1145. {
  1146. int client = GetClientOfUserId(event.GetInt("userid"));
  1147. if( !client || !IsClientInGame(client) ) return;
  1148.  
  1149.  
  1150. // Class check
  1151. // Smoker = 1; Spitter = 4; Tank = 8
  1152. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  1153. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  1154. switch( class )
  1155. {
  1156. case 1: class = 0;
  1157. case 4: class = 1;
  1158. case 8: class = 2;
  1159. default: class = 99;
  1160. }
  1161. if( !(g_iCvarType & (1 << class)) ) return;
  1162.  
  1163.  
  1164. // Bots check
  1165. if( g_iCvarAllow != 3 )
  1166. {
  1167. bool fake = IsFakeClient(client);
  1168. if( g_iCvarAllow == 1 && fake ) return;
  1169. if( g_iCvarAllow == 2 && !fake ) return;
  1170. }
  1171.  
  1172.  
  1173. // Event check
  1174. char sUse[16];
  1175. event.GetString("ability", sUse, sizeof(sUse));
  1176. if(
  1177. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  1178. || strcmp(sUse, "ability_throw") == 0
  1179. || strcmp(sUse, "ability_tongue") == 0
  1180. )
  1181. {
  1182. if( GetGameTime() - g_fTime[client] >= 3.0 )
  1183. {
  1184. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  1185. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  1186. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  1187. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  1188. }
  1189. g_fTime[client] = GetGameTime();
  1190. }
  1191. }
  1192.  
  1193. public void onThinkFunk(int client) //Dance
  1194. {
  1195. if( IsClientInGame(client) )
  1196. {
  1197. if( GetGameTime() - g_fTime[client] < 3.0 )
  1198. {
  1199. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  1200.  
  1201. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  1202. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  1203. {
  1204. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  1205. }
  1206. } else {
  1207. g_fTime[client] = 0.0;
  1208. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  1209. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  1210. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  1211. }
  1212. }
  1213. }#define PLUGIN_VERSION "1.1"
  1214.  
  1215. /*=======================================================================================
  1216. Plugin Info:
  1217.  
  1218. * Name : [L4D & L4D2] Special Infected Ability Movement
  1219. * Author : SilverShot
  1220. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  1221. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  1222.  
  1223. ========================================================================================
  1224. Change Log:
  1225.  
  1226. 1.1 (23-Aug-2018)
  1227. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  1228.  
  1229. 1.0 (05-May-2018)
  1230. - Initial release.
  1231.  
  1232. ======================================================================================*/
  1233.  
  1234. #pragma semicolon 1
  1235. #pragma newdecls required
  1236.  
  1237. #include <sourcemod>
  1238. #include <sdktools>
  1239. #include <sdkhooks>
  1240.  
  1241. #define CVAR_FLAGS FCVAR_NOTIFY
  1242.  
  1243.  
  1244. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  1245. int g_iCvarAllow, g_iCvarType;
  1246. bool g_bCvarAllow, g_bLeft4Dead2;
  1247. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  1248.  
  1249. enum ()
  1250. {
  1251. ENUM_SMOKE = 1,
  1252. ENUM_SPITS = 2,
  1253. ENUM_TANKS = 4
  1254. }
  1255.  
  1256.  
  1257.  
  1258. // ====================================================================================================
  1259. // PLUGIN INFO / START / END
  1260. // ====================================================================================================
  1261. public Plugin myinfo =
  1262. {
  1263. name = "[L4D & L4D2] Special Infected Ability Movement",
  1264. author = "SilverShot",
  1265. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  1266. version = PLUGIN_VERSION,
  1267. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  1268. }
  1269.  
  1270. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  1271. {
  1272. EngineVersion test = GetEngineVersion();
  1273. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  1274. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  1275. else
  1276. {
  1277. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  1278. return APLRes_SilentFailure;
  1279. }
  1280. return APLRes_Success;
  1281. }
  1282.  
  1283. public void OnPluginStart()
  1284. {
  1285. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  1286. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  1287. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  1288. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  1289. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  1290. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  1291. AutoExecConfig(true, "l4d_infected_movement");
  1292.  
  1293. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  1294. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  1295. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  1296. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  1297. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  1298. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  1299. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  1300.  
  1301. g_hSpeedTank = FindConVar("z_tank_speed");
  1302. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  1303. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  1304. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  1305.  
  1306. if( g_bLeft4Dead2 )
  1307. {
  1308. g_hSpeedSpit = FindConVar("z_spitter_speed");
  1309. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  1310. }
  1311. }
  1312.  
  1313.  
  1314.  
  1315. // ====================================================================================================
  1316. // CVARS
  1317. // ====================================================================================================
  1318. public void OnConfigsExecuted()
  1319. {
  1320. IsAllowed();
  1321. }
  1322.  
  1323. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  1324. {
  1325. IsAllowed();
  1326. }
  1327.  
  1328. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  1329. {
  1330. GetCvars();
  1331. }
  1332.  
  1333. void GetCvars()
  1334. {
  1335. if( g_bLeft4Dead2 )
  1336. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  1337. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  1338. g_fSpeedTank = g_hSpeedTank.FloatValue;
  1339. g_iCvarType = g_hCvarType.IntValue;
  1340. }
  1341.  
  1342. void IsAllowed()
  1343. {
  1344. g_iCvarAllow = g_hCvarAllow.IntValue;
  1345. bool bAllowMode = IsAllowedGameMode();
  1346. GetCvars();
  1347.  
  1348. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  1349. {
  1350. g_bCvarAllow = true;
  1351. HookEvent("round_end", Event_Reset);
  1352. HookEvent("round_start", Event_Reset);
  1353. HookEvent("ability_use", Event_Use);
  1354. }
  1355. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  1356. {
  1357. g_bCvarAllow = false;
  1358. UnhookEvent("round_end", Event_Reset);
  1359. UnhookEvent("round_start", Event_Reset);
  1360. UnhookEvent("ability_use", Event_Use);
  1361. }
  1362. }
  1363.  
  1364. int g_iCurrentMode;
  1365. bool IsAllowedGameMode()
  1366. {
  1367. if( g_hCvarMPGameMode == null )
  1368. return false;
  1369.  
  1370. int iCvarModesTog = g_hCvarModesTog.IntValue;
  1371. if( iCvarModesTog != 0 )
  1372. {
  1373. g_iCurrentMode = 0;
  1374.  
  1375. int entity = CreateEntityByName("info_gamemode");
  1376. DispatchSpawn(entity);
  1377. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  1378. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  1379. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  1380. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  1381. ActivateEntity(entity);
  1382. AcceptEntityInput(entity, "PostSpawnActivate");
  1383. AcceptEntityInput(entity, "Kill");
  1384.  
  1385. if( g_iCurrentMode == 0 )
  1386. return false;
  1387.  
  1388. if( !(iCvarModesTog & g_iCurrentMode) )
  1389. return false;
  1390. }
  1391.  
  1392. char sGameModes[64], sGameMode[64];
  1393. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  1394. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  1395.  
  1396. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  1397. if( strcmp(sGameModes, "") )
  1398. {
  1399. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  1400. if( StrContains(sGameModes, sGameMode, false) == -1 )
  1401. return false;
  1402. }
  1403.  
  1404. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  1405. if( strcmp(sGameModes, "") )
  1406. {
  1407. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  1408. if( StrContains(sGameModes, sGameMode, false) != -1 )
  1409. return false;
  1410. }
  1411.  
  1412. return true;
  1413. }
  1414.  
  1415. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  1416. {
  1417. if( strcmp(output, "OnCoop") == 0 )
  1418. g_iCurrentMode = 1;
  1419. else if( strcmp(output, "OnSurvival") == 0 )
  1420. g_iCurrentMode = 2;
  1421. else if( strcmp(output, "OnVersus") == 0 )
  1422. g_iCurrentMode = 4;
  1423. else if( strcmp(output, "OnScavenge") == 0 )
  1424. g_iCurrentMode = 8;
  1425. }
  1426.  
  1427.  
  1428.  
  1429. // ====================================================================================================
  1430. // EVENTS
  1431. // ====================================================================================================
  1432. static float g_fTime[MAXPLAYERS+1];
  1433.  
  1434. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  1435. {
  1436. ResetPlugin();
  1437. }
  1438.  
  1439. void ResetPlugin()
  1440. {
  1441. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  1442. {
  1443. g_fTime[i] = 0.0;
  1444. }
  1445. }
  1446.  
  1447. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  1448. {
  1449. int client = GetClientOfUserId(event.GetInt("userid"));
  1450. if( !client || !IsClientInGame(client) ) return;
  1451.  
  1452.  
  1453. // Class check
  1454. // Smoker = 1; Spitter = 4; Tank = 8
  1455. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  1456. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  1457. switch( class )
  1458. {
  1459. case 1: class = 0;
  1460. case 4: class = 1;
  1461. case 8: class = 2;
  1462. default: class = 99;
  1463. }
  1464. if( !(g_iCvarType & (1 << class)) ) return;
  1465.  
  1466.  
  1467. // Bots check
  1468. if( g_iCvarAllow != 3 )
  1469. {
  1470. bool fake = IsFakeClient(client);
  1471. if( g_iCvarAllow == 1 && fake ) return;
  1472. if( g_iCvarAllow == 2 && !fake ) return;
  1473. }
  1474.  
  1475.  
  1476. // Event check
  1477. char sUse[16];
  1478. event.GetString("ability", sUse, sizeof(sUse));
  1479. if(
  1480. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  1481. || strcmp(sUse, "ability_throw") == 0
  1482. || strcmp(sUse, "ability_tongue") == 0
  1483. )
  1484. {
  1485. if( GetGameTime() - g_fTime[client] >= 3.0 )
  1486. {
  1487. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  1488. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  1489. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  1490. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  1491. }
  1492. g_fTime[client] = GetGameTime();
  1493. }
  1494. }
  1495.  
  1496. public void onThinkFunk(int client) //Dance
  1497. {
  1498. if( IsClientInGame(client) )
  1499. {
  1500. if( GetGameTime() - g_fTime[client] < 3.0 )
  1501. {
  1502. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  1503.  
  1504. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  1505. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  1506. {
  1507. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  1508. }
  1509. } else {
  1510. g_fTime[client] = 0.0;
  1511. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  1512. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  1513. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  1514. }
  1515. }
  1516. }#define PLUGIN_VERSION "1.1"
  1517.  
  1518. /*=======================================================================================
  1519. Plugin Info:
  1520.  
  1521. * Name : [L4D & L4D2] Special Infected Ability Movement
  1522. * Author : SilverShot
  1523. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  1524. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  1525.  
  1526. ========================================================================================
  1527. Change Log:
  1528.  
  1529. 1.1 (23-Aug-2018)
  1530. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  1531.  
  1532. 1.0 (05-May-2018)
  1533. - Initial release.
  1534.  
  1535. ======================================================================================*/
  1536.  
  1537. #pragma semicolon 1
  1538. #pragma newdecls required
  1539.  
  1540. #include <sourcemod>
  1541. #include <sdktools>
  1542. #include <sdkhooks>
  1543.  
  1544. #define CVAR_FLAGS FCVAR_NOTIFY
  1545.  
  1546.  
  1547. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  1548. int g_iCvarAllow, g_iCvarType;
  1549. bool g_bCvarAllow, g_bLeft4Dead2;
  1550. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  1551.  
  1552. enum ()
  1553. {
  1554. ENUM_SMOKE = 1,
  1555. ENUM_SPITS = 2,
  1556. ENUM_TANKS = 4
  1557. }
  1558.  
  1559.  
  1560.  
  1561. // ====================================================================================================
  1562. // PLUGIN INFO / START / END
  1563. // ====================================================================================================
  1564. public Plugin myinfo =
  1565. {
  1566. name = "[L4D & L4D2] Special Infected Ability Movement",
  1567. author = "SilverShot",
  1568. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  1569. version = PLUGIN_VERSION,
  1570. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  1571. }
  1572.  
  1573. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  1574. {
  1575. EngineVersion test = GetEngineVersion();
  1576. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  1577. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  1578. else
  1579. {
  1580. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  1581. return APLRes_SilentFailure;
  1582. }
  1583. return APLRes_Success;
  1584. }
  1585.  
  1586. public void OnPluginStart()
  1587. {
  1588. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  1589. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  1590. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  1591. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  1592. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  1593. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  1594. AutoExecConfig(true, "l4d_infected_movement");
  1595.  
  1596. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  1597. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  1598. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  1599. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  1600. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  1601. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  1602. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  1603.  
  1604. g_hSpeedTank = FindConVar("z_tank_speed");
  1605. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  1606. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  1607. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  1608.  
  1609. if( g_bLeft4Dead2 )
  1610. {
  1611. g_hSpeedSpit = FindConVar("z_spitter_speed");
  1612. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  1613. }
  1614. }
  1615.  
  1616.  
  1617.  
  1618. // ====================================================================================================
  1619. // CVARS
  1620. // ====================================================================================================
  1621. public void OnConfigsExecuted()
  1622. {
  1623. IsAllowed();
  1624. }
  1625.  
  1626. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  1627. {
  1628. IsAllowed();
  1629. }
  1630.  
  1631. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  1632. {
  1633. GetCvars();
  1634. }
  1635.  
  1636. void GetCvars()
  1637. {
  1638. if( g_bLeft4Dead2 )
  1639. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  1640. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  1641. g_fSpeedTank = g_hSpeedTank.FloatValue;
  1642. g_iCvarType = g_hCvarType.IntValue;
  1643. }
  1644.  
  1645. void IsAllowed()
  1646. {
  1647. g_iCvarAllow = g_hCvarAllow.IntValue;
  1648. bool bAllowMode = IsAllowedGameMode();
  1649. GetCvars();
  1650.  
  1651. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  1652. {
  1653. g_bCvarAllow = true;
  1654. HookEvent("round_end", Event_Reset);
  1655. HookEvent("round_start", Event_Reset);
  1656. HookEvent("ability_use", Event_Use);
  1657. }
  1658. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  1659. {
  1660. g_bCvarAllow = false;
  1661. UnhookEvent("round_end", Event_Reset);
  1662. UnhookEvent("round_start", Event_Reset);
  1663. UnhookEvent("ability_use", Event_Use);
  1664. }
  1665. }
  1666.  
  1667. int g_iCurrentMode;
  1668. bool IsAllowedGameMode()
  1669. {
  1670. if( g_hCvarMPGameMode == null )
  1671. return false;
  1672.  
  1673. int iCvarModesTog = g_hCvarModesTog.IntValue;
  1674. if( iCvarModesTog != 0 )
  1675. {
  1676. g_iCurrentMode = 0;
  1677.  
  1678. int entity = CreateEntityByName("info_gamemode");
  1679. DispatchSpawn(entity);
  1680. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  1681. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  1682. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  1683. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  1684. ActivateEntity(entity);
  1685. AcceptEntityInput(entity, "PostSpawnActivate");
  1686. AcceptEntityInput(entity, "Kill");
  1687.  
  1688. if( g_iCurrentMode == 0 )
  1689. return false;
  1690.  
  1691. if( !(iCvarModesTog & g_iCurrentMode) )
  1692. return false;
  1693. }
  1694.  
  1695. char sGameModes[64], sGameMode[64];
  1696. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  1697. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  1698.  
  1699. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  1700. if( strcmp(sGameModes, "") )
  1701. {
  1702. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  1703. if( StrContains(sGameModes, sGameMode, false) == -1 )
  1704. return false;
  1705. }
  1706.  
  1707. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  1708. if( strcmp(sGameModes, "") )
  1709. {
  1710. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  1711. if( StrContains(sGameModes, sGameMode, false) != -1 )
  1712. return false;
  1713. }
  1714.  
  1715. return true;
  1716. }
  1717.  
  1718. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  1719. {
  1720. if( strcmp(output, "OnCoop") == 0 )
  1721. g_iCurrentMode = 1;
  1722. else if( strcmp(output, "OnSurvival") == 0 )
  1723. g_iCurrentMode = 2;
  1724. else if( strcmp(output, "OnVersus") == 0 )
  1725. g_iCurrentMode = 4;
  1726. else if( strcmp(output, "OnScavenge") == 0 )
  1727. g_iCurrentMode = 8;
  1728. }
  1729.  
  1730.  
  1731.  
  1732. // ====================================================================================================
  1733. // EVENTS
  1734. // ====================================================================================================
  1735. static float g_fTime[MAXPLAYERS+1];
  1736.  
  1737. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  1738. {
  1739. ResetPlugin();
  1740. }
  1741.  
  1742. void ResetPlugin()
  1743. {
  1744. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  1745. {
  1746. g_fTime[i] = 0.0;
  1747. }
  1748. }
  1749.  
  1750. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  1751. {
  1752. int client = GetClientOfUserId(event.GetInt("userid"));
  1753. if( !client || !IsClientInGame(client) ) return;
  1754.  
  1755.  
  1756. // Class check
  1757. // Smoker = 1; Spitter = 4; Tank = 8
  1758. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  1759. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  1760. switch( class )
  1761. {
  1762. case 1: class = 0;
  1763. case 4: class = 1;
  1764. case 8: class = 2;
  1765. default: class = 99;
  1766. }
  1767. if( !(g_iCvarType & (1 << class)) ) return;
  1768.  
  1769.  
  1770. // Bots check
  1771. if( g_iCvarAllow != 3 )
  1772. {
  1773. bool fake = IsFakeClient(client);
  1774. if( g_iCvarAllow == 1 && fake ) return;
  1775. if( g_iCvarAllow == 2 && !fake ) return;
  1776. }
  1777.  
  1778.  
  1779. // Event check
  1780. char sUse[16];
  1781. event.GetString("ability", sUse, sizeof(sUse));
  1782. if(
  1783. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  1784. || strcmp(sUse, "ability_throw") == 0
  1785. || strcmp(sUse, "ability_tongue") == 0
  1786. )
  1787. {
  1788. if( GetGameTime() - g_fTime[client] >= 3.0 )
  1789. {
  1790. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  1791. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  1792. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  1793. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  1794. }
  1795. g_fTime[client] = GetGameTime();
  1796. }
  1797. }
  1798.  
  1799. public void onThinkFunk(int client) //Dance
  1800. {
  1801. if( IsClientInGame(client) )
  1802. {
  1803. if( GetGameTime() - g_fTime[client] < 3.0 )
  1804. {
  1805. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  1806.  
  1807. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  1808. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  1809. {
  1810. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  1811. }
  1812. } else {
  1813. g_fTime[client] = 0.0;
  1814. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  1815. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  1816. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  1817. }
  1818. }
  1819. }#define PLUGIN_VERSION "1.1"
  1820.  
  1821. /*=======================================================================================
  1822. Plugin Info:
  1823.  
  1824. * Name : [L4D & L4D2] Special Infected Ability Movement
  1825. * Author : SilverShot
  1826. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  1827. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  1828.  
  1829. ========================================================================================
  1830. Change Log:
  1831.  
  1832. 1.1 (23-Aug-2018)
  1833. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  1834.  
  1835. 1.0 (05-May-2018)
  1836. - Initial release.
  1837.  
  1838. ======================================================================================*/
  1839.  
  1840. #pragma semicolon 1
  1841. #pragma newdecls required
  1842.  
  1843. #include <sourcemod>
  1844. #include <sdktools>
  1845. #include <sdkhooks>
  1846.  
  1847. #define CVAR_FLAGS FCVAR_NOTIFY
  1848.  
  1849.  
  1850. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  1851. int g_iCvarAllow, g_iCvarType;
  1852. bool g_bCvarAllow, g_bLeft4Dead2;
  1853. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  1854.  
  1855. enum ()
  1856. {
  1857. ENUM_SMOKE = 1,
  1858. ENUM_SPITS = 2,
  1859. ENUM_TANKS = 4
  1860. }
  1861.  
  1862.  
  1863.  
  1864. // ====================================================================================================
  1865. // PLUGIN INFO / START / END
  1866. // ====================================================================================================
  1867. public Plugin myinfo =
  1868. {
  1869. name = "[L4D & L4D2] Special Infected Ability Movement",
  1870. author = "SilverShot",
  1871. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  1872. version = PLUGIN_VERSION,
  1873. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  1874. }
  1875.  
  1876. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  1877. {
  1878. EngineVersion test = GetEngineVersion();
  1879. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  1880. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  1881. else
  1882. {
  1883. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  1884. return APLRes_SilentFailure;
  1885. }
  1886. return APLRes_Success;
  1887. }
  1888.  
  1889. public void OnPluginStart()
  1890. {
  1891. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  1892. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  1893. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  1894. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  1895. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  1896. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  1897. AutoExecConfig(true, "l4d_infected_movement");
  1898.  
  1899. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  1900. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  1901. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  1902. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  1903. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  1904. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  1905. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  1906.  
  1907. g_hSpeedTank = FindConVar("z_tank_speed");
  1908. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  1909. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  1910. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  1911.  
  1912. if( g_bLeft4Dead2 )
  1913. {
  1914. g_hSpeedSpit = FindConVar("z_spitter_speed");
  1915. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  1916. }
  1917. }
  1918.  
  1919.  
  1920.  
  1921. // ====================================================================================================
  1922. // CVARS
  1923. // ====================================================================================================
  1924. public void OnConfigsExecuted()
  1925. {
  1926. IsAllowed();
  1927. }
  1928.  
  1929. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  1930. {
  1931. IsAllowed();
  1932. }
  1933.  
  1934. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  1935. {
  1936. GetCvars();
  1937. }
  1938.  
  1939. void GetCvars()
  1940. {
  1941. if( g_bLeft4Dead2 )
  1942. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  1943. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  1944. g_fSpeedTank = g_hSpeedTank.FloatValue;
  1945. g_iCvarType = g_hCvarType.IntValue;
  1946. }
  1947.  
  1948. void IsAllowed()
  1949. {
  1950. g_iCvarAllow = g_hCvarAllow.IntValue;
  1951. bool bAllowMode = IsAllowedGameMode();
  1952. GetCvars();
  1953.  
  1954. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  1955. {
  1956. g_bCvarAllow = true;
  1957. HookEvent("round_end", Event_Reset);
  1958. HookEvent("round_start", Event_Reset);
  1959. HookEvent("ability_use", Event_Use);
  1960. }
  1961. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  1962. {
  1963. g_bCvarAllow = false;
  1964. UnhookEvent("round_end", Event_Reset);
  1965. UnhookEvent("round_start", Event_Reset);
  1966. UnhookEvent("ability_use", Event_Use);
  1967. }
  1968. }
  1969.  
  1970. int g_iCurrentMode;
  1971. bool IsAllowedGameMode()
  1972. {
  1973. if( g_hCvarMPGameMode == null )
  1974. return false;
  1975.  
  1976. int iCvarModesTog = g_hCvarModesTog.IntValue;
  1977. if( iCvarModesTog != 0 )
  1978. {
  1979. g_iCurrentMode = 0;
  1980.  
  1981. int entity = CreateEntityByName("info_gamemode");
  1982. DispatchSpawn(entity);
  1983. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  1984. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  1985. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  1986. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  1987. ActivateEntity(entity);
  1988. AcceptEntityInput(entity, "PostSpawnActivate");
  1989. AcceptEntityInput(entity, "Kill");
  1990.  
  1991. if( g_iCurrentMode == 0 )
  1992. return false;
  1993.  
  1994. if( !(iCvarModesTog & g_iCurrentMode) )
  1995. return false;
  1996. }
  1997.  
  1998. char sGameModes[64], sGameMode[64];
  1999. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  2000. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  2001.  
  2002. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  2003. if( strcmp(sGameModes, "") )
  2004. {
  2005. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2006. if( StrContains(sGameModes, sGameMode, false) == -1 )
  2007. return false;
  2008. }
  2009.  
  2010. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  2011. if( strcmp(sGameModes, "") )
  2012. {
  2013. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2014. if( StrContains(sGameModes, sGameMode, false) != -1 )
  2015. return false;
  2016. }
  2017.  
  2018. return true;
  2019. }
  2020.  
  2021. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  2022. {
  2023. if( strcmp(output, "OnCoop") == 0 )
  2024. g_iCurrentMode = 1;
  2025. else if( strcmp(output, "OnSurvival") == 0 )
  2026. g_iCurrentMode = 2;
  2027. else if( strcmp(output, "OnVersus") == 0 )
  2028. g_iCurrentMode = 4;
  2029. else if( strcmp(output, "OnScavenge") == 0 )
  2030. g_iCurrentMode = 8;
  2031. }
  2032.  
  2033.  
  2034.  
  2035. // ====================================================================================================
  2036. // EVENTS
  2037. // ====================================================================================================
  2038. static float g_fTime[MAXPLAYERS+1];
  2039.  
  2040. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  2041. {
  2042. ResetPlugin();
  2043. }
  2044.  
  2045. void ResetPlugin()
  2046. {
  2047. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  2048. {
  2049. g_fTime[i] = 0.0;
  2050. }
  2051. }
  2052.  
  2053. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  2054. {
  2055. int client = GetClientOfUserId(event.GetInt("userid"));
  2056. if( !client || !IsClientInGame(client) ) return;
  2057.  
  2058.  
  2059. // Class check
  2060. // Smoker = 1; Spitter = 4; Tank = 8
  2061. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  2062. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  2063. switch( class )
  2064. {
  2065. case 1: class = 0;
  2066. case 4: class = 1;
  2067. case 8: class = 2;
  2068. default: class = 99;
  2069. }
  2070. if( !(g_iCvarType & (1 << class)) ) return;
  2071.  
  2072.  
  2073. // Bots check
  2074. if( g_iCvarAllow != 3 )
  2075. {
  2076. bool fake = IsFakeClient(client);
  2077. if( g_iCvarAllow == 1 && fake ) return;
  2078. if( g_iCvarAllow == 2 && !fake ) return;
  2079. }
  2080.  
  2081.  
  2082. // Event check
  2083. char sUse[16];
  2084. event.GetString("ability", sUse, sizeof(sUse));
  2085. if(
  2086. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  2087. || strcmp(sUse, "ability_throw") == 0
  2088. || strcmp(sUse, "ability_tongue") == 0
  2089. )
  2090. {
  2091. if( GetGameTime() - g_fTime[client] >= 3.0 )
  2092. {
  2093. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  2094. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  2095. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  2096. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  2097. }
  2098. g_fTime[client] = GetGameTime();
  2099. }
  2100. }
  2101.  
  2102. public void onThinkFunk(int client) //Dance
  2103. {
  2104. if( IsClientInGame(client) )
  2105. {
  2106. if( GetGameTime() - g_fTime[client] < 3.0 )
  2107. {
  2108. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  2109.  
  2110. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  2111. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  2112. {
  2113. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  2114. }
  2115. } else {
  2116. g_fTime[client] = 0.0;
  2117. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  2118. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  2119. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  2120. }
  2121. }
  2122. }#define PLUGIN_VERSION "1.1"
  2123.  
  2124. /*=======================================================================================
  2125. Plugin Info:
  2126.  
  2127. * Name : [L4D & L4D2] Special Infected Ability Movement
  2128. * Author : SilverShot
  2129. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  2130. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  2131.  
  2132. ========================================================================================
  2133. Change Log:
  2134.  
  2135. 1.1 (23-Aug-2018)
  2136. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  2137.  
  2138. 1.0 (05-May-2018)
  2139. - Initial release.
  2140.  
  2141. ======================================================================================*/
  2142.  
  2143. #pragma semicolon 1
  2144. #pragma newdecls required
  2145.  
  2146. #include <sourcemod>
  2147. #include <sdktools>
  2148. #include <sdkhooks>
  2149.  
  2150. #define CVAR_FLAGS FCVAR_NOTIFY
  2151.  
  2152.  
  2153. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  2154. int g_iCvarAllow, g_iCvarType;
  2155. bool g_bCvarAllow, g_bLeft4Dead2;
  2156. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  2157.  
  2158. enum ()
  2159. {
  2160. ENUM_SMOKE = 1,
  2161. ENUM_SPITS = 2,
  2162. ENUM_TANKS = 4
  2163. }
  2164.  
  2165.  
  2166.  
  2167. // ====================================================================================================
  2168. // PLUGIN INFO / START / END
  2169. // ====================================================================================================
  2170. public Plugin myinfo =
  2171. {
  2172. name = "[L4D & L4D2] Special Infected Ability Movement",
  2173. author = "SilverShot",
  2174. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  2175. version = PLUGIN_VERSION,
  2176. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  2177. }
  2178.  
  2179. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  2180. {
  2181. EngineVersion test = GetEngineVersion();
  2182. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  2183. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  2184. else
  2185. {
  2186. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  2187. return APLRes_SilentFailure;
  2188. }
  2189. return APLRes_Success;
  2190. }
  2191.  
  2192. public void OnPluginStart()
  2193. {
  2194. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  2195. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  2196. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  2197. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  2198. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  2199. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  2200. AutoExecConfig(true, "l4d_infected_movement");
  2201.  
  2202. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  2203. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  2204. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  2205. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  2206. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  2207. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  2208. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  2209.  
  2210. g_hSpeedTank = FindConVar("z_tank_speed");
  2211. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  2212. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  2213. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  2214.  
  2215. if( g_bLeft4Dead2 )
  2216. {
  2217. g_hSpeedSpit = FindConVar("z_spitter_speed");
  2218. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  2219. }
  2220. }
  2221.  
  2222.  
  2223.  
  2224. // ====================================================================================================
  2225. // CVARS
  2226. // ====================================================================================================
  2227. public void OnConfigsExecuted()
  2228. {
  2229. IsAllowed();
  2230. }
  2231.  
  2232. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  2233. {
  2234. IsAllowed();
  2235. }
  2236.  
  2237. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  2238. {
  2239. GetCvars();
  2240. }
  2241.  
  2242. void GetCvars()
  2243. {
  2244. if( g_bLeft4Dead2 )
  2245. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  2246. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  2247. g_fSpeedTank = g_hSpeedTank.FloatValue;
  2248. g_iCvarType = g_hCvarType.IntValue;
  2249. }
  2250.  
  2251. void IsAllowed()
  2252. {
  2253. g_iCvarAllow = g_hCvarAllow.IntValue;
  2254. bool bAllowMode = IsAllowedGameMode();
  2255. GetCvars();
  2256.  
  2257. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  2258. {
  2259. g_bCvarAllow = true;
  2260. HookEvent("round_end", Event_Reset);
  2261. HookEvent("round_start", Event_Reset);
  2262. HookEvent("ability_use", Event_Use);
  2263. }
  2264. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  2265. {
  2266. g_bCvarAllow = false;
  2267. UnhookEvent("round_end", Event_Reset);
  2268. UnhookEvent("round_start", Event_Reset);
  2269. UnhookEvent("ability_use", Event_Use);
  2270. }
  2271. }
  2272.  
  2273. int g_iCurrentMode;
  2274. bool IsAllowedGameMode()
  2275. {
  2276. if( g_hCvarMPGameMode == null )
  2277. return false;
  2278.  
  2279. int iCvarModesTog = g_hCvarModesTog.IntValue;
  2280. if( iCvarModesTog != 0 )
  2281. {
  2282. g_iCurrentMode = 0;
  2283.  
  2284. int entity = CreateEntityByName("info_gamemode");
  2285. DispatchSpawn(entity);
  2286. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  2287. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  2288. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  2289. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  2290. ActivateEntity(entity);
  2291. AcceptEntityInput(entity, "PostSpawnActivate");
  2292. AcceptEntityInput(entity, "Kill");
  2293.  
  2294. if( g_iCurrentMode == 0 )
  2295. return false;
  2296.  
  2297. if( !(iCvarModesTog & g_iCurrentMode) )
  2298. return false;
  2299. }
  2300.  
  2301. char sGameModes[64], sGameMode[64];
  2302. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  2303. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  2304.  
  2305. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  2306. if( strcmp(sGameModes, "") )
  2307. {
  2308. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2309. if( StrContains(sGameModes, sGameMode, false) == -1 )
  2310. return false;
  2311. }
  2312.  
  2313. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  2314. if( strcmp(sGameModes, "") )
  2315. {
  2316. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2317. if( StrContains(sGameModes, sGameMode, false) != -1 )
  2318. return false;
  2319. }
  2320.  
  2321. return true;
  2322. }
  2323.  
  2324. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  2325. {
  2326. if( strcmp(output, "OnCoop") == 0 )
  2327. g_iCurrentMode = 1;
  2328. else if( strcmp(output, "OnSurvival") == 0 )
  2329. g_iCurrentMode = 2;
  2330. else if( strcmp(output, "OnVersus") == 0 )
  2331. g_iCurrentMode = 4;
  2332. else if( strcmp(output, "OnScavenge") == 0 )
  2333. g_iCurrentMode = 8;
  2334. }
  2335.  
  2336.  
  2337.  
  2338. // ====================================================================================================
  2339. // EVENTS
  2340. // ====================================================================================================
  2341. static float g_fTime[MAXPLAYERS+1];
  2342.  
  2343. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  2344. {
  2345. ResetPlugin();
  2346. }
  2347.  
  2348. void ResetPlugin()
  2349. {
  2350. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  2351. {
  2352. g_fTime[i] = 0.0;
  2353. }
  2354. }
  2355.  
  2356. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  2357. {
  2358. int client = GetClientOfUserId(event.GetInt("userid"));
  2359. if( !client || !IsClientInGame(client) ) return;
  2360.  
  2361.  
  2362. // Class check
  2363. // Smoker = 1; Spitter = 4; Tank = 8
  2364. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  2365. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  2366. switch( class )
  2367. {
  2368. case 1: class = 0;
  2369. case 4: class = 1;
  2370. case 8: class = 2;
  2371. default: class = 99;
  2372. }
  2373. if( !(g_iCvarType & (1 << class)) ) return;
  2374.  
  2375.  
  2376. // Bots check
  2377. if( g_iCvarAllow != 3 )
  2378. {
  2379. bool fake = IsFakeClient(client);
  2380. if( g_iCvarAllow == 1 && fake ) return;
  2381. if( g_iCvarAllow == 2 && !fake ) return;
  2382. }
  2383.  
  2384.  
  2385. // Event check
  2386. char sUse[16];
  2387. event.GetString("ability", sUse, sizeof(sUse));
  2388. if(
  2389. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  2390. || strcmp(sUse, "ability_throw") == 0
  2391. || strcmp(sUse, "ability_tongue") == 0
  2392. )
  2393. {
  2394. if( GetGameTime() - g_fTime[client] >= 3.0 )
  2395. {
  2396. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  2397. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  2398. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  2399. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  2400. }
  2401. g_fTime[client] = GetGameTime();
  2402. }
  2403. }
  2404.  
  2405. public void onThinkFunk(int client) //Dance
  2406. {
  2407. if( IsClientInGame(client) )
  2408. {
  2409. if( GetGameTime() - g_fTime[client] < 3.0 )
  2410. {
  2411. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  2412.  
  2413. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  2414. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  2415. {
  2416. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  2417. }
  2418. } else {
  2419. g_fTime[client] = 0.0;
  2420. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  2421. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  2422. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  2423. }
  2424. }
  2425. }#define PLUGIN_VERSION "1.1"
  2426.  
  2427. /*=======================================================================================
  2428. Plugin Info:
  2429.  
  2430. * Name : [L4D & L4D2] Special Infected Ability Movement
  2431. * Author : SilverShot
  2432. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  2433. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  2434.  
  2435. ========================================================================================
  2436. Change Log:
  2437.  
  2438. 1.1 (23-Aug-2018)
  2439. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  2440.  
  2441. 1.0 (05-May-2018)
  2442. - Initial release.
  2443.  
  2444. ======================================================================================*/
  2445.  
  2446. #pragma semicolon 1
  2447. #pragma newdecls required
  2448.  
  2449. #include <sourcemod>
  2450. #include <sdktools>
  2451. #include <sdkhooks>
  2452.  
  2453. #define CVAR_FLAGS FCVAR_NOTIFY
  2454.  
  2455.  
  2456. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  2457. int g_iCvarAllow, g_iCvarType;
  2458. bool g_bCvarAllow, g_bLeft4Dead2;
  2459. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  2460.  
  2461. enum ()
  2462. {
  2463. ENUM_SMOKE = 1,
  2464. ENUM_SPITS = 2,
  2465. ENUM_TANKS = 4
  2466. }
  2467.  
  2468.  
  2469.  
  2470. // ====================================================================================================
  2471. // PLUGIN INFO / START / END
  2472. // ====================================================================================================
  2473. public Plugin myinfo =
  2474. {
  2475. name = "[L4D & L4D2] Special Infected Ability Movement",
  2476. author = "SilverShot",
  2477. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  2478. version = PLUGIN_VERSION,
  2479. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  2480. }
  2481.  
  2482. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  2483. {
  2484. EngineVersion test = GetEngineVersion();
  2485. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  2486. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  2487. else
  2488. {
  2489. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  2490. return APLRes_SilentFailure;
  2491. }
  2492. return APLRes_Success;
  2493. }
  2494.  
  2495. public void OnPluginStart()
  2496. {
  2497. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  2498. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  2499. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  2500. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  2501. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  2502. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  2503. AutoExecConfig(true, "l4d_infected_movement");
  2504.  
  2505. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  2506. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  2507. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  2508. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  2509. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  2510. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  2511. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  2512.  
  2513. g_hSpeedTank = FindConVar("z_tank_speed");
  2514. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  2515. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  2516. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  2517.  
  2518. if( g_bLeft4Dead2 )
  2519. {
  2520. g_hSpeedSpit = FindConVar("z_spitter_speed");
  2521. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  2522. }
  2523. }
  2524.  
  2525.  
  2526.  
  2527. // ====================================================================================================
  2528. // CVARS
  2529. // ====================================================================================================
  2530. public void OnConfigsExecuted()
  2531. {
  2532. IsAllowed();
  2533. }
  2534.  
  2535. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  2536. {
  2537. IsAllowed();
  2538. }
  2539.  
  2540. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  2541. {
  2542. GetCvars();
  2543. }
  2544.  
  2545. void GetCvars()
  2546. {
  2547. if( g_bLeft4Dead2 )
  2548. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  2549. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  2550. g_fSpeedTank = g_hSpeedTank.FloatValue;
  2551. g_iCvarType = g_hCvarType.IntValue;
  2552. }
  2553.  
  2554. void IsAllowed()
  2555. {
  2556. g_iCvarAllow = g_hCvarAllow.IntValue;
  2557. bool bAllowMode = IsAllowedGameMode();
  2558. GetCvars();
  2559.  
  2560. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  2561. {
  2562. g_bCvarAllow = true;
  2563. HookEvent("round_end", Event_Reset);
  2564. HookEvent("round_start", Event_Reset);
  2565. HookEvent("ability_use", Event_Use);
  2566. }
  2567. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  2568. {
  2569. g_bCvarAllow = false;
  2570. UnhookEvent("round_end", Event_Reset);
  2571. UnhookEvent("round_start", Event_Reset);
  2572. UnhookEvent("ability_use", Event_Use);
  2573. }
  2574. }
  2575.  
  2576. int g_iCurrentMode;
  2577. bool IsAllowedGameMode()
  2578. {
  2579. if( g_hCvarMPGameMode == null )
  2580. return false;
  2581.  
  2582. int iCvarModesTog = g_hCvarModesTog.IntValue;
  2583. if( iCvarModesTog != 0 )
  2584. {
  2585. g_iCurrentMode = 0;
  2586.  
  2587. int entity = CreateEntityByName("info_gamemode");
  2588. DispatchSpawn(entity);
  2589. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  2590. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  2591. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  2592. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  2593. ActivateEntity(entity);
  2594. AcceptEntityInput(entity, "PostSpawnActivate");
  2595. AcceptEntityInput(entity, "Kill");
  2596.  
  2597. if( g_iCurrentMode == 0 )
  2598. return false;
  2599.  
  2600. if( !(iCvarModesTog & g_iCurrentMode) )
  2601. return false;
  2602. }
  2603.  
  2604. char sGameModes[64], sGameMode[64];
  2605. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  2606. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  2607.  
  2608. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  2609. if( strcmp(sGameModes, "") )
  2610. {
  2611. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2612. if( StrContains(sGameModes, sGameMode, false) == -1 )
  2613. return false;
  2614. }
  2615.  
  2616. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  2617. if( strcmp(sGameModes, "") )
  2618. {
  2619. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2620. if( StrContains(sGameModes, sGameMode, false) != -1 )
  2621. return false;
  2622. }
  2623.  
  2624. return true;
  2625. }
  2626.  
  2627. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  2628. {
  2629. if( strcmp(output, "OnCoop") == 0 )
  2630. g_iCurrentMode = 1;
  2631. else if( strcmp(output, "OnSurvival") == 0 )
  2632. g_iCurrentMode = 2;
  2633. else if( strcmp(output, "OnVersus") == 0 )
  2634. g_iCurrentMode = 4;
  2635. else if( strcmp(output, "OnScavenge") == 0 )
  2636. g_iCurrentMode = 8;
  2637. }
  2638.  
  2639.  
  2640.  
  2641. // ====================================================================================================
  2642. // EVENTS
  2643. // ====================================================================================================
  2644. static float g_fTime[MAXPLAYERS+1];
  2645.  
  2646. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  2647. {
  2648. ResetPlugin();
  2649. }
  2650.  
  2651. void ResetPlugin()
  2652. {
  2653. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  2654. {
  2655. g_fTime[i] = 0.0;
  2656. }
  2657. }
  2658.  
  2659. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  2660. {
  2661. int client = GetClientOfUserId(event.GetInt("userid"));
  2662. if( !client || !IsClientInGame(client) ) return;
  2663.  
  2664.  
  2665. // Class check
  2666. // Smoker = 1; Spitter = 4; Tank = 8
  2667. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  2668. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  2669. switch( class )
  2670. {
  2671. case 1: class = 0;
  2672. case 4: class = 1;
  2673. case 8: class = 2;
  2674. default: class = 99;
  2675. }
  2676. if( !(g_iCvarType & (1 << class)) ) return;
  2677.  
  2678.  
  2679. // Bots check
  2680. if( g_iCvarAllow != 3 )
  2681. {
  2682. bool fake = IsFakeClient(client);
  2683. if( g_iCvarAllow == 1 && fake ) return;
  2684. if( g_iCvarAllow == 2 && !fake ) return;
  2685. }
  2686.  
  2687.  
  2688. // Event check
  2689. char sUse[16];
  2690. event.GetString("ability", sUse, sizeof(sUse));
  2691. if(
  2692. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  2693. || strcmp(sUse, "ability_throw") == 0
  2694. || strcmp(sUse, "ability_tongue") == 0
  2695. )
  2696. {
  2697. if( GetGameTime() - g_fTime[client] >= 3.0 )
  2698. {
  2699. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  2700. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  2701. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  2702. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  2703. }
  2704. g_fTime[client] = GetGameTime();
  2705. }
  2706. }
  2707.  
  2708. public void onThinkFunk(int client) //Dance
  2709. {
  2710. if( IsClientInGame(client) )
  2711. {
  2712. if( GetGameTime() - g_fTime[client] < 3.0 )
  2713. {
  2714. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  2715.  
  2716. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  2717. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  2718. {
  2719. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  2720. }
  2721. } else {
  2722. g_fTime[client] = 0.0;
  2723. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  2724. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  2725. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  2726. }
  2727. }
  2728. }#define PLUGIN_VERSION "1.1"
  2729.  
  2730. /*=======================================================================================
  2731. Plugin Info:
  2732.  
  2733. * Name : [L4D & L4D2] Special Infected Ability Movement
  2734. * Author : SilverShot
  2735. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  2736. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  2737.  
  2738. ========================================================================================
  2739. Change Log:
  2740.  
  2741. 1.1 (23-Aug-2018)
  2742. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  2743.  
  2744. 1.0 (05-May-2018)
  2745. - Initial release.
  2746.  
  2747. ======================================================================================*/
  2748.  
  2749. #pragma semicolon 1
  2750. #pragma newdecls required
  2751.  
  2752. #include <sourcemod>
  2753. #include <sdktools>
  2754. #include <sdkhooks>
  2755.  
  2756. #define CVAR_FLAGS FCVAR_NOTIFY
  2757.  
  2758.  
  2759. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  2760. int g_iCvarAllow, g_iCvarType;
  2761. bool g_bCvarAllow, g_bLeft4Dead2;
  2762. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  2763.  
  2764. enum ()
  2765. {
  2766. ENUM_SMOKE = 1,
  2767. ENUM_SPITS = 2,
  2768. ENUM_TANKS = 4
  2769. }
  2770.  
  2771.  
  2772.  
  2773. // ====================================================================================================
  2774. // PLUGIN INFO / START / END
  2775. // ====================================================================================================
  2776. public Plugin myinfo =
  2777. {
  2778. name = "[L4D & L4D2] Special Infected Ability Movement",
  2779. author = "SilverShot",
  2780. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  2781. version = PLUGIN_VERSION,
  2782. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  2783. }
  2784.  
  2785. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  2786. {
  2787. EngineVersion test = GetEngineVersion();
  2788. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  2789. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  2790. else
  2791. {
  2792. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  2793. return APLRes_SilentFailure;
  2794. }
  2795. return APLRes_Success;
  2796. }
  2797.  
  2798. public void OnPluginStart()
  2799. {
  2800. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  2801. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  2802. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  2803. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  2804. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  2805. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  2806. AutoExecConfig(true, "l4d_infected_movement");
  2807.  
  2808. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  2809. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  2810. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  2811. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  2812. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  2813. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  2814. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  2815.  
  2816. g_hSpeedTank = FindConVar("z_tank_speed");
  2817. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  2818. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  2819. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  2820.  
  2821. if( g_bLeft4Dead2 )
  2822. {
  2823. g_hSpeedSpit = FindConVar("z_spitter_speed");
  2824. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  2825. }
  2826. }
  2827.  
  2828.  
  2829.  
  2830. // ====================================================================================================
  2831. // CVARS
  2832. // ====================================================================================================
  2833. public void OnConfigsExecuted()
  2834. {
  2835. IsAllowed();
  2836. }
  2837.  
  2838. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  2839. {
  2840. IsAllowed();
  2841. }
  2842.  
  2843. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  2844. {
  2845. GetCvars();
  2846. }
  2847.  
  2848. void GetCvars()
  2849. {
  2850. if( g_bLeft4Dead2 )
  2851. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  2852. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  2853. g_fSpeedTank = g_hSpeedTank.FloatValue;
  2854. g_iCvarType = g_hCvarType.IntValue;
  2855. }
  2856.  
  2857. void IsAllowed()
  2858. {
  2859. g_iCvarAllow = g_hCvarAllow.IntValue;
  2860. bool bAllowMode = IsAllowedGameMode();
  2861. GetCvars();
  2862.  
  2863. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  2864. {
  2865. g_bCvarAllow = true;
  2866. HookEvent("round_end", Event_Reset);
  2867. HookEvent("round_start", Event_Reset);
  2868. HookEvent("ability_use", Event_Use);
  2869. }
  2870. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  2871. {
  2872. g_bCvarAllow = false;
  2873. UnhookEvent("round_end", Event_Reset);
  2874. UnhookEvent("round_start", Event_Reset);
  2875. UnhookEvent("ability_use", Event_Use);
  2876. }
  2877. }
  2878.  
  2879. int g_iCurrentMode;
  2880. bool IsAllowedGameMode()
  2881. {
  2882. if( g_hCvarMPGameMode == null )
  2883. return false;
  2884.  
  2885. int iCvarModesTog = g_hCvarModesTog.IntValue;
  2886. if( iCvarModesTog != 0 )
  2887. {
  2888. g_iCurrentMode = 0;
  2889.  
  2890. int entity = CreateEntityByName("info_gamemode");
  2891. DispatchSpawn(entity);
  2892. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  2893. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  2894. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  2895. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  2896. ActivateEntity(entity);
  2897. AcceptEntityInput(entity, "PostSpawnActivate");
  2898. AcceptEntityInput(entity, "Kill");
  2899.  
  2900. if( g_iCurrentMode == 0 )
  2901. return false;
  2902.  
  2903. if( !(iCvarModesTog & g_iCurrentMode) )
  2904. return false;
  2905. }
  2906.  
  2907. char sGameModes[64], sGameMode[64];
  2908. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  2909. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  2910.  
  2911. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  2912. if( strcmp(sGameModes, "") )
  2913. {
  2914. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2915. if( StrContains(sGameModes, sGameMode, false) == -1 )
  2916. return false;
  2917. }
  2918.  
  2919. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  2920. if( strcmp(sGameModes, "") )
  2921. {
  2922. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  2923. if( StrContains(sGameModes, sGameMode, false) != -1 )
  2924. return false;
  2925. }
  2926.  
  2927. return true;
  2928. }
  2929.  
  2930. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  2931. {
  2932. if( strcmp(output, "OnCoop") == 0 )
  2933. g_iCurrentMode = 1;
  2934. else if( strcmp(output, "OnSurvival") == 0 )
  2935. g_iCurrentMode = 2;
  2936. else if( strcmp(output, "OnVersus") == 0 )
  2937. g_iCurrentMode = 4;
  2938. else if( strcmp(output, "OnScavenge") == 0 )
  2939. g_iCurrentMode = 8;
  2940. }
  2941.  
  2942.  
  2943.  
  2944. // ====================================================================================================
  2945. // EVENTS
  2946. // ====================================================================================================
  2947. static float g_fTime[MAXPLAYERS+1];
  2948.  
  2949. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  2950. {
  2951. ResetPlugin();
  2952. }
  2953.  
  2954. void ResetPlugin()
  2955. {
  2956. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  2957. {
  2958. g_fTime[i] = 0.0;
  2959. }
  2960. }
  2961.  
  2962. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  2963. {
  2964. int client = GetClientOfUserId(event.GetInt("userid"));
  2965. if( !client || !IsClientInGame(client) ) return;
  2966.  
  2967.  
  2968. // Class check
  2969. // Smoker = 1; Spitter = 4; Tank = 8
  2970. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  2971. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  2972. switch( class )
  2973. {
  2974. case 1: class = 0;
  2975. case 4: class = 1;
  2976. case 8: class = 2;
  2977. default: class = 99;
  2978. }
  2979. if( !(g_iCvarType & (1 << class)) ) return;
  2980.  
  2981.  
  2982. // Bots check
  2983. if( g_iCvarAllow != 3 )
  2984. {
  2985. bool fake = IsFakeClient(client);
  2986. if( g_iCvarAllow == 1 && fake ) return;
  2987. if( g_iCvarAllow == 2 && !fake ) return;
  2988. }
  2989.  
  2990.  
  2991. // Event check
  2992. char sUse[16];
  2993. event.GetString("ability", sUse, sizeof(sUse));
  2994. if(
  2995. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  2996. || strcmp(sUse, "ability_throw") == 0
  2997. || strcmp(sUse, "ability_tongue") == 0
  2998. )
  2999. {
  3000. if( GetGameTime() - g_fTime[client] >= 3.0 )
  3001. {
  3002. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  3003. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  3004. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  3005. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  3006. }
  3007. g_fTime[client] = GetGameTime();
  3008. }
  3009. }
  3010.  
  3011. public void onThinkFunk(int client) //Dance
  3012. {
  3013. if( IsClientInGame(client) )
  3014. {
  3015. if( GetGameTime() - g_fTime[client] < 3.0 )
  3016. {
  3017. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  3018.  
  3019. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  3020. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  3021. {
  3022. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  3023. }
  3024. } else {
  3025. g_fTime[client] = 0.0;
  3026. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  3027. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  3028. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  3029. }
  3030. }
  3031. }#define PLUGIN_VERSION "1.1"
  3032.  
  3033. /*=======================================================================================
  3034. Plugin Info:
  3035.  
  3036. * Name : [L4D & L4D2] Special Infected Ability Movement
  3037. * Author : SilverShot
  3038. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  3039. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  3040.  
  3041. ========================================================================================
  3042. Change Log:
  3043.  
  3044. 1.1 (23-Aug-2018)
  3045. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  3046.  
  3047. 1.0 (05-May-2018)
  3048. - Initial release.
  3049.  
  3050. ======================================================================================*/
  3051.  
  3052. #pragma semicolon 1
  3053. #pragma newdecls required
  3054.  
  3055. #include <sourcemod>
  3056. #include <sdktools>
  3057. #include <sdkhooks>
  3058.  
  3059. #define CVAR_FLAGS FCVAR_NOTIFY
  3060.  
  3061.  
  3062. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  3063. int g_iCvarAllow, g_iCvarType;
  3064. bool g_bCvarAllow, g_bLeft4Dead2;
  3065. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  3066.  
  3067. enum ()
  3068. {
  3069. ENUM_SMOKE = 1,
  3070. ENUM_SPITS = 2,
  3071. ENUM_TANKS = 4
  3072. }
  3073.  
  3074.  
  3075.  
  3076. // ====================================================================================================
  3077. // PLUGIN INFO / START / END
  3078. // ====================================================================================================
  3079. public Plugin myinfo =
  3080. {
  3081. name = "[L4D & L4D2] Special Infected Ability Movement",
  3082. author = "SilverShot",
  3083. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  3084. version = PLUGIN_VERSION,
  3085. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  3086. }
  3087.  
  3088. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  3089. {
  3090. EngineVersion test = GetEngineVersion();
  3091. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  3092. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  3093. else
  3094. {
  3095. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  3096. return APLRes_SilentFailure;
  3097. }
  3098. return APLRes_Success;
  3099. }
  3100.  
  3101. public void OnPluginStart()
  3102. {
  3103. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  3104. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  3105. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  3106. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  3107. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  3108. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  3109. AutoExecConfig(true, "l4d_infected_movement");
  3110.  
  3111. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  3112. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  3113. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  3114. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  3115. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  3116. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  3117. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  3118.  
  3119. g_hSpeedTank = FindConVar("z_tank_speed");
  3120. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  3121. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  3122. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  3123.  
  3124. if( g_bLeft4Dead2 )
  3125. {
  3126. g_hSpeedSpit = FindConVar("z_spitter_speed");
  3127. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  3128. }
  3129. }
  3130.  
  3131.  
  3132.  
  3133. // ====================================================================================================
  3134. // CVARS
  3135. // ====================================================================================================
  3136. public void OnConfigsExecuted()
  3137. {
  3138. IsAllowed();
  3139. }
  3140.  
  3141. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  3142. {
  3143. IsAllowed();
  3144. }
  3145.  
  3146. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  3147. {
  3148. GetCvars();
  3149. }
  3150.  
  3151. void GetCvars()
  3152. {
  3153. if( g_bLeft4Dead2 )
  3154. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  3155. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  3156. g_fSpeedTank = g_hSpeedTank.FloatValue;
  3157. g_iCvarType = g_hCvarType.IntValue;
  3158. }
  3159.  
  3160. void IsAllowed()
  3161. {
  3162. g_iCvarAllow = g_hCvarAllow.IntValue;
  3163. bool bAllowMode = IsAllowedGameMode();
  3164. GetCvars();
  3165.  
  3166. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  3167. {
  3168. g_bCvarAllow = true;
  3169. HookEvent("round_end", Event_Reset);
  3170. HookEvent("round_start", Event_Reset);
  3171. HookEvent("ability_use", Event_Use);
  3172. }
  3173. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  3174. {
  3175. g_bCvarAllow = false;
  3176. UnhookEvent("round_end", Event_Reset);
  3177. UnhookEvent("round_start", Event_Reset);
  3178. UnhookEvent("ability_use", Event_Use);
  3179. }
  3180. }
  3181.  
  3182. int g_iCurrentMode;
  3183. bool IsAllowedGameMode()
  3184. {
  3185. if( g_hCvarMPGameMode == null )
  3186. return false;
  3187.  
  3188. int iCvarModesTog = g_hCvarModesTog.IntValue;
  3189. if( iCvarModesTog != 0 )
  3190. {
  3191. g_iCurrentMode = 0;
  3192.  
  3193. int entity = CreateEntityByName("info_gamemode");
  3194. DispatchSpawn(entity);
  3195. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  3196. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  3197. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  3198. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  3199. ActivateEntity(entity);
  3200. AcceptEntityInput(entity, "PostSpawnActivate");
  3201. AcceptEntityInput(entity, "Kill");
  3202.  
  3203. if( g_iCurrentMode == 0 )
  3204. return false;
  3205.  
  3206. if( !(iCvarModesTog & g_iCurrentMode) )
  3207. return false;
  3208. }
  3209.  
  3210. char sGameModes[64], sGameMode[64];
  3211. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  3212. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  3213.  
  3214. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  3215. if( strcmp(sGameModes, "") )
  3216. {
  3217. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  3218. if( StrContains(sGameModes, sGameMode, false) == -1 )
  3219. return false;
  3220. }
  3221.  
  3222. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  3223. if( strcmp(sGameModes, "") )
  3224. {
  3225. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  3226. if( StrContains(sGameModes, sGameMode, false) != -1 )
  3227. return false;
  3228. }
  3229.  
  3230. return true;
  3231. }
  3232.  
  3233. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  3234. {
  3235. if( strcmp(output, "OnCoop") == 0 )
  3236. g_iCurrentMode = 1;
  3237. else if( strcmp(output, "OnSurvival") == 0 )
  3238. g_iCurrentMode = 2;
  3239. else if( strcmp(output, "OnVersus") == 0 )
  3240. g_iCurrentMode = 4;
  3241. else if( strcmp(output, "OnScavenge") == 0 )
  3242. g_iCurrentMode = 8;
  3243. }
  3244.  
  3245.  
  3246.  
  3247. // ====================================================================================================
  3248. // EVENTS
  3249. // ====================================================================================================
  3250. static float g_fTime[MAXPLAYERS+1];
  3251.  
  3252. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  3253. {
  3254. ResetPlugin();
  3255. }
  3256.  
  3257. void ResetPlugin()
  3258. {
  3259. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  3260. {
  3261. g_fTime[i] = 0.0;
  3262. }
  3263. }
  3264.  
  3265. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  3266. {
  3267. int client = GetClientOfUserId(event.GetInt("userid"));
  3268. if( !client || !IsClientInGame(client) ) return;
  3269.  
  3270.  
  3271. // Class check
  3272. // Smoker = 1; Spitter = 4; Tank = 8
  3273. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  3274. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  3275. switch( class )
  3276. {
  3277. case 1: class = 0;
  3278. case 4: class = 1;
  3279. case 8: class = 2;
  3280. default: class = 99;
  3281. }
  3282. if( !(g_iCvarType & (1 << class)) ) return;
  3283.  
  3284.  
  3285. // Bots check
  3286. if( g_iCvarAllow != 3 )
  3287. {
  3288. bool fake = IsFakeClient(client);
  3289. if( g_iCvarAllow == 1 && fake ) return;
  3290. if( g_iCvarAllow == 2 && !fake ) return;
  3291. }
  3292.  
  3293.  
  3294. // Event check
  3295. char sUse[16];
  3296. event.GetString("ability", sUse, sizeof(sUse));
  3297. if(
  3298. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  3299. || strcmp(sUse, "ability_throw") == 0
  3300. || strcmp(sUse, "ability_tongue") == 0
  3301. )
  3302. {
  3303. if( GetGameTime() - g_fTime[client] >= 3.0 )
  3304. {
  3305. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  3306. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  3307. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  3308. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  3309. }
  3310. g_fTime[client] = GetGameTime();
  3311. }
  3312. }
  3313.  
  3314. public void onThinkFunk(int client) //Dance
  3315. {
  3316. if( IsClientInGame(client) )
  3317. {
  3318. if( GetGameTime() - g_fTime[client] < 3.0 )
  3319. {
  3320. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  3321.  
  3322. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  3323. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  3324. {
  3325. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  3326. }
  3327. } else {
  3328. g_fTime[client] = 0.0;
  3329. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  3330. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  3331. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  3332. }
  3333. }
  3334. }#define PLUGIN_VERSION "1.1"
  3335.  
  3336. /*=======================================================================================
  3337. Plugin Info:
  3338.  
  3339. * Name : [L4D & L4D2] Special Infected Ability Movement
  3340. * Author : SilverShot
  3341. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  3342. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  3343.  
  3344. ========================================================================================
  3345. Change Log:
  3346.  
  3347. 1.1 (23-Aug-2018)
  3348. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  3349.  
  3350. 1.0 (05-May-2018)
  3351. - Initial release.
  3352.  
  3353. ======================================================================================*/
  3354.  
  3355. #pragma semicolon 1
  3356. #pragma newdecls required
  3357.  
  3358. #include <sourcemod>
  3359. #include <sdktools>
  3360. #include <sdkhooks>
  3361.  
  3362. #define CVAR_FLAGS FCVAR_NOTIFY
  3363.  
  3364.  
  3365. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  3366. int g_iCvarAllow, g_iCvarType;
  3367. bool g_bCvarAllow, g_bLeft4Dead2;
  3368. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  3369.  
  3370. enum ()
  3371. {
  3372. ENUM_SMOKE = 1,
  3373. ENUM_SPITS = 2,
  3374. ENUM_TANKS = 4
  3375. }
  3376.  
  3377.  
  3378.  
  3379. // ====================================================================================================
  3380. // PLUGIN INFO / START / END
  3381. // ====================================================================================================
  3382. public Plugin myinfo =
  3383. {
  3384. name = "[L4D & L4D2] Special Infected Ability Movement",
  3385. author = "SilverShot",
  3386. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  3387. version = PLUGIN_VERSION,
  3388. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  3389. }
  3390.  
  3391. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  3392. {
  3393. EngineVersion test = GetEngineVersion();
  3394. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  3395. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  3396. else
  3397. {
  3398. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  3399. return APLRes_SilentFailure;
  3400. }
  3401. return APLRes_Success;
  3402. }
  3403.  
  3404. public void OnPluginStart()
  3405. {
  3406. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  3407. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  3408. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  3409. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  3410. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  3411. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  3412. AutoExecConfig(true, "l4d_infected_movement");
  3413.  
  3414. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  3415. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  3416. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  3417. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  3418. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  3419. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  3420. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  3421.  
  3422. g_hSpeedTank = FindConVar("z_tank_speed");
  3423. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  3424. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  3425. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  3426.  
  3427. if( g_bLeft4Dead2 )
  3428. {
  3429. g_hSpeedSpit = FindConVar("z_spitter_speed");
  3430. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  3431. }
  3432. }
  3433.  
  3434.  
  3435.  
  3436. // ====================================================================================================
  3437. // CVARS
  3438. // ====================================================================================================
  3439. public void OnConfigsExecuted()
  3440. {
  3441. IsAllowed();
  3442. }
  3443.  
  3444. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  3445. {
  3446. IsAllowed();
  3447. }
  3448.  
  3449. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  3450. {
  3451. GetCvars();
  3452. }
  3453.  
  3454. void GetCvars()
  3455. {
  3456. if( g_bLeft4Dead2 )
  3457. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  3458. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  3459. g_fSpeedTank = g_hSpeedTank.FloatValue;
  3460. g_iCvarType = g_hCvarType.IntValue;
  3461. }
  3462.  
  3463. void IsAllowed()
  3464. {
  3465. g_iCvarAllow = g_hCvarAllow.IntValue;
  3466. bool bAllowMode = IsAllowedGameMode();
  3467. GetCvars();
  3468.  
  3469. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  3470. {
  3471. g_bCvarAllow = true;
  3472. HookEvent("round_end", Event_Reset);
  3473. HookEvent("round_start", Event_Reset);
  3474. HookEvent("ability_use", Event_Use);
  3475. }
  3476. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  3477. {
  3478. g_bCvarAllow = false;
  3479. UnhookEvent("round_end", Event_Reset);
  3480. UnhookEvent("round_start", Event_Reset);
  3481. UnhookEvent("ability_use", Event_Use);
  3482. }
  3483. }
  3484.  
  3485. int g_iCurrentMode;
  3486. bool IsAllowedGameMode()
  3487. {
  3488. if( g_hCvarMPGameMode == null )
  3489. return false;
  3490.  
  3491. int iCvarModesTog = g_hCvarModesTog.IntValue;
  3492. if( iCvarModesTog != 0 )
  3493. {
  3494. g_iCurrentMode = 0;
  3495.  
  3496. int entity = CreateEntityByName("info_gamemode");
  3497. DispatchSpawn(entity);
  3498. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  3499. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  3500. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  3501. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  3502. ActivateEntity(entity);
  3503. AcceptEntityInput(entity, "PostSpawnActivate");
  3504. AcceptEntityInput(entity, "Kill");
  3505.  
  3506. if( g_iCurrentMode == 0 )
  3507. return false;
  3508.  
  3509. if( !(iCvarModesTog & g_iCurrentMode) )
  3510. return false;
  3511. }
  3512.  
  3513. char sGameModes[64], sGameMode[64];
  3514. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  3515. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  3516.  
  3517. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  3518. if( strcmp(sGameModes, "") )
  3519. {
  3520. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  3521. if( StrContains(sGameModes, sGameMode, false) == -1 )
  3522. return false;
  3523. }
  3524.  
  3525. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  3526. if( strcmp(sGameModes, "") )
  3527. {
  3528. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  3529. if( StrContains(sGameModes, sGameMode, false) != -1 )
  3530. return false;
  3531. }
  3532.  
  3533. return true;
  3534. }
  3535.  
  3536. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  3537. {
  3538. if( strcmp(output, "OnCoop") == 0 )
  3539. g_iCurrentMode = 1;
  3540. else if( strcmp(output, "OnSurvival") == 0 )
  3541. g_iCurrentMode = 2;
  3542. else if( strcmp(output, "OnVersus") == 0 )
  3543. g_iCurrentMode = 4;
  3544. else if( strcmp(output, "OnScavenge") == 0 )
  3545. g_iCurrentMode = 8;
  3546. }
  3547.  
  3548.  
  3549.  
  3550. // ====================================================================================================
  3551. // EVENTS
  3552. // ====================================================================================================
  3553. static float g_fTime[MAXPLAYERS+1];
  3554.  
  3555. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  3556. {
  3557. ResetPlugin();
  3558. }
  3559.  
  3560. void ResetPlugin()
  3561. {
  3562. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  3563. {
  3564. g_fTime[i] = 0.0;
  3565. }
  3566. }
  3567.  
  3568. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  3569. {
  3570. int client = GetClientOfUserId(event.GetInt("userid"));
  3571. if( !client || !IsClientInGame(client) ) return;
  3572.  
  3573.  
  3574. // Class check
  3575. // Smoker = 1; Spitter = 4; Tank = 8
  3576. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  3577. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  3578. switch( class )
  3579. {
  3580. case 1: class = 0;
  3581. case 4: class = 1;
  3582. case 8: class = 2;
  3583. default: class = 99;
  3584. }
  3585. if( !(g_iCvarType & (1 << class)) ) return;
  3586.  
  3587.  
  3588. // Bots check
  3589. if( g_iCvarAllow != 3 )
  3590. {
  3591. bool fake = IsFakeClient(client);
  3592. if( g_iCvarAllow == 1 && fake ) return;
  3593. if( g_iCvarAllow == 2 && !fake ) return;
  3594. }
  3595.  
  3596.  
  3597. // Event check
  3598. char sUse[16];
  3599. event.GetString("ability", sUse, sizeof(sUse));
  3600. if(
  3601. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  3602. || strcmp(sUse, "ability_throw") == 0
  3603. || strcmp(sUse, "ability_tongue") == 0
  3604. )
  3605. {
  3606. if( GetGameTime() - g_fTime[client] >= 3.0 )
  3607. {
  3608. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  3609. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  3610. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  3611. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  3612. }
  3613. g_fTime[client] = GetGameTime();
  3614. }
  3615. }
  3616.  
  3617. public void onThinkFunk(int client) //Dance
  3618. {
  3619. if( IsClientInGame(client) )
  3620. {
  3621. if( GetGameTime() - g_fTime[client] < 3.0 )
  3622. {
  3623. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  3624.  
  3625. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  3626. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  3627. {
  3628. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  3629. }
  3630. } else {
  3631. g_fTime[client] = 0.0;
  3632. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  3633. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  3634. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  3635. }
  3636. }
  3637. }#define PLUGIN_VERSION "1.1"
  3638.  
  3639. /*=======================================================================================
  3640. Plugin Info:
  3641.  
  3642. * Name : [L4D & L4D2] Special Infected Ability Movement
  3643. * Author : SilverShot
  3644. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  3645. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  3646.  
  3647. ========================================================================================
  3648. Change Log:
  3649.  
  3650. 1.1 (23-Aug-2018)
  3651. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  3652.  
  3653. 1.0 (05-May-2018)
  3654. - Initial release.
  3655.  
  3656. ======================================================================================*/
  3657.  
  3658. #pragma semicolon 1
  3659. #pragma newdecls required
  3660.  
  3661. #include <sourcemod>
  3662. #include <sdktools>
  3663. #include <sdkhooks>
  3664.  
  3665. #define CVAR_FLAGS FCVAR_NOTIFY
  3666.  
  3667.  
  3668. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  3669. int g_iCvarAllow, g_iCvarType;
  3670. bool g_bCvarAllow, g_bLeft4Dead2;
  3671. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  3672.  
  3673. enum ()
  3674. {
  3675. ENUM_SMOKE = 1,
  3676. ENUM_SPITS = 2,
  3677. ENUM_TANKS = 4
  3678. }
  3679.  
  3680.  
  3681.  
  3682. // ====================================================================================================
  3683. // PLUGIN INFO / START / END
  3684. // ====================================================================================================
  3685. public Plugin myinfo =
  3686. {
  3687. name = "[L4D & L4D2] Special Infected Ability Movement",
  3688. author = "SilverShot",
  3689. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  3690. version = PLUGIN_VERSION,
  3691. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  3692. }
  3693.  
  3694. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  3695. {
  3696. EngineVersion test = GetEngineVersion();
  3697. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  3698. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  3699. else
  3700. {
  3701. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  3702. return APLRes_SilentFailure;
  3703. }
  3704. return APLRes_Success;
  3705. }
  3706.  
  3707. public void OnPluginStart()
  3708. {
  3709. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  3710. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  3711. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  3712. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  3713. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  3714. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  3715. AutoExecConfig(true, "l4d_infected_movement");
  3716.  
  3717. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  3718. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  3719. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  3720. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  3721. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  3722. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  3723. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  3724.  
  3725. g_hSpeedTank = FindConVar("z_tank_speed");
  3726. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  3727. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  3728. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  3729.  
  3730. if( g_bLeft4Dead2 )
  3731. {
  3732. g_hSpeedSpit = FindConVar("z_spitter_speed");
  3733. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  3734. }
  3735. }
  3736.  
  3737.  
  3738.  
  3739. // ====================================================================================================
  3740. // CVARS
  3741. // ====================================================================================================
  3742. public void OnConfigsExecuted()
  3743. {
  3744. IsAllowed();
  3745. }
  3746.  
  3747. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  3748. {
  3749. IsAllowed();
  3750. }
  3751.  
  3752. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  3753. {
  3754. GetCvars();
  3755. }
  3756.  
  3757. void GetCvars()
  3758. {
  3759. if( g_bLeft4Dead2 )
  3760. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  3761. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  3762. g_fSpeedTank = g_hSpeedTank.FloatValue;
  3763. g_iCvarType = g_hCvarType.IntValue;
  3764. }
  3765.  
  3766. void IsAllowed()
  3767. {
  3768. g_iCvarAllow = g_hCvarAllow.IntValue;
  3769. bool bAllowMode = IsAllowedGameMode();
  3770. GetCvars();
  3771.  
  3772. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  3773. {
  3774. g_bCvarAllow = true;
  3775. HookEvent("round_end", Event_Reset);
  3776. HookEvent("round_start", Event_Reset);
  3777. HookEvent("ability_use", Event_Use);
  3778. }
  3779. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  3780. {
  3781. g_bCvarAllow = false;
  3782. UnhookEvent("round_end", Event_Reset);
  3783. UnhookEvent("round_start", Event_Reset);
  3784. UnhookEvent("ability_use", Event_Use);
  3785. }
  3786. }
  3787.  
  3788. int g_iCurrentMode;
  3789. bool IsAllowedGameMode()
  3790. {
  3791. if( g_hCvarMPGameMode == null )
  3792. return false;
  3793.  
  3794. int iCvarModesTog = g_hCvarModesTog.IntValue;
  3795. if( iCvarModesTog != 0 )
  3796. {
  3797. g_iCurrentMode = 0;
  3798.  
  3799. int entity = CreateEntityByName("info_gamemode");
  3800. DispatchSpawn(entity);
  3801. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  3802. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  3803. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  3804. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  3805. ActivateEntity(entity);
  3806. AcceptEntityInput(entity, "PostSpawnActivate");
  3807. AcceptEntityInput(entity, "Kill");
  3808.  
  3809. if( g_iCurrentMode == 0 )
  3810. return false;
  3811.  
  3812. if( !(iCvarModesTog & g_iCurrentMode) )
  3813. return false;
  3814. }
  3815.  
  3816. char sGameModes[64], sGameMode[64];
  3817. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  3818. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  3819.  
  3820. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  3821. if( strcmp(sGameModes, "") )
  3822. {
  3823. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  3824. if( StrContains(sGameModes, sGameMode, false) == -1 )
  3825. return false;
  3826. }
  3827.  
  3828. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  3829. if( strcmp(sGameModes, "") )
  3830. {
  3831. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  3832. if( StrContains(sGameModes, sGameMode, false) != -1 )
  3833. return false;
  3834. }
  3835.  
  3836. return true;
  3837. }
  3838.  
  3839. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  3840. {
  3841. if( strcmp(output, "OnCoop") == 0 )
  3842. g_iCurrentMode = 1;
  3843. else if( strcmp(output, "OnSurvival") == 0 )
  3844. g_iCurrentMode = 2;
  3845. else if( strcmp(output, "OnVersus") == 0 )
  3846. g_iCurrentMode = 4;
  3847. else if( strcmp(output, "OnScavenge") == 0 )
  3848. g_iCurrentMode = 8;
  3849. }
  3850.  
  3851.  
  3852.  
  3853. // ====================================================================================================
  3854. // EVENTS
  3855. // ====================================================================================================
  3856. static float g_fTime[MAXPLAYERS+1];
  3857.  
  3858. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  3859. {
  3860. ResetPlugin();
  3861. }
  3862.  
  3863. void ResetPlugin()
  3864. {
  3865. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  3866. {
  3867. g_fTime[i] = 0.0;
  3868. }
  3869. }
  3870.  
  3871. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  3872. {
  3873. int client = GetClientOfUserId(event.GetInt("userid"));
  3874. if( !client || !IsClientInGame(client) ) return;
  3875.  
  3876.  
  3877. // Class check
  3878. // Smoker = 1; Spitter = 4; Tank = 8
  3879. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  3880. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  3881. switch( class )
  3882. {
  3883. case 1: class = 0;
  3884. case 4: class = 1;
  3885. case 8: class = 2;
  3886. default: class = 99;
  3887. }
  3888. if( !(g_iCvarType & (1 << class)) ) return;
  3889.  
  3890.  
  3891. // Bots check
  3892. if( g_iCvarAllow != 3 )
  3893. {
  3894. bool fake = IsFakeClient(client);
  3895. if( g_iCvarAllow == 1 && fake ) return;
  3896. if( g_iCvarAllow == 2 && !fake ) return;
  3897. }
  3898.  
  3899.  
  3900. // Event check
  3901. char sUse[16];
  3902. event.GetString("ability", sUse, sizeof(sUse));
  3903. if(
  3904. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  3905. || strcmp(sUse, "ability_throw") == 0
  3906. || strcmp(sUse, "ability_tongue") == 0
  3907. )
  3908. {
  3909. if( GetGameTime() - g_fTime[client] >= 3.0 )
  3910. {
  3911. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  3912. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  3913. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  3914. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  3915. }
  3916. g_fTime[client] = GetGameTime();
  3917. }
  3918. }
  3919.  
  3920. public void onThinkFunk(int client) //Dance
  3921. {
  3922. if( IsClientInGame(client) )
  3923. {
  3924. if( GetGameTime() - g_fTime[client] < 3.0 )
  3925. {
  3926. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  3927.  
  3928. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  3929. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  3930. {
  3931. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  3932. }
  3933. } else {
  3934. g_fTime[client] = 0.0;
  3935. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  3936. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  3937. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  3938. }
  3939. }
  3940. }#define PLUGIN_VERSION "1.1"
  3941.  
  3942. /*=======================================================================================
  3943. Plugin Info:
  3944.  
  3945. * Name : [L4D & L4D2] Special Infected Ability Movement
  3946. * Author : SilverShot
  3947. * Descrp : Continue normal movement speed while spitting/smoking/tank throwing rock
  3948. * Link : http://forums.alliedmods.net/showthread.php?t=307330
  3949.  
  3950. ========================================================================================
  3951. Change Log:
  3952.  
  3953. 1.1 (23-Aug-2018)
  3954. - Fixed the Smoker not working correctly. Thanks to "phoenix0001" for reporting.
  3955.  
  3956. 1.0 (05-May-2018)
  3957. - Initial release.
  3958.  
  3959. ======================================================================================*/
  3960.  
  3961. #pragma semicolon 1
  3962. #pragma newdecls required
  3963.  
  3964. #include <sourcemod>
  3965. #include <sdktools>
  3966. #include <sdkhooks>
  3967.  
  3968. #define CVAR_FLAGS FCVAR_NOTIFY
  3969.  
  3970.  
  3971. ConVar g_hCvarAllow, g_hCvarMPGameMode, g_hCvarModes, g_hCvarModesOff, g_hCvarModesTog, g_hCvarType, g_hSpeedSmoke, g_hSpeedSpit, g_hSpeedTank;
  3972. int g_iCvarAllow, g_iCvarType;
  3973. bool g_bCvarAllow, g_bLeft4Dead2;
  3974. float g_fSpeedSmoke, g_fSpeedSpit, g_fSpeedTank;
  3975.  
  3976. enum ()
  3977. {
  3978. ENUM_SMOKE = 1,
  3979. ENUM_SPITS = 2,
  3980. ENUM_TANKS = 4
  3981. }
  3982.  
  3983.  
  3984.  
  3985. // ====================================================================================================
  3986. // PLUGIN INFO / START / END
  3987. // ====================================================================================================
  3988. public Plugin myinfo =
  3989. {
  3990. name = "[L4D & L4D2] Special Infected Ability Movement",
  3991. author = "SilverShot",
  3992. description = "Continue normal movement speed while spitting/smoking/tank throwing rocks.",
  3993. version = PLUGIN_VERSION,
  3994. url = "http://forums.alliedmods.net/showthread.php?t=307330"
  3995. }
  3996.  
  3997. public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
  3998. {
  3999. EngineVersion test = GetEngineVersion();
  4000. if (test == Engine_Left4Dead) g_bLeft4Dead2 = false;
  4001. else if (test == Engine_Left4Dead2) g_bLeft4Dead2 = true;
  4002. else
  4003. {
  4004. strcopy(error, err_max, "Plugin only supports Left 4 Dead 1 & 2.");
  4005. return APLRes_SilentFailure;
  4006. }
  4007. return APLRes_Success;
  4008. }
  4009.  
  4010. public void OnPluginStart()
  4011. {
  4012. g_hCvarAllow = CreateConVar( "l4d_infected_movement_allow", "3", "0=Plugin off, 1=Allow players only, 2=Allow bots only, 3=Both.", CVAR_FLAGS );
  4013. g_hCvarType = CreateConVar( "l4d_infected_movement_type", "7", "These Special Infected can use: 1=Smoker, 2=Spitter, 4=Tank, 7=All.", CVAR_FLAGS );
  4014. g_hCvarModes = CreateConVar( "l4d_infected_movement_modes", "", "Turn on the plugin in these game modes, separate by commas (no spaces). (Empty = all).", CVAR_FLAGS );
  4015. g_hCvarModesOff = CreateConVar( "l4d_infected_movement_modes_off", "", "Turn off the plugin in these game modes, separate by commas (no spaces). (Empty = none).", CVAR_FLAGS );
  4016. g_hCvarModesTog = CreateConVar( "l4d_infected_movement_modes_tog", "0", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", CVAR_FLAGS );
  4017. CreateConVar( "l4d_infected_movement_version", PLUGIN_VERSION, "Ability Movement plugin version.", CVAR_FLAGS|FCVAR_DONTRECORD);
  4018. AutoExecConfig(true, "l4d_infected_movement");
  4019.  
  4020. g_hCvarMPGameMode = FindConVar("mp_gamemode");
  4021. g_hCvarMPGameMode.AddChangeHook(ConVarChanged_Allow);
  4022. g_hCvarAllow.AddChangeHook(ConVarChanged_Allow);
  4023. g_hCvarModes.AddChangeHook(ConVarChanged_Allow);
  4024. g_hCvarModesOff.AddChangeHook(ConVarChanged_Allow);
  4025. g_hCvarModesTog.AddChangeHook(ConVarChanged_Allow);
  4026. g_hCvarType.AddChangeHook(ConVarChanged_Cvars);
  4027.  
  4028. g_hSpeedTank = FindConVar("z_tank_speed");
  4029. g_hSpeedTank.AddChangeHook(ConVarChanged_Cvars);
  4030. g_hSpeedSmoke = FindConVar("tongue_victim_max_speed");
  4031. g_hSpeedSmoke.AddChangeHook(ConVarChanged_Cvars);
  4032.  
  4033. if( g_bLeft4Dead2 )
  4034. {
  4035. g_hSpeedSpit = FindConVar("z_spitter_speed");
  4036. g_hSpeedSpit.AddChangeHook(ConVarChanged_Cvars);
  4037. }
  4038. }
  4039.  
  4040.  
  4041.  
  4042. // ====================================================================================================
  4043. // CVARS
  4044. // ====================================================================================================
  4045. public void OnConfigsExecuted()
  4046. {
  4047. IsAllowed();
  4048. }
  4049.  
  4050. public void ConVarChanged_Allow(Handle convar, const char[] oldValue, const char[] newValue)
  4051. {
  4052. IsAllowed();
  4053. }
  4054.  
  4055. public void ConVarChanged_Cvars(Handle convar, const char[] oldValue, const char[] newValue)
  4056. {
  4057. GetCvars();
  4058. }
  4059.  
  4060. void GetCvars()
  4061. {
  4062. if( g_bLeft4Dead2 )
  4063. g_fSpeedSpit = g_hSpeedSpit.FloatValue;
  4064. g_fSpeedSmoke = g_hSpeedSmoke.FloatValue;
  4065. g_fSpeedTank = g_hSpeedTank.FloatValue;
  4066. g_iCvarType = g_hCvarType.IntValue;
  4067. }
  4068.  
  4069. void IsAllowed()
  4070. {
  4071. g_iCvarAllow = g_hCvarAllow.IntValue;
  4072. bool bAllowMode = IsAllowedGameMode();
  4073. GetCvars();
  4074.  
  4075. if( g_bCvarAllow == false && g_iCvarAllow && bAllowMode == true )
  4076. {
  4077. g_bCvarAllow = true;
  4078. HookEvent("round_end", Event_Reset);
  4079. HookEvent("round_start", Event_Reset);
  4080. HookEvent("ability_use", Event_Use);
  4081. }
  4082. else if( g_bCvarAllow == true && (g_iCvarAllow == 0 || bAllowMode == false) )
  4083. {
  4084. g_bCvarAllow = false;
  4085. UnhookEvent("round_end", Event_Reset);
  4086. UnhookEvent("round_start", Event_Reset);
  4087. UnhookEvent("ability_use", Event_Use);
  4088. }
  4089. }
  4090.  
  4091. int g_iCurrentMode;
  4092. bool IsAllowedGameMode()
  4093. {
  4094. if( g_hCvarMPGameMode == null )
  4095. return false;
  4096.  
  4097. int iCvarModesTog = g_hCvarModesTog.IntValue;
  4098. if( iCvarModesTog != 0 )
  4099. {
  4100. g_iCurrentMode = 0;
  4101.  
  4102. int entity = CreateEntityByName("info_gamemode");
  4103. DispatchSpawn(entity);
  4104. HookSingleEntityOutput(entity, "OnCoop", OnGamemode, true);
  4105. HookSingleEntityOutput(entity, "OnSurvival", OnGamemode, true);
  4106. HookSingleEntityOutput(entity, "OnVersus", OnGamemode, true);
  4107. HookSingleEntityOutput(entity, "OnScavenge", OnGamemode, true);
  4108. ActivateEntity(entity);
  4109. AcceptEntityInput(entity, "PostSpawnActivate");
  4110. AcceptEntityInput(entity, "Kill");
  4111.  
  4112. if( g_iCurrentMode == 0 )
  4113. return false;
  4114.  
  4115. if( !(iCvarModesTog & g_iCurrentMode) )
  4116. return false;
  4117. }
  4118.  
  4119. char sGameModes[64], sGameMode[64];
  4120. g_hCvarMPGameMode.GetString(sGameMode, sizeof(sGameMode));
  4121. Format(sGameMode, sizeof(sGameMode), ",%s,", sGameMode);
  4122.  
  4123. g_hCvarModes.GetString(sGameModes, sizeof(sGameModes));
  4124. if( strcmp(sGameModes, "") )
  4125. {
  4126. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  4127. if( StrContains(sGameModes, sGameMode, false) == -1 )
  4128. return false;
  4129. }
  4130.  
  4131. g_hCvarModesOff.GetString(sGameModes, sizeof(sGameModes));
  4132. if( strcmp(sGameModes, "") )
  4133. {
  4134. Format(sGameModes, sizeof(sGameModes), ",%s,", sGameModes);
  4135. if( StrContains(sGameModes, sGameMode, false) != -1 )
  4136. return false;
  4137. }
  4138.  
  4139. return true;
  4140. }
  4141.  
  4142. public void OnGamemode(const char[] output, int caller, int activator, float delay)
  4143. {
  4144. if( strcmp(output, "OnCoop") == 0 )
  4145. g_iCurrentMode = 1;
  4146. else if( strcmp(output, "OnSurvival") == 0 )
  4147. g_iCurrentMode = 2;
  4148. else if( strcmp(output, "OnVersus") == 0 )
  4149. g_iCurrentMode = 4;
  4150. else if( strcmp(output, "OnScavenge") == 0 )
  4151. g_iCurrentMode = 8;
  4152. }
  4153.  
  4154.  
  4155.  
  4156. // ====================================================================================================
  4157. // EVENTS
  4158. // ====================================================================================================
  4159. static float g_fTime[MAXPLAYERS+1];
  4160.  
  4161. public void Event_Reset(Event event, const char[] name, bool dontBroadcast)
  4162. {
  4163. ResetPlugin();
  4164. }
  4165.  
  4166. void ResetPlugin()
  4167. {
  4168. for( int i = 0; i < sizeof(g_fTime[]); i++ )
  4169. {
  4170. g_fTime[i] = 0.0;
  4171. }
  4172. }
  4173.  
  4174. public void Event_Use(Event event, const char[] name, bool dontBroadcast)
  4175. {
  4176. int client = GetClientOfUserId(event.GetInt("userid"));
  4177. if( !client || !IsClientInGame(client) ) return;
  4178.  
  4179.  
  4180. // Class check
  4181. // Smoker = 1; Spitter = 4; Tank = 8
  4182. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  4183. if( !g_bLeft4Dead2 && class == 5 ) class = 8;
  4184. switch( class )
  4185. {
  4186. case 1: class = 0;
  4187. case 4: class = 1;
  4188. case 8: class = 2;
  4189. default: class = 99;
  4190. }
  4191. if( !(g_iCvarType & (1 << class)) ) return;
  4192.  
  4193.  
  4194. // Bots check
  4195. if( g_iCvarAllow != 3 )
  4196. {
  4197. bool fake = IsFakeClient(client);
  4198. if( g_iCvarAllow == 1 && fake ) return;
  4199. if( g_iCvarAllow == 2 && !fake ) return;
  4200. }
  4201.  
  4202.  
  4203. // Event check
  4204. char sUse[16];
  4205. event.GetString("ability", sUse, sizeof(sUse));
  4206. if(
  4207. (g_bLeft4Dead2 && strcmp(sUse, "ability_spit") == 0)
  4208. || strcmp(sUse, "ability_throw") == 0
  4209. || strcmp(sUse, "ability_tongue") == 0
  4210. )
  4211. {
  4212. if( GetGameTime() - g_fTime[client] >= 3.0 )
  4213. {
  4214. // Hooked 3 times, because each alone is not enough, this creates the smoothest play with minimal movement stutter
  4215. SDKHook(client, SDKHook_PostThinkPost, onThinkFunk);
  4216. SDKHook(client, SDKHook_PreThink, onThinkFunk);
  4217. SDKHook(client, SDKHook_PreThinkPost, onThinkFunk);
  4218. }
  4219. g_fTime[client] = GetGameTime();
  4220. }
  4221. }
  4222.  
  4223. public void onThinkFunk(int client) //Dance
  4224. {
  4225. if( IsClientInGame(client) )
  4226. {
  4227. if( GetGameTime() - g_fTime[client] < 3.0 )
  4228. {
  4229. SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
  4230.  
  4231. int class = GetEntProp(client, Prop_Send, "m_zombieClass");
  4232. if( class == 1 || class == 4 || class == 8 || (!g_bLeft4Dead2 && class == 5) )
  4233. {
  4234. SetEntPropFloat(client, Prop_Send, "m_flMaxspeed", class == 4 ? g_fSpeedSpit : class == 1 ? g_fSpeedSmoke : g_fSpeedTank);
  4235. }
  4236. } else {
  4237. g_fTime[client] = 0.0;
  4238. SDKUnhook(client, SDKHook_PostThinkPost, onThinkFunk);
  4239. SDKUnhook(client, SDKHook_PreThink, onThinkFunk);
  4240. SDKUnhook(client, SDKHook_PreThinkPost, onThinkFunk);
  4241. }
  4242. }
  4243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement