diff --git a/addons/sourcemod/scripting/fix_fastmelee.sp b/addons/sourcemod/scripting/fix_fastmelee.sp index d1c298af1..fc526aaa0 100644 --- a/addons/sourcemod/scripting/fix_fastmelee.sp +++ b/addons/sourcemod/scripting/fix_fastmelee.sp @@ -1,95 +1,116 @@ +#pragma semicolon 1 +#pragma newdecls required + #include #include #include +#include + +#define DEBUG 0 -#define PL_VERSION "2.1" +//Handle g_hWeaponSwitchFwd; -new Handle:hWeaponSwitchFwd; +float g_fLastMeleeSwing[MAXPLAYERS + 1]; -new Float:fLastMeleeSwing[MAXPLAYERS + 1]; -new bool:bLate; +bool g_bLateLoad = false; + +public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int iErrMax) +{ + EngineVersion iEngine = GetEngineVersion(); + if (iEngine != Engine_Left4Dead2) { + strcopy(sError, iErrMax, "Plugin only supports Left 4 Dead 2."); + return APLRes_SilentFailure; + } + + //g_hWeaponSwitchFwd = CreateGlobalForward("OnClientMeleeSwitch", ET_Ignore, Param_Cell, Param_Cell); + g_bLateLoad = bLate; + return APLRes_Success; +} public Plugin myinfo = { name = "Fast melee fix", author = "sheo", description = "Fixes the bug with too fast melee attacks", - version = PL_VERSION, - url = "http://steamcommunity.com/groups/b1com" + version = "2.3", + url = "https://github.com/SirPlease/L4D2-Competitive-Rework" }; -public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) +public void OnPluginStart() { - bLate = late; - return APLRes_Success; -} + HookEvent("round_start", Event_Reset, EventHookMode_PostNoCopy); + //HookEvent("round_end", Event_Reset, EventHookMode_PostNoCopy); + HookEvent("weapon_fire", Event_WeaponFire, EventHookMode_Post); -public OnPluginStart() -{ - decl String:gfstring[128]; - GetGameFolderName(gfstring, sizeof(gfstring)); - if (!StrEqual(gfstring, "left4dead2", false)) - { - SetFailState("Plugin supports Left 4 dead 2 only!"); - } - HookEvent("weapon_fire", Event_WeaponFire); - CreateConVar("l4d2_fast_melee_fix_version", PL_VERSION, "Fast melee fix version"); - if (bLate) - { - for (new i = 1; i <= MaxClients; i++) - { - if (IsClientInGame(i) && !IsFakeClient(i)) - { - SDKHook(i, SDKHook_WeaponSwitchPost, OnWeaponSwitched); + if (g_bLateLoad) { + for (int i = 1; i <= MaxClients; i++) { + if (IsClientInGame(i)) { + OnClientPutInServer(i); } } } - - hWeaponSwitchFwd = CreateGlobalForward("OnClientMeleeSwitch", ET_Ignore, Param_Cell, Param_Cell); } -public OnClientPutInServer(client) +public void OnClientPutInServer(int iClient) { - if (!IsFakeClient(client)) - { - SDKHook(client, SDKHook_WeaponSwitchPost, OnWeaponSwitched); + if (!IsFakeClient(iClient)) { + SDKHook(iClient, SDKHook_WeaponSwitchPost, OnWeaponSwitched); } - fLastMeleeSwing[client] = 0.0; + + g_fLastMeleeSwing[iClient] = 0.0; } -Action:Event_WeaponFire(Handle:event, const String:name[], bool:dontBroadcast) +void Event_Reset(Event hEvent, const char[] sEntityName, bool bDontBroadcast) { - new client = GetClientOfUserId(GetEventInt(event, "userid")); - if (client > 0 && !IsFakeClient(client)) - { - decl String:sBuffer[64]; - GetEventString(event, "weapon", sBuffer, sizeof(sBuffer)); - if (StrEqual(sBuffer, "melee")) - { - fLastMeleeSwing[client] = GetGameTime(); - } + for (int i = 1; i <= MaxClients; i++) { + g_fLastMeleeSwing[i] = 0.0; } } -void OnWeaponSwitched(client, weapon) +void Event_WeaponFire(Event hEvent, const char[] sEventName, bool bDontBroadcast) { - if (!IsFakeClient(client) && IsValidEntity(weapon)) - { - decl String:sBuffer[32]; - GetEntityClassname(weapon, sBuffer, sizeof(sBuffer)); - if (StrEqual(sBuffer, "weapon_melee")) - { - new Float:fShouldbeNextAttack = fLastMeleeSwing[client] + 0.92; - new Float:fByServerNextAttack = GetGameTime() + 0.5; - SetEntPropFloat(weapon, Prop_Send, "m_flNextPrimaryAttack", (fShouldbeNextAttack > fByServerNextAttack) ? fShouldbeNextAttack : fByServerNextAttack); + int iWeaponId = hEvent.GetInt("weaponid"); + if (iWeaponId != WEPID_MELEE) { + return; + } - Call_StartForward(hWeaponSwitchFwd); + int iClient = GetClientOfUserId(hEvent.GetInt("userid")); + if (iClient < 1 || IsFakeClient(iClient)) { + return; + } - Call_PushCell(client); + g_fLastMeleeSwing[iClient] = GetGameTime(); - Call_PushCell(weapon); +#if DEBUG + char sWeaponName[ENTITY_MAX_NAME_LENGTH]; + hEvent.GetString("weapon", sWeaponName, sizeof(sWeaponName)); + PrintToChatAll("Event_WeaponFire: %N, weapon: %s, time: %f, iWeaponId: %d", iClient, sWeaponName, g_fLastMeleeSwing[iClient], iWeaponId); +#endif +} - Call_Finish(); - } +void OnWeaponSwitched(int iClient, int iWeapon) +{ + if (IsFakeClient(iClient) || !IsValidEdict(iWeapon)) { + return; } -} \ No newline at end of file + + char sWeaponName[ENTITY_MAX_NAME_LENGTH]; + GetEdictClassname(iWeapon, sWeaponName, sizeof(sWeaponName)); + if (strcmp(sWeaponName, "weapon_melee") != 0) { + return; + } + + float fShouldbeNextAttack = g_fLastMeleeSwing[iClient] + 0.92; + float fByServerNextAttack = GetGameTime() + 0.5; + float fNextAttack = (fShouldbeNextAttack > fByServerNextAttack) ? fShouldbeNextAttack : fByServerNextAttack; + SetEntPropFloat(iWeapon, Prop_Send, "m_flNextPrimaryAttack", fNextAttack); + + /*Call_StartForward(g_hWeaponSwitchFwd); + Call_PushCell(iClient); + Call_PushCell(iWeapon); + Call_Finish();*/ + +#if DEBUG + PrintToChatAll("OnWeaponSwitched: %N, weapon: %d (%s), fNextAttack: %f", iClient, iWeapon, sWeaponName, fNextAttack); +#endif +} diff --git a/addons/sourcemod/scripting/frozen_tank_fix.sp b/addons/sourcemod/scripting/frozen_tank_fix.sp index 46034821a..aba843c3e 100644 --- a/addons/sourcemod/scripting/frozen_tank_fix.sp +++ b/addons/sourcemod/scripting/frozen_tank_fix.sp @@ -1,54 +1,52 @@ +#pragma semicolon 1 +#pragma newdecls required + #include #include -#define PL_VERSION "2.0" +#define TEAM_INFECTED 3 +#define Z_TANK 8 -public Plugin:myinfo = +public Plugin myinfo = { name = "Fix frozen tanks", - version = PL_VERSION, + version = "2.2", author = "sheo", -} + url = "https://github.com/SirPlease/L4D2-Competitive-Rework" +}; -public OnPluginStart() +public void OnPluginStart() { HookEvent("player_incapacitated", Event_PlayerIncap); - CreateConVar("l4d2_fix_frozen_tank_version", PL_VERSION, "Frozen tank fix version", FCVAR_NOTIFY); } -void Event_PlayerIncap(Handle:event, const String:name[], bool:dontBroadcast) +void Event_PlayerIncap(Event hEvent, const char[] sEventName, bool bDontBroadcast) { - new client = GetClientOfUserId(GetEventInt(event, "userid")); - if (client > 0 && IsPlayerTank(client)) - { - CreateTimer(1.0, KillTank_tCallback); + int iClient = GetClientOfUserId(hEvent.GetInt("userid")); + if (iClient > 0 && IsPlayerTank(iClient)) { + CreateTimer(1.0, Timer_KillTankDelay, _, TIMER_FLAG_NO_MAPCHANGE); } } -Action:KillTank_tCallback(Handle:timer) +Action Timer_KillTankDelay(Handle hTimer) { - for (new i = 1; i <= MaxClients; i++) - { - if (IsPlayerTank(i) && IsIncapitated(i)) - { + for (int i = 1; i <= MaxClients; i++) { + if (IsPlayerTank(i) && IsIncapitated(i)) { ForcePlayerSuicide(i); } } + + return Plugin_Stop; } -bool:IsIncapitated(client) +bool IsPlayerTank(int iClient) { - return bool:GetEntProp(client, Prop_Send, "m_isIncapacitated"); + return (IsClientInGame(iClient) + && GetClientTeam(iClient) == TEAM_INFECTED + && GetEntProp(iClient, Prop_Send, "m_zombieClass") == Z_TANK); } -bool:IsPlayerTank(client) +bool IsIncapitated(int iClient) { - if (IsClientInGame(client) && GetClientTeam(client) == 3) - { - if (GetEntProp(client, Prop_Send, "m_zombieClass") == 8) - { - return true; - } - } - return false; -} \ No newline at end of file + return (GetEntProp(iClient, Prop_Send, "m_isIncapacitated", 1) > 0); +} diff --git a/addons/sourcemod/scripting/l4d2_byedoor.sp b/addons/sourcemod/scripting/l4d2_byedoor.sp index 0f6c49c48..12b356be3 100644 --- a/addons/sourcemod/scripting/l4d2_byedoor.sp +++ b/addons/sourcemod/scripting/l4d2_byedoor.sp @@ -1,15 +1,17 @@ #pragma semicolon 1 -#pragma newdecls required; +#pragma newdecls required #include #include +#define ENTITY_NAME_MAX_LENGTH 64 + public Plugin myinfo = { name = "Byebye Door", description = "Time to kill Saferoom Doors.", author = "Sir", - version = "1.1", + version = "1.2", url = "https://github.com/SirPlease/L4D2-Competitive-Rework" }; @@ -20,15 +22,21 @@ public void OnPluginStart() void Event_RoundStart(Event hEvent, const char[] eName, bool dontBroadcast) { - int EntityCount = GetEntityCount(); - char EdictClassName[128]; - for (int i = 0; i <= EntityCount; i++){ - if (IsValidEntity(i)) { - GetEdictClassname(i, EdictClassName, 128); - if (StrContains(EdictClassName, "prop_door_rotating_checkpoint", false) != -1 - && GetEntProp(i, Prop_Send, "m_bLocked", 4) == 1) { - AcceptEntityInput(i, "Kill", -1, -1, 0); - return; + int iEntityCount = GetEntityCount(); + char sClassName[ENTITY_NAME_MAX_LENGTH]; + + for (int i = (MaxClients + 1); i <= iEntityCount; i++){ + if (!IsValidEdict(i)) { + continue; + } + + GetEdictClassname(i, sClassName, sizeof(sClassName)); + + if (strcmp(sClassName, "prop_door_rotating_checkpoint", false) == 0) { + if (GetEntProp(i, Prop_Send, "m_bLocked", 1) > 0) { + RemoveEntity(i); + + break; } } } diff --git a/addons/sourcemod/scripting/l4d2_character_fix.sp b/addons/sourcemod/scripting/l4d2_character_fix.sp index 91e3bd153..1803530e3 100644 --- a/addons/sourcemod/scripting/l4d2_character_fix.sp +++ b/addons/sourcemod/scripting/l4d2_character_fix.sp @@ -1,36 +1,60 @@ +#pragma semicolon 1 +#pragma newdecls required + #include -new Handle:hCvarMaxZombies; +#define TEAM_SURVIVOR 2 +#define TEAM_INFECTED 3 + +ConVar g_hCvarMaxZombies = null; -public Plugin:myinfo = { +public Plugin myinfo = +{ name = "Character Fix", author = "someone", - version = "0.1", - description = "Fixes character change exploit in 1v1, 2v2, 3v3" + version = "0.2", + description = "Fixes character change exploit in 1v1, 2v2, 3v3", + url = "https://github.com/SirPlease/L4D2-Competitive-Rework" }; -public OnPluginStart() { - AddCommandListener(TeamCmd, "jointeam") - hCvarMaxZombies = FindConVar("z_max_player_zombies"); +public void OnPluginStart() +{ + AddCommandListener(TeamCmd, "jointeam"); + + g_hCvarMaxZombies = FindConVar("z_max_player_zombies"); } -Action:TeamCmd(client, const String:command[], argc) { - if (client && argc > 0) - { - static String:sBuffer[128]; - GetCmdArg(1, sBuffer, sizeof(sBuffer)); - new newteam = StringToInt(sBuffer); - if (GetClientTeam(client)==2 && (StrEqual("Infected", sBuffer, false) || newteam==3)) - { - new zombies = 0; - for (new i=1; i <= MaxClients; i++) - { - if (IsClientInGame(i) && GetClientTeam(i)==3) - zombies++; - } - if (zombies>=GetConVarInt(hCvarMaxZombies)) - return Plugin_Handled; +Action TeamCmd(int iClient, const char[] sCommand, int iArgc) +{ + if (iClient == 0 || iArgc < 1) { + return Plugin_Continue; + } + + char sBuffer[128]; + GetCmdArg(1, sBuffer, sizeof(sBuffer)); + int iNewteam = StringToInt(sBuffer); + + if (GetClientTeam(iClient) == TEAM_SURVIVOR + && (strcmp("Infected", sBuffer, false) == 0 + || iNewteam == TEAM_INFECTED) + ) { + if (GetInfectedCount() >= g_hCvarMaxZombies.IntValue) { + return Plugin_Handled; } } + return Plugin_Continue; -} \ No newline at end of file +} + +int GetInfectedCount() +{ + int iZombies = 0; + + for (int i = 1; i <= MaxClients; i++) { + if (IsClientInGame(i) && GetClientTeam(i) == TEAM_INFECTED) { + iZombies++; + } + } + + return iZombies; +} diff --git a/addons/sourcemod/scripting/l4d2_fireworks_noise_block.sp b/addons/sourcemod/scripting/l4d2_fireworks_noise_block.sp index dc8a2ded4..8f3edce83 100644 --- a/addons/sourcemod/scripting/l4d2_fireworks_noise_block.sp +++ b/addons/sourcemod/scripting/l4d2_fireworks_noise_block.sp @@ -1,27 +1,32 @@ +#pragma semicolon 1 +#pragma newdecls required + #include #include -public Plugin:myinfo = +public Plugin myinfo = { name = "L4D2 Fireworks Noise Blocker", description = "Focus on SI!", author = "Visor", - version = "0.3", - url = "https://github.com/Attano/L4D2-Competitive-Framework" + version = "0.4", + url = "https://github.com/SirPlease/L4D2-Competitive-Rework" }; -public OnPluginStart() +public void OnPluginStart() { - AddNormalSoundHook(NormalSHook:OnNormalSound); - AddAmbientSoundHook(AmbientSHook:OnAmbientSound); + AddNormalSoundHook(Hook_OnNormalSound); + AddAmbientSoundHook(Hook_OnAmbientSound); } -Action:OnNormalSound(int clients[64], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags) +Action Hook_OnNormalSound(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, \ + float &volume, int &level, int &pitch, int &flags, char soundEntry[PLATFORM_MAX_PATH], int &seed) { return (StrContains(sample, "firewerks", true) > -1) ? Plugin_Stop : Plugin_Continue; } -Action:OnAmbientSound(char sample[PLATFORM_MAX_PATH], int &entity, float &volume, int &level, int &pitch, float pos[3], int &flags, float &delay) +Action Hook_OnAmbientSound(char sample[PLATFORM_MAX_PATH], int &entity, float &volume, int &level, \ + int &pitch, float pos[3], int &flags, float &delay) { return (StrContains(sample, "firewerks", true) > -1) ? Plugin_Stop : Plugin_Continue; } diff --git a/addons/sourcemod/scripting/panel_text.sp b/addons/sourcemod/scripting/panel_text.sp index 1abfde583..d874db7aa 100644 --- a/addons/sourcemod/scripting/panel_text.sp +++ b/addons/sourcemod/scripting/panel_text.sp @@ -1,63 +1,78 @@ #pragma semicolon 1 +#pragma newdecls required #include #include -#define PLUGIN_VERSION "1 point 1" + #define MAX_TEXT_LENGTH 65 +#define MAX_STRING_COUNT 10 + +char g_sPanelText[MAX_STRING_COUNT][MAX_TEXT_LENGTH]; + +int g_iStringCount = 0; + +bool g_bAreStringsLocked = false; -public Plugin:myinfo = +ConVar g_hCvarReadyPanelTextDelay = null; + +public Plugin myinfo = { name = "Add Text To Readyup Panel", author = "epilimic", description = "Displays custom text in the readyup panel. Spanks for the help CanadaRox!", - version = PLUGIN_VERSION, - url = "http://buttsecs.org" + version = "1.2", + url = "https://github.com/SirPlease/L4D2-Competitive-Rework/" }; -new String:panelText[10][MAX_TEXT_LENGTH]; -new stringCount = 0; -new bool:areStringsLocked; -new Handle:sm_readypaneltextdelay; - -public OnPluginStart() +public void OnPluginStart() { - RegServerCmd("sm_addreadystring", AddReadyString_Cmd, "Sets the string to add to the ready-up panel", FCVAR_NONE); - RegServerCmd("sm_resetstringcount", ResetStringCount_Cmd, "Resets the string count", FCVAR_NONE); - RegServerCmd("sm_lockstrings", LockStrings_Cmd, "Locks the strings", FCVAR_NONE); - HookEvent("round_start", RoundStart_Event, EventHookMode_PostNoCopy); - sm_readypaneltextdelay = CreateConVar("sm_readypaneltextdelay", "4.0", "Delay before adding the text to the ready-up panel for order control", FCVAR_NONE, true, 0.0, true, 10.0); + g_hCvarReadyPanelTextDelay = CreateConVar("sm_readypaneltextdelay", "4.0", "Delay before adding the text to the ready-up panel for order control", _, true, 0.0, true, 10.0); + + RegServerCmd("sm_addreadystring", Cmd_AddReadyString, "Sets the string to add to the ready-up panel"); + RegServerCmd("sm_resetstringcount", Cmd_ResetStringCount, "Resets the string count"); + RegServerCmd("sm_lockstrings", Cmd_LockStrings, "Locks the strings"); + + HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy); } -Action:LockStrings_Cmd(args) +Action Cmd_LockStrings(int iArgs) { - areStringsLocked = true; + g_bAreStringsLocked = true; return Plugin_Handled; } -Action:AddReadyString_Cmd(args) +Action Cmd_AddReadyString(int iArgs) { - if (stringCount < 10 && !areStringsLocked) - { - GetCmdArg(1, panelText[stringCount], MAX_TEXT_LENGTH); - ++stringCount; + if (g_iStringCount < MAX_STRING_COUNT && !g_bAreStringsLocked) { + GetCmdArg(1, g_sPanelText[g_iStringCount], MAX_TEXT_LENGTH); + + ++g_iStringCount; } + return Plugin_Handled; } -Action:ResetStringCount_Cmd(args) +Action Cmd_ResetStringCount(int iArgs) { - stringCount = 0; - areStringsLocked = false; + g_iStringCount = 0; + g_bAreStringsLocked = false; + return Plugin_Handled; } -void RoundStart_Event(Handle:event, const String:name[], bool:dontBroadcast) +void Event_RoundStart(Event hEvent, const char[] sEventName, bool bDontBroadcast) { - CreateTimer(GetConVarFloat(sm_readypaneltextdelay), panelTimer); + float fTime = g_hCvarReadyPanelTextDelay.FloatValue; + CreateTimer(fTime, panelTimer, _, TIMER_FLAG_NO_MAPCHANGE); } -Action:panelTimer(Handle:timer) +Action panelTimer(Handle hTimer) { - for (new i = 0; i < stringCount && AddStringToReadyFooter(panelText[i]); i++) - { } + for (int i = 0; i < g_iStringCount; i++) { + if (!AddStringToReadyFooter(g_sPanelText[i])) { + break; + } + } + + return Plugin_Stop; } diff --git a/addons/sourcemod/scripting/smart_ai_rock.sp b/addons/sourcemod/scripting/smart_ai_rock.sp index ae170e93a..53712524b 100644 --- a/addons/sourcemod/scripting/smart_ai_rock.sp +++ b/addons/sourcemod/scripting/smart_ai_rock.sp @@ -1,23 +1,24 @@ #pragma semicolon 1 +#pragma newdecls required #include #include -public Plugin:myinfo = +public Plugin myinfo = { name = "Smart AI Rock", author = "CanadaRox", description = "Prevents AI tanks from throwing underhand rocks since he can't aim them correctly", - version = "1", - url = "https://github.com/CanadaRox/sourcemod-plugins/tree/master/smart_ai_rock" + version = "1.1", + url = "https://github.com/SirPlease/L4D2-Competitive-Rework" }; -public Action:L4D2_OnSelectTankAttack(client, &sequence) +public Action L4D2_OnSelectTankAttack(int iClient, int &iSequence) { - if (IsFakeClient(client) && sequence == 50) - { - sequence = GetRandomInt(0, 1) ? 49 : 51; + if (IsFakeClient(iClient) && iSequence == 50) { + iSequence = (GetRandomInt(0, 1)) ? 49 : 51; return Plugin_Handled; } + return Plugin_Continue; }