diff --git a/README.md b/README.md index c893f03..3bbd3e1 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ All my sourcemod plugins... shitty probably * [BetterWitchAvoidance](#BetterWitchAvoidance) * [L4D2FFKickProtection](#L4D2FFKickProtection) * [l4d2_ff_test](#l4d2_ff_test) +* [CSGOTroll](#CSGOTroll) ## Descriptions ### csgo-knifehp @@ -71,9 +72,17 @@ Inspired by the 200IQBots_FlyYouFools. Bots avoid witch if its over 40% anger wh ### L4D2FFKickProtection Simple plugin that prevents a player that is being vote-kicked from doing any ff damage to teammates. * **Convars:** - * `sm_votekick_force_threshold` - The threshold of damage where the offending player is just immediately kicked. 0 -> Any attempted damage, -1 -> No auto kick. + * `sm_votekick_force_threshold <#>` - The threshold of damage where the offending player is just immediately kicked. 0 -> Any attempted damage, -1 -> No auto kick. ### l4d2_ff_test More of a joke plugin, it will prevent a player from picking up a m60 if their friendly fire count or damage is over a certain threshold (Hardcoded as 5 and 35 respectively) * **Commands:** * `sm_view_ff` - View the ff damage and count of all players + +### CSGOTroll +Another joke plugin, with it configured, a victim will have a % chance their shots just fail. This can be for the AWP or all weapons at least for now. +* **Convars:** + * `troll_enable <0/1>` - Enable troll. 0 -> OFF, 1 -> Shots + * `troll_shot_fail_percentage <0.0-1.1>` - percentage float (0.0 to 1.0) chance that victims' shots fail + * `troll_targets ` - comma seperated list of steamid64 targets (ex: STEAM_0:0:75141700) + * `troll_shot_mode <0/1>` - 0 -> ALL Weapons, 1 -> AWP \ No newline at end of file diff --git a/plugins/CSGOTroll.smx b/plugins/CSGOTroll.smx new file mode 100644 index 0000000..5cae2d4 Binary files /dev/null and b/plugins/CSGOTroll.smx differ diff --git a/scripting/CSGOTroll.sp b/scripting/CSGOTroll.sp new file mode 100644 index 0000000..565415d --- /dev/null +++ b/scripting/CSGOTroll.sp @@ -0,0 +1,112 @@ +#pragma semicolon 1 + +#define DEBUG + +#define PLUGIN_AUTHOR "" +#define PLUGIN_VERSION "0.00" + +#include +#include +#include +#include + +EngineVersion g_Game; +ConVar hTrollEnableState, hShotFailPercentage, hTrollTargets, hGunType; +bool TrollTargets[MAXPLAYERS+1], lateLoaded; + +public Plugin myinfo = +{ + name = "", + author = PLUGIN_AUTHOR, + description = "", + version = PLUGIN_VERSION, + url = "" +}; + +public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { + if(late) { + lateLoaded = true; + } +} + +public OnPluginStart() +{ + g_Game = GetEngineVersion(); + if(g_Game != Engine_CSGO && g_Game != Engine_CSS) + { + SetFailState("This plugin is for CSGO/CSS only."); + } + //convars + hTrollEnableState = CreateConVar("troll_enable", "1.0", "Enable troll. 0 -> OFF, 1 -> Shots", FCVAR_NONE, true, 0.0, true, 1.0); + hShotFailPercentage = CreateConVar("troll_shot_fail_percentage", "0.4", "The percentage that the troll acts (shots fail). float 0-1", FCVAR_NONE, true, 0.0, true, 1.0); + hTrollTargets = CreateConVar("troll_targets", "", "comma seperated list of steamid64 targets (ex: STEAM_0:0:75141700)", FCVAR_NONE); + hGunType = CreateConVar("troll_shot_mode", "0", "0 -> ALL Weapons, 1 -> AWP", FCVAR_NONE, true, 0.0, true, 1.0); + + if(lateLoaded) FindExistingVictims(); +} + +public void OnClientAuthorized(int client, const char[] auth) { + if(hTrollEnableState.IntValue > 0) { + if(StrContains(auth, "BOT", true) == -1) { + TestForTrollUser(client, auth); + } + } +} +public void OnClientPutInServer(int client) { + SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); +} +public OnClientDisconnect(int client) { + TrollTargets[client] = false; +} +public void FindExistingVictims() { + for(int i = 1; i <= MaxClients; i++) { + if(IsClientInGame(i) && IsClientAuthorized(i)) { + if(!IsFakeClient(i)) { + char auth[64]; + GetClientAuthId(i, AuthId_Steam2, auth, sizeof(auth)); + TestForTrollUser(i, auth); + } + SDKHook(i, SDKHook_OnTakeDamage, OnTakeDamage); + } + } +} +public bool TestForTrollUser(int client, const char[] auth) { + char targets[32][8]; + char raw_targets[64]; + hTrollTargets.GetString(raw_targets, sizeof(raw_targets)); + ExplodeString(raw_targets, ",", targets, 8, 32, false); + for(int i = 0; i < 8; i++) { + if(StrEqual(targets[i], auth, true)) { + PrintToServer("Troll victim detected with id %d and steamid %s", client, auth); + TrollTargets[client] = true; + return true; + } + } + return false; +} +public Action OnTakeDamage(int victim, int& attacker, int& inflictor, float& damage, int& damagetype, int& weapon, float damageForce[3], float damagePosition[3]) { + if(hTrollEnableState.IntValue == 1) { + if(TrollTargets[attacker]) { + bool try_failure = false; + char weapon_name[64]; + GetClientWeapon(victim, weapon_name, sizeof(weapon_name)); + + if(hGunType.IntValue == 0) { + try_failure = true; + }else{ + if(StrEqual(weapon_name, "weapon_awp", true)) { + try_failure = true; + } + + } + float random_float = GetURandomFloat(); + if(try_failure) { + if(FloatCompare(random_float, hShotFailPercentage.FloatValue) == -1) { + damage = 0.0; + return Plugin_Handled; + } + } + } + } + return Plugin_Continue; +} \ No newline at end of file