Advertisement
Guest User

Untitled

a guest
Jun 17th, 2016
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.58 KB | None | 0 0
  1. /*
  2. SourcePawn is Copyright (C) 2006-2015 AlliedModders LLC. All rights reserved.
  3. SourceMod is Copyright (C) 2006-2015 AlliedModders LLC. All rights reserved.
  4. Pawn and SMALL are Copyright (C) 1997-2015 ITB CompuPhase.
  5. Source is Copyright (C) Valve Corporation.
  6. All trademarks are property of their respective owners.
  7.  
  8. This program is free software: you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation, either version 3 of the License, or (at your
  11. option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful, but
  14. WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <sourcemod>
  22. #include <sdktools>
  23. #include <sdkhooks>
  24.  
  25. public Plugin:myinfo =
  26. {
  27. name = "L4D Pistol Delayer",
  28. author = "Griffin, darkid",
  29. description = "Limits pistol fire rate & allows slow fire while holding m1.",
  30. version = "0.3",
  31. url = "https://github.com/jacob404/Pro-Mod-4.0/releases/latest"
  32. };
  33.  
  34. new Float:g_fNextAttack[MAXPLAYERS + 1];
  35. new Float:g_fNextAutoFire[MAXPLAYERS + 1];
  36. new Handle:g_hPistolDelayDualies = INVALID_HANDLE;
  37. new Handle:g_hPistolDelaySingle = INVALID_HANDLE;
  38. new Handle:g_hPistolDelayIncapped = INVALID_HANDLE;
  39. new Handle:g_hPistolSlowFire = INVALID_HANDLE;
  40.  
  41. public OnPluginStart()
  42. {
  43. for (new client = 1; client <= MaxClients; client++)
  44. {
  45. if (!IsClientInGame(client)) continue;
  46. SDKHook(client, SDKHook_PostThinkPost, Hook_OnPostThinkPost);
  47. }
  48. // Defaults are from fastest firing on 30tick
  49. g_hPistolDelayDualies = CreateConVar("l4d_pistol_delay_dualies", "0.1", "Minimum time (in seconds) between dual pistol shots",
  50. FCVAR_PLUGIN | FCVAR_SPONLY | FCVAR_NOTIFY, true, 0.0, true, 5.0);
  51. g_hPistolDelaySingle = CreateConVar("l4d_pistol_delay_single", "0.2", "Minimum time (in seconds) between single pistol shots",
  52. FCVAR_PLUGIN | FCVAR_SPONLY | FCVAR_NOTIFY, true, 0.0, true, 5.0);
  53. g_hPistolDelayIncapped = CreateConVar("l4d_pistol_delay_incapped", "0.3", "Minimum time (in seconds) between pistol shots while incapped",
  54. FCVAR_PLUGIN | FCVAR_SPONLY | FCVAR_NOTIFY, true, 0.0, true, 5.0);
  55. g_hPistolSlowFire = CreateConVar("l4d_pistol_autofire_rate", "0.3", "Auto-fire rate for dualies (seconds per shot) while holding mouse1.",
  56. FCVAR_PLUGIN | FCVAR_SPONLY | FCVAR_NOTIFY, true, 0.0, true, 5.0);
  57.  
  58. HookEvent("weapon_fire", Event_WeaponFire);
  59. }
  60.  
  61. public OnMapStart()
  62. {
  63. for (new client = 1; client <= MaxClients; client++)
  64. {
  65. g_fNextAttack[client] = 0.0;
  66. }
  67. }
  68.  
  69. public OnClientPutInServer(client)
  70. {
  71. SDKHook(client, SDKHook_PreThink, Hook_OnPostThinkPost);
  72. g_fNextAttack[client] = 0.0;
  73. }
  74.  
  75. public Hook_OnPostThinkPost(client)
  76. {
  77. // Human survivors only
  78. if (!IsClientInGame(client) || IsFakeClient(client) || GetClientTeam(client) != 2) return;
  79. new activeweapon = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon");
  80. if (!IsValidEdict(activeweapon)) return;
  81. decl String:weaponname[64];
  82. GetEdictClassname(activeweapon, weaponname, sizeof(weaponname));
  83. if (strcmp(weaponname, "weapon_pistol") != 0) return;
  84.  
  85. new Float:old_value = GetEntPropFloat(activeweapon, Prop_Send, "m_flNextPrimaryAttack");
  86. new Float:new_value = g_fNextAttack[client];
  87.  
  88. // Never accidentally speed up fire rate
  89. if (new_value > old_value)
  90. {
  91. // PrintToChatAll("Readjusting delay: Old=%f, New=%f", old_value, new_value);
  92. SetEntPropFloat(activeweapon, Prop_Send, "m_flNextPrimaryAttack", new_value);
  93. }
  94. }
  95.  
  96. public Action:Event_WeaponFire(Handle:event, const String:name[], bool:dontBroadcast)
  97. {
  98. new client = GetClientOfUserId(GetEventInt(event, "userid"));
  99. if (!IsClientInGame(client) || IsFakeClient(client) || GetClientTeam(client) != 2) return;
  100. new activeweapon = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon");
  101. if (!IsValidEdict(activeweapon)) return;
  102. decl String:weaponname[64];
  103. GetEdictClassname(activeweapon, weaponname, sizeof(weaponname));
  104. if (strcmp(weaponname, "weapon_pistol") != 0) return;
  105. // new dualies = GetEntProp(activeweapon, Prop_Send, "m_hasDualWeapons");
  106. if (GetEntProp(client, Prop_Send, "m_isIncapacitated"))
  107. {
  108. g_fNextAttack[client] = GetGameTime() + GetConVarFloat(g_hPistolDelayIncapped);
  109. }
  110. // What is the difference between m_isDualWielding and m_hasDualWeapons ?
  111. else if (GetEntProp(activeweapon, Prop_Send, "m_isDualWielding"))
  112. {
  113. g_fNextAttack[client] = GetGameTime() + GetConVarFloat(g_hPistolDelayDualies);
  114. }
  115. else
  116. {
  117. g_fNextAttack[client] = GetGameTime() + GetConVarFloat(g_hPistolDelaySingle);
  118. }
  119. }
  120.  
  121.  
  122. public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon) {
  123. if (client <= 0 || client > MaxClients) return Plugin_Continue;
  124. if (!IsClientInGame(client)) return Plugin_Continue;
  125. if (IsFakeClient(client)) return Plugin_Continue;
  126. if (GetClientTeam(client) != 2) return Plugin_Continue;
  127. new activeweapon = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon");
  128. if (!IsValidEdict(activeweapon)) return Plugin_Continue;
  129. decl String:weaponname[64];
  130. GetEdictClassname(activeweapon, weaponname, sizeof(weaponname));
  131. if (strcmp(weaponname, "weapon_pistol") != 0) return Plugin_Continue;
  132.  
  133. if (buttons & IN_RELOAD == IN_RELOAD) {
  134. // Otherwise the user can't reload while their pistol is on cooldown.
  135. // If the delay is longer than the reload anim (~2.4 sec), they will not get credit for reloading until the cooldown wears off.
  136. // The reload will be canceled if weapons are changed during this time.
  137. SetEntPropFloat(activeweapon, Prop_Send, "m_flNextPrimaryAttack", GetGameTime());
  138. }
  139.  
  140. if (GetEntProp(client, Prop_Send, "m_isIncapacitated")) return Plugin_Continue;
  141. if (!GetEntProp(activeweapon, Prop_Send, "m_isDualWielding")) return Plugin_Continue;
  142.  
  143. if (buttons & IN_ATTACK == IN_ATTACK) {
  144. if (g_fNextAutoFire[client] == 0.0) { // Signal
  145. g_fNextAutoFire[client] = GetGameTime() + GetConVarFloat(g_hPistolSlowFire);
  146. } else if (GetGameTime() > g_fNextAutoFire[client]) {
  147. buttons &= ~IN_ATTACK; // Release M1 for them so the game thinks that they're clicking again next frame.
  148. g_fNextAutoFire[client] = GetGameTime() + GetConVarFloat(g_hPistolSlowFire);
  149. EmitSoundToAll("weapons/pistol/gunfire/pistol_dual_fire.wav", client, SNDCHAN_VOICE);
  150. return Plugin_Changed;
  151. }
  152. } else {
  153. g_fNextAutoFire[client] = 0.0; // Signals client not attacking
  154. }
  155.  
  156. return Plugin_Continue;
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement