mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 21:43:22 +00:00
ftt: Refactor
This commit is contained in:
parent
72cac56b1a
commit
e6811228fa
9 changed files with 1200 additions and 1191 deletions
372
scripting/include/events.inc
Normal file
372
scripting/include/events.inc
Normal file
|
@ -0,0 +1,372 @@
|
|||
public void OnPluginEnd() {
|
||||
UnhookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
}
|
||||
public void OnMapEnd() {
|
||||
UnhookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
}
|
||||
public void OnMapStart() {
|
||||
AddFileToDownloadsTable("sound/custom/meow1.mp3");
|
||||
PrecacheSound("custom/meow1.mp3");
|
||||
|
||||
lastButtonUser = -1;
|
||||
HookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
CreateTimer(MAIN_TIMER_INTERVAL_S, Timer_Main, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
PrecacheSound("player/footsteps/clown/concrete1.wav");
|
||||
//CreateTimer(30.0, Timer_AutoPunishCheck, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
public void OnClientPutInServer(int client) {
|
||||
g_PendingBanTroll[client] = false;
|
||||
SDKHook(client, SDKHook_OnTakeDamage, Event_TakeDamage);
|
||||
}
|
||||
public void OnClientAuthorized(int client, const char[] auth) {
|
||||
if(!IsFakeClient(client)) {
|
||||
strcopy(steamids[client], 64, auth);
|
||||
}
|
||||
}
|
||||
public void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(g_PendingBanTroll[client]) {
|
||||
g_PendingBanTroll[client] = false;
|
||||
if(!IsFakeClient(client) && GetUserAdmin(client) == INVALID_ADMIN_ID) {
|
||||
BanIdentity(steamids[client], 0, BANFLAG_AUTHID, "TrollMarked", "ftt", 0);
|
||||
}
|
||||
}
|
||||
steamids[client][0] = '\0';
|
||||
ActiveTrolls[client] = 0;
|
||||
g_iAttackerTarget[client] = 0;
|
||||
}
|
||||
public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
g_iAttackerTarget[client] = 0;
|
||||
}
|
||||
public Action Event_WeaponReload(int weapon) {
|
||||
int client = GetEntPropEnt(weapon, Prop_Send, "m_hOwner");
|
||||
if(IsTrollActive(client, "GunJam")) {
|
||||
float dec = GetRandomFloat(0.0, 1.0);
|
||||
if(FloatCompare(dec, 0.50) == -1) { //10% chance gun jams
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public Action Event_ButtonPress(const char[] output, int entity, int client, float delay) {
|
||||
if(client > 0 && client <= MaxClients) {
|
||||
lastButtonUser = client;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public void Event_PanicEventCreate(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client) {
|
||||
lastButtonUser = client;
|
||||
}
|
||||
}
|
||||
public void Event_CarAlarm(Event event, const char[] name, bool dontBroadcast) {
|
||||
int user = event.GetInt("userid");
|
||||
int client = GetClientOfUserId(user);
|
||||
if(client) {
|
||||
PrintToChatAll("%N has alerted the horde!", client);
|
||||
L4D2_RunScript("RushVictim(GetPlayerFromUserID(%d), %d)", user, 15000);
|
||||
}
|
||||
//Ignore car alarms for autopunish
|
||||
lastButtonUser = -1;
|
||||
}
|
||||
public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
||||
// =========================
|
||||
// OVERRIDE VICTIM
|
||||
// =========================
|
||||
if(hMagnetChance.FloatValue < GetRandomFloat()) return Plugin_Continue;
|
||||
L4D2Infected class = view_as<L4D2Infected>(GetEntProp(attacker, Prop_Send, "m_zombieClass"));
|
||||
int existingTarget = GetClientOfUserId(g_iAttackerTarget[attacker]);
|
||||
if(existingTarget > 0 && IsPlayerAlive(existingTarget) && (hMagnetTargetMode.IntValue & 1 != 1 || !IsPlayerIncapped(existingTarget))) {
|
||||
if(class == L4D2Infected_Tank && (hMagnetTargetMode.IntValue % 2 != 2 || !IsPlayerIncapped(existingTarget))) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}else if(hMagnetTargetMode.IntValue & 1 != 1 || !IsPlayerIncapped(existingTarget)) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
}
|
||||
|
||||
float closestDistance, survPos[3], spPos[3];
|
||||
GetClientAbsOrigin(attacker, spPos);
|
||||
int closestClient = -1;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
//Ignore incapped players if turned on:
|
||||
if(IsPlayerIncapped(i)) {
|
||||
if((class == L4D2Infected_Tank && hMagnetTargetMode.IntValue & 2 == 2) || hMagnetTargetMode.IntValue & 1 == 1 ) continue;
|
||||
}
|
||||
|
||||
if(class == L4D2Infected_Tank && IsTrollActive(i, "TankMagnet") || (class != L4D2Infected_Tank && IsTrollActive(i, "SpecialMagnet"))) {
|
||||
GetClientAbsOrigin(i, survPos);
|
||||
float dist = GetVectorDistance(survPos, spPos, true);
|
||||
if(closestClient == -1 || dist < closestDistance) {
|
||||
closestDistance = dist;
|
||||
closestClient = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(closestClient > 0) {
|
||||
g_iAttackerTarget[attacker] = GetClientUserId(closestClient);
|
||||
curTarget = closestClient;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public Action L4D2_OnEntityShoved(int client, int entity, int weapon, float vecDir[3], bool bIsHighPounce) {
|
||||
if(client > 0 && client <= MaxClients && IsTrollActive(client, "NoShove") && hShoveFailChance.FloatValue > GetRandomFloat()) {
|
||||
return Plugin_Handled;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) {
|
||||
if(sArgs[0] == '@') return Plugin_Continue;
|
||||
if(IsTrollActive(client, "Honk")) {
|
||||
static char strings[32][7];
|
||||
int words = ExplodeString(sArgs, " ", strings, sizeof(strings), 5);
|
||||
for(int i = 0; i < words; i++) {
|
||||
if(GetRandomFloat() <= 0.8) strings[i] = "honk";
|
||||
else strings[i] = "squeak";
|
||||
}
|
||||
int length = 7 * words;
|
||||
char[] message = new char[length];
|
||||
ImplodeStrings(strings, 32, " ", message, length);
|
||||
CPrintToChatAll("{blue}%N {default}: %s", client, message);
|
||||
PrintToServer("%N: %s", client, sArgs);
|
||||
return Plugin_Handled;
|
||||
}else if(IsTrollActive(client, "iCantSpellNoMore")) {
|
||||
int type = GetRandomInt(1, trollKV.Size + 8);
|
||||
char letterSrc, replaceChar;
|
||||
switch(type) {
|
||||
case 1: {
|
||||
letterSrc = 'e';
|
||||
replaceChar = 'b';
|
||||
}
|
||||
case 2: {
|
||||
letterSrc = 't';
|
||||
replaceChar = 'e';
|
||||
}
|
||||
case 3: {
|
||||
letterSrc = 'i';
|
||||
replaceChar = 'e';
|
||||
}
|
||||
case 4: {
|
||||
letterSrc = 'a';
|
||||
replaceChar = 's';
|
||||
}
|
||||
case 5: {
|
||||
letterSrc = 'u';
|
||||
replaceChar = 'i';
|
||||
}
|
||||
case 6: {
|
||||
letterSrc = '.';
|
||||
replaceChar = '/';
|
||||
}
|
||||
case 7: {
|
||||
letterSrc = 'm';
|
||||
replaceChar = 'n';
|
||||
}
|
||||
case 8: {
|
||||
letterSrc = 'n';
|
||||
replaceChar = 'm';
|
||||
}
|
||||
case 9: {
|
||||
letterSrc = 'l';
|
||||
replaceChar = 'b';
|
||||
}
|
||||
case 10: {
|
||||
letterSrc = 'l';
|
||||
replaceChar = 'b';
|
||||
}
|
||||
case 11: {
|
||||
letterSrc = 'h';
|
||||
replaceChar = 'j';
|
||||
}
|
||||
case 12: {
|
||||
letterSrc = 'o';
|
||||
replaceChar = 'i';
|
||||
}
|
||||
case 13: {
|
||||
letterSrc = 'e';
|
||||
replaceChar = 'r';
|
||||
}
|
||||
|
||||
default:
|
||||
return Plugin_Continue;
|
||||
}
|
||||
int strLength = strlen(sArgs);
|
||||
char[] newMessage = new char[strLength + 20];
|
||||
int n = 0;
|
||||
while (sArgs[n] != '\0') {
|
||||
if(sArgs[n] == letterSrc) {
|
||||
newMessage[n] = replaceChar;
|
||||
}else{
|
||||
newMessage[n] = sArgs[n];
|
||||
}
|
||||
n++;
|
||||
}
|
||||
PrintToServer("%N: %s", client, sArgs);
|
||||
CPrintToChatAll("{blue}%N {default}: %s", client, newMessage);
|
||||
return Plugin_Handled;
|
||||
}else if(IsTrollActive(client, "NoProfanity")) {
|
||||
//TODO: Check all replacement words, if none were replaced then do full word
|
||||
//TODO: Lowercase .getstring
|
||||
static char strings[32][MAX_PHRASE_LENGTH];
|
||||
ArrayList phrases;
|
||||
bool foundWord = false;
|
||||
int words = ExplodeString(sArgs, " ", strings, 32, MAX_PHRASE_LENGTH);
|
||||
for(int i = 0; i < words; i++) {
|
||||
if(REPLACEMENT_PHRASES.GetValue(strings[i], phrases) && phrases.Length > 0) {
|
||||
foundWord = true;
|
||||
int c = phrases.GetString(GetRandomInt(0, phrases.Length - 1), strings[i], MAX_PHRASE_LENGTH);
|
||||
PrintToServer("replacement: %s (%d)", strings[i], c);
|
||||
}
|
||||
}
|
||||
int length = MAX_PHRASE_LENGTH * words;
|
||||
char[] message = new char[length];
|
||||
if(foundWord) {
|
||||
ImplodeStrings(strings, 32, " ", message, length);
|
||||
} else {
|
||||
REPLACEMENT_PHRASES.GetValue("_Full Message Phrases", phrases);
|
||||
phrases.GetString(GetRandomInt(0, phrases.Length - 1), message, MAX_PHRASE_LENGTH);
|
||||
}
|
||||
CPrintToChatAll("{blue}%N {default}: %s", client, message);
|
||||
PrintToServer("%N: %s", client, sArgs);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_ItemPickup(int client, int weapon) {
|
||||
if(IsTrollActive(client, "NoPickup")) {
|
||||
return Plugin_Stop;
|
||||
}else{
|
||||
static char wpnName[64];
|
||||
GetEdictClassname(weapon, wpnName, sizeof(wpnName));
|
||||
if(StrContains(wpnName, "rifle") > -1
|
||||
|| StrContains(wpnName, "smg") > -1
|
||||
|| StrContains(wpnName, "weapon_grenade_launcher") > -1
|
||||
|| StrContains(wpnName, "sniper") > -1
|
||||
|| StrContains(wpnName, "shotgun") > -1
|
||||
) {
|
||||
//If 4: Only UZI, if 5: Can't switch.
|
||||
if(IsTrollActive(client, "UziRules")) {
|
||||
static char currentWpn[32];
|
||||
GetClientWeaponName(client, 0, currentWpn, sizeof(currentWpn));
|
||||
if(StrEqual(wpnName, "weapon_smg", true)) {
|
||||
return Plugin_Continue;
|
||||
} else if(StrEqual(currentWpn, "weapon_smg", true)) {
|
||||
return Plugin_Stop;
|
||||
}else{
|
||||
int flags = GetCommandFlags("give");
|
||||
SetCommandFlags("give", flags & ~FCVAR_CHEAT);
|
||||
FakeClientCommand(client, "give smg");
|
||||
SetCommandFlags("give", flags);
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}else if(IsTrollActive(client, "PrimaryDisable")) {
|
||||
return Plugin_Stop;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}else{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) {
|
||||
if(g_bPendingItemGive[client] && !(buttons & IN_ATTACK2)) {
|
||||
int target = GetClientAimTarget(client, true);
|
||||
if(target > -1) {
|
||||
buttons |= IN_ATTACK2;
|
||||
RequestFrame(StopItemGive, client);
|
||||
return Plugin_Changed;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_TakeDamage(int victim, int& attacker, int& inflictor, float& damage, int& damagetype) {
|
||||
//Stop FF from marked:
|
||||
if(attacker > 0 && attacker <= MaxClients && IsClientInGame(attacker) && IsPlayerAlive(attacker)) {
|
||||
if(g_PendingBanTroll[attacker] && GetClientTeam(attacker) == 2 && GetClientTeam(victim) == 2) {
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
if(IsTrollActive(attacker, "DamageBoost")) {
|
||||
damage * 2;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action SoundHook(int[] clients, int& numClients, char sample[PLATFORM_MAX_PATH], int& entity, int& channel, float& volume, int& level, int& pitch, int& flags, char[] soundEntry, int& seed) {
|
||||
if(lastButtonUser > -1 && StrEqual(sample, "npc/mega_mob/mega_mob_incoming.wav")) {
|
||||
PrintToConsoleAll("CRESCENDO STARTED BY %N", lastButtonUser);
|
||||
#if defined DEBUG
|
||||
PrintToChatAll("CRESCENDO STARTED BY %N", lastButtonUser);
|
||||
#endif
|
||||
|
||||
lastCrescendoUser = lastButtonUser;
|
||||
if(IsPlayerFarDistance(lastButtonUser, AUTOPUNISH_FLOW_MIN_DISTANCE)) {
|
||||
NotifyAllAdmins("Autopunishing player %N for activation of event far from team", lastButtonUser);
|
||||
ShowActivity(0, "activated autopunish for crescendo activator %N (auto)", lastButtonUser);
|
||||
ActivateAutoPunish(lastButtonUser);
|
||||
}
|
||||
lastButtonUser = -1;
|
||||
}else if(numClients > 0 && entity > 0 && entity <= MaxClients) {
|
||||
if(StrContains(sample, "survivor\\voice") > -1) {
|
||||
if(IsTrollActive(entity, "Honk")) {
|
||||
strcopy(sample, sizeof(sample), "player/footsteps/clown/concrete1.wav");
|
||||
return Plugin_Changed;
|
||||
} else if(IsTrollActive(entity, "VocalizeGag")) {
|
||||
return Plugin_Handled;
|
||||
} else if(IsTrollActive(entity, "Meow")) {
|
||||
strcopy(sample, sizeof(sample), "custom/meow1.mp3");
|
||||
return Plugin_Changed;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_WitchVictimSet(Event event, const char[] name, bool dontBroadcast) {
|
||||
int witch = event.GetInt("witchid");
|
||||
float closestDistance, survPos[3], witchPos[3];
|
||||
GetEntPropVector(witch, Prop_Send, "m_vecOrigin", witchPos);
|
||||
int closestClient = -1;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
//Ignore incapped players if hWitchIgnoreIncapp turned on:
|
||||
if(IsPlayerIncapped(i) && !hWitchTargetIncapp.BoolValue) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(IsTrollActive(i, "WitchMagnet")) {
|
||||
GetClientAbsOrigin(i, survPos);
|
||||
float dist = GetVectorDistance(survPos, witchPos, true);
|
||||
if(closestClient == -1 || dist < closestDistance) {
|
||||
closestDistance = dist;
|
||||
closestClient = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(closestClient > 0) {
|
||||
DataPack pack;
|
||||
CreateDataTimer(0.1, Timer_NextWitchSet, pack);
|
||||
pack.WriteCell(GetClientUserId(closestClient));
|
||||
pack.WriteCell(witch);
|
||||
CreateDataTimer(0.2, Timer_NextWitchSet, pack);
|
||||
pack.WriteCell(GetClientUserId(closestClient));
|
||||
pack.WriteCell(witch);
|
||||
}
|
||||
}
|
|
@ -4,21 +4,34 @@
|
|||
//#define DEBUG 1
|
||||
|
||||
enum TrollModifier {
|
||||
TrollMod_None = 0,
|
||||
TrollMod_InstantFire = 1,
|
||||
TrollMod_Repeat = 2
|
||||
TrollMod_Instant = 1,
|
||||
TrollMod_Constant = 2
|
||||
}
|
||||
|
||||
|
||||
enum struct Troll {
|
||||
char name[32];
|
||||
char description[128];
|
||||
|
||||
bool runsOnce;
|
||||
int flags;
|
||||
|
||||
void GetID(char[] name, int length) {
|
||||
strcopy(name, length, this.name);
|
||||
ReplaceString(name, MAX_TROLL_NAME_LENGTH, " ", "", false);
|
||||
}
|
||||
|
||||
bool HasMod(TrollMod mod) {
|
||||
return ((this.flags >> view_as<int>(mod)) & 1) == view_as<int>(mod);
|
||||
}
|
||||
|
||||
// Gets the default modifier to use
|
||||
TrollModifier GetDefaultMod() {
|
||||
// If the flags is equal to the 2^n flag, then it must be the only flag:
|
||||
if(this.flags == TrollMod_Instant) return TrollMod_Instant;
|
||||
else if(this.flags == TrollMod_Constant) return TrollMod_Constant;
|
||||
else return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Troll Trolls[MAX_TROLLS+1];
|
||||
|
@ -27,11 +40,21 @@ int ActiveTrolls[MAXPLAYERS+1];
|
|||
StringMap trollKV;
|
||||
char trollIds[MAX_TROLLS+1][MAX_TROLL_NAME_LENGTH];
|
||||
|
||||
int SetupTroll(const char[] name, const char description[128], bool hasMods) {
|
||||
void ResetClient(int victim, bool wipe = true) {
|
||||
if(wipe) ActiveTrolls[victim] = 0;
|
||||
SetEntityGravity(victim, 1.0);
|
||||
SetEntPropFloat(victim, Prop_Send, "m_flLaggedMovementValue", 1.0);
|
||||
SDKUnhook(victim, SDKHook_WeaponCanUse, Event_ItemPickup);
|
||||
int wpn = GetClientWeaponEntIndex(victim, 0);
|
||||
if(wpn > -1)
|
||||
SDKUnhook(wpn, SDKHook_Reload, Event_WeaponReload);
|
||||
}
|
||||
|
||||
int SetupTroll(const char[] name, const char description[128], int flags) {
|
||||
static int i = 0;
|
||||
strcopy(Trolls[i].name, MAX_TROLL_NAME_LENGTH, name);
|
||||
strcopy(Trolls[i].description, 128, description);
|
||||
Trolls[i].runsOnce = !hasMods;
|
||||
Trolls[i].flags = flags;
|
||||
static char key[MAX_TROLL_NAME_LENGTH];
|
||||
strcopy(key, MAX_TROLL_NAME_LENGTH, name);
|
||||
ReplaceString(key, MAX_TROLL_NAME_LENGTH, " ", "", false);
|
||||
|
@ -207,31 +230,31 @@ void DisableTroll(int client, const char[] troll) {
|
|||
|
||||
void SetupTrolls() {
|
||||
trollKV = new StringMap();
|
||||
SetupTroll("Reset Troll", "Resets the user, removes all troll effects", false);
|
||||
SetupTroll("Special Magnet", "Attracts ALL specials to any alive target with this troll enabled", false);
|
||||
SetupTroll("Tank Magnet", "Attracts ALL tanks to any alive target with this troll enabled", false);
|
||||
SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", false);
|
||||
SetupTroll("Vomit Player", "Shortcut to sm_vomitplayer. vomits the player.", false);
|
||||
SetupTroll("ThrowItAll", "Player throws all their items at nearby player, periodically", true);
|
||||
SetupTroll("Vocalize Gag", "Prevents player from sending any vocalizations (even automatic)", false);
|
||||
SetupTroll("No Profanity", "Replaces some words with random phrases", false);
|
||||
SetupTroll("Swarm", "Swarms a player with zombies. Requires swarm plugin", false);
|
||||
SetupTroll("UziRules", "Picking up a weapon gives them a UZI instead", false);
|
||||
SetupTroll("Slow Speed", "Sets player speed to 0.8x of normal speed", false);
|
||||
SetupTroll("Higher Gravity", "Sets player gravity to 1.3x of normal gravity", false);
|
||||
SetupTroll("Half Primary Ammo", "Cuts their primary reserve ammo in half", false);
|
||||
SetupTroll("PrimaryDisable", "Player cannot pickup any weapons, only melee/pistols", true);
|
||||
SetupTroll("Clusmy", "Player drops axe periodically or on demand", true);
|
||||
SetupTroll("iCantSpellNoMore", "Chat messages letter will randomly changed with wrong letters", false);
|
||||
SetupTroll("KillMeSoftly", "Make player eat or waste pills whenever possible", false);
|
||||
SetupTroll("GunJam", "On reload, small chance their gun gets jammed - Can't reload.", false);
|
||||
SetupTroll("NoPickup", "Prevents a player from picking up ANY (new) item. Use ThrowItAll to make them drop", true);
|
||||
SetupTroll("Honk", "Honk", false);
|
||||
SetupTroll("No Shove", "Prevents a player from shoving", false);
|
||||
SetupTroll("Damage Boost", "Makes a player take more damage than normal", false);
|
||||
SetupTroll("Temp Health Quick Drain", "Makes a player's temporarily health drain very quickly", false);
|
||||
SetupTroll("Slow Drain", "Will make the player slowly lose health over time", false);
|
||||
SetupTroll("CameTooEarly", "When they shoot, random chance they empty whole clip", true);
|
||||
SetupTroll("Reset Troll", "Resets the user, removes all troll effects", TrollMod_Instant);
|
||||
SetupTroll("Special Magnet", "Attracts ALL specials to any alive target with this troll enabled", TrollMod_Constant);
|
||||
SetupTroll("Tank Magnet", "Attracts ALL tanks to any alive target with this troll enabled", TrollMod_Constant);
|
||||
SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", TrollMod_Constant);
|
||||
SetupTroll("Vomit Player", "Shortcut to sm_vomitplayer. vomits the player.", TrollMod_Instant);
|
||||
SetupTroll("ThrowItAll", "Player throws all their items at nearby player, periodically", TrollMod_Instant | TrollMod_Constant);
|
||||
SetupTroll("Vocalize Gag", "Prevents player from sending any vocalizations (even automatic)", TrollMod_Constant);
|
||||
SetupTroll("No Profanity", "Replaces some words with random phrases", TrollMod_Constant);
|
||||
SetupTroll("Swarm", "Swarms a player with zombies. Requires swarm plugin", TrollMod_Instant);
|
||||
SetupTroll("UziRules", "Picking up a weapon gives them a UZI instead", TrollMod_Constant);
|
||||
SetupTroll("Slow Speed", "Sets player speed to 0.8x of normal speed", TrollMod_Constant);
|
||||
SetupTroll("Higher Gravity", "Sets player gravity to 1.3x of normal gravity", TrollMod_Constant);
|
||||
SetupTroll("Half Primary Ammo", "Cuts their primary reserve ammo in half", TrollMod_Instant);
|
||||
SetupTroll("PrimaryDisable", "Player cannot pickup any weapons, only melee/pistols", TrollMod_Constant);
|
||||
SetupTroll("Clusmy", "Player drops axe periodically or on demand", TrollMod_Instant | TrollMod_Constant);
|
||||
SetupTroll("iCantSpellNoMore", "Chat messages letter will randomly changed with wrong letters", TrollMod_Instant);
|
||||
SetupTroll("KillMeSoftly", "Make player eat or waste pills whenever possible", TrollMod_Instant | TrollMod_Constant);
|
||||
SetupTroll("GunJam", "On reload, small chance their gun gets jammed - Can't reload.", TrollMod_Constant);
|
||||
SetupTroll("NoPickup", "Prevents a player from picking up ANY (new) item. Use ThrowItAll to make them drop", TrollMod_Constant);
|
||||
SetupTroll("Honk", "Honk", TrollMod_Constant);
|
||||
SetupTroll("No Shove", "Prevents a player from shoving", TrollMod_Constant);
|
||||
SetupTroll("Damage Boost", "Makes a player take more damage than normal", TrollMod_Constant);
|
||||
SetupTroll("Temp Health Quick Drain", "Makes a player's temporarily health drain very quickly", TrollMod_Constant);
|
||||
SetupTroll("Slow Drain", "Will make the player slowly lose health over time", TrollMod_Constant);
|
||||
SetupTroll("CameTooEarly", "When they shoot, random chance they empty whole clip", TrollMod_Constant);
|
||||
SetupTroll("Meow", "Makes the player meow", false);
|
||||
//INFO: UP MAX_TROLLS when adding new trolls!
|
||||
}
|
348
scripting/include/feedthetrolls/commands.inc
Normal file
348
scripting/include/feedthetrolls/commands.inc
Normal file
|
@ -0,0 +1,348 @@
|
|||
public Action Command_InstaSpecial(int client, int args) {
|
||||
if(args < 1) {
|
||||
Menu menu = new Menu(Insta_PlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
static char userid[8], display[16];
|
||||
Format(userid, sizeof(userid), "%d|0", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
char arg1[32], arg2[32] = "jockey";
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
if(args >= 2) {
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
}
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MaxClients,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
int specialType = GetSpecialType(arg2);
|
||||
static float pos[3];
|
||||
if(specialType == -1) {
|
||||
ReplyToCommand(client, "Unknown special \"%s\"", arg2);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
int target = target_list[i];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
SpawnSpecialNear(target, specialType);
|
||||
}else{
|
||||
ReplyToTargetError(client, target_count);
|
||||
}
|
||||
}
|
||||
ShowActivity(client, "spawned Insta-%s™ near %s", arg2, target_name);
|
||||
}
|
||||
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_InstaSpecialFace(int client, int args) {
|
||||
if(args < 1) {
|
||||
Menu menu = new Menu(Insta_PlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
static char userid[8], display[16];
|
||||
Format(userid, sizeof(userid), "%d|1", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
char arg1[32], arg2[32] = "jockey";
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
if(args >= 2) {
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
}
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MaxClients,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
int specialType = GetSpecialType(arg2);
|
||||
static float pos[3];
|
||||
if(specialType == -1) {
|
||||
ReplyToCommand(client, "Unknown special \"%s\"", arg2);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
int target = target_list[i];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
SpawnSpecialInFace(target, specialType);
|
||||
}else{
|
||||
ReplyToTargetError(client, target_count);
|
||||
}
|
||||
}
|
||||
ShowActivity(client, "spawned Insta-%s™ on %s", arg2, target_name);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
||||
public Action Command_WitchAttack(int client, int args) {
|
||||
if(args < 1) {
|
||||
ReplyToCommand(client, "Usage: sm_witch_attack <user>");
|
||||
} else {
|
||||
char arg1[32];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
1,
|
||||
COMMAND_FILTER_ALIVE | COMMAND_FILTER_NO_MULTI, /* Only allow alive players */
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
int target = target_list[0];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
int witch = INVALID_ENT_REFERENCE;
|
||||
while ((witch = FindEntityByClassname(witch, "witch")) != INVALID_ENT_REFERENCE) {
|
||||
SetWitchTarget(witch, target);
|
||||
|
||||
ShowActivity(client, "all witches target %s", target_name);
|
||||
}
|
||||
}else{
|
||||
ReplyToTargetError(client, target_count);
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_FeedTheCrescendoTroll(int client, int args) {
|
||||
if(lastCrescendoUser > -1) {
|
||||
ActivateAutoPunish(lastCrescendoUser);
|
||||
ReplyToCommand(client, "Activated auto punish on %N", lastCrescendoUser);
|
||||
ShowActivity(client, "activated autopunish for crescendo activator %N",lastCrescendoUser);
|
||||
}else{
|
||||
ReplyToCommand(client, "No player could be found to autopunish.");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ResetUser(int client, int args) {
|
||||
if(args < 1) {
|
||||
ReplyToCommand(client, "Usage: sm_ftr <user(s)>");
|
||||
}else{
|
||||
char arg1[32];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_CONNECTED, /* Only allow alive players */
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
if(ActiveTrolls[target_list[i]] > 0) {
|
||||
ResetClient(target_list[i], true);
|
||||
ShowActivity(client, "reset troll effects on \"%N\". ", target_list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ApplyUser(int client, int args) {
|
||||
if(args < 2) {
|
||||
Menu menu = new Menu(ChoosePlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
static char userid[8], display[16];
|
||||
Format(userid, sizeof(userid), "%d", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
}else{
|
||||
char arg1[32], arg2[32], arg3[8];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
GetCmdArg(3, arg3, sizeof(arg3));
|
||||
|
||||
bool silent = StrEqual(arg3, "silent") || StrEqual(arg3, "quiet") || StrEqual(arg3, "mute");
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
if(!GetTrollID(StringToInt(arg2), name)) {
|
||||
ReplyToCommand(client, "Not a valid mode. Must be greater than 0. Usage: sm_fta [player] [mode]. Use sm_ftr <player> to reset.");
|
||||
}else{
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
if(IsClientInGame(target_list[i]) && GetClientTeam(target_list[i]) == 2)
|
||||
ApplyTroll(target_list[i], name, client, TrollMod_Instant, silent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ListModes(int client, int args) {
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
static Troll troll;
|
||||
for(int i = 0; i <= MAX_TROLLS; i++) {
|
||||
GetTrollByKeyIndex(i, troll);
|
||||
ReplyToCommand(client, "%d. %s - %s", i, troll.name, troll.description);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ListTheTrolls(int client, int args) {
|
||||
int count = 0;
|
||||
//TODO: Update
|
||||
char[][] modeListArr = new char[MAX_TROLLS+1][MAX_TROLL_NAME_LENGTH];
|
||||
static char modeList[255];
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && ActiveTrolls[i] > 0) {
|
||||
int modeCount = 0;
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
for(int j = 1; j <= MAX_TROLLS; j++) {
|
||||
GetTrollID(j, name);
|
||||
if(IsTrollActive(i, name)) {
|
||||
strcopy(modeListArr[modeCount], MAX_TROLL_NAME_LENGTH, name);
|
||||
modeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
ImplodeStrings(modeListArr, modeCount, ", ", modeList, sizeof(modeList));
|
||||
ReplyToCommand(client, "%N | %s", i, modeList);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count == 0) {
|
||||
ReplyToCommand(client, "No clients have a mode applied.");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_MarkPendingTroll(int client, int args) {
|
||||
if(args == 0) {
|
||||
Menu menu = new Menu(ChooseMarkedTroll);
|
||||
menu.SetTitle("Choose a troll to mark");
|
||||
static char userid[8], display[16];
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
AdminId admin = GetUserAdmin(i);
|
||||
if(admin == INVALID_ADMIN_ID) {
|
||||
Format(userid, sizeof(userid), "%d", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}else{
|
||||
ReplyToCommand(client, "%N is an admin cannot be marked.", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
char arg1[32];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
1,
|
||||
COMMAND_FILTER_NO_MULTI , /* Only allow alive players */
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
int target = target_list[0];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
ToggleMarkPlayer(client, target);
|
||||
}else{
|
||||
ReplyToCommand(client, "Player does not exist or is not a survivor.");
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_FeedTheTrollMenu(int client, int args) {
|
||||
ReplyToCommand(client, "sm_ftl - Lists all the active trolls on players");
|
||||
ReplyToCommand(client, "sm_ftm - Lists all available troll modes & descriptions");
|
||||
ReplyToCommand(client, "sm_ftr - Resets target users' of their trolls");
|
||||
ReplyToCommand(client, "sm_fta - Applies a troll mode on targets");
|
||||
ReplyToCommand(client, "sm_ftt - Opens this menu");
|
||||
ReplyToCommand(client, "sm_ftc - Will apply a punishment to last crescendo activator");
|
||||
ReplyToCommand(client, "sm_mark - Marks the user to be banned on disconnect, prevents their FF.");
|
||||
return Plugin_Handled;
|
||||
}
|
141
scripting/include/feedthetrolls/menus.inc
Normal file
141
scripting/include/feedthetrolls/menus.inc
Normal file
|
@ -0,0 +1,141 @@
|
|||
public int Insta_PlayerHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
|
||||
static char str[2][8];
|
||||
ExplodeString(info, "|", str, 2, 8, false);
|
||||
|
||||
int userid = StringToInt(str[0]);
|
||||
int instaMode = StringToInt(str[1]);
|
||||
|
||||
Menu spMenu = new Menu(Insta_SpecialHandler);
|
||||
spMenu.SetTitle("Choose a Insta-Special™");
|
||||
for(int i = 1; i <= 6; i++) {
|
||||
static char id[8];
|
||||
Format(id, sizeof(id), "%d|%d|%d", userid, instaMode, i);
|
||||
spMenu.AddItem(id, SPECIAL_NAMES[i-1]);
|
||||
}
|
||||
spMenu.ExitButton = true;
|
||||
spMenu.Display(client, 0);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int Insta_SpecialHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[3][8];
|
||||
ExplodeString(info, "|", str, 3, 8, false);
|
||||
int target = GetClientOfUserId(StringToInt(str[0]));
|
||||
bool inFace = StrEqual(str[1], "1");
|
||||
int special = StringToInt(str[2]);
|
||||
if(inFace) {
|
||||
SpawnSpecialInFace(target, special);
|
||||
ShowActivity(client, "spawned Insta-%s™ near %N", SPECIAL_NAMES[special-1], target);
|
||||
} else {
|
||||
SpawnSpecialNear(target, special);
|
||||
ShowActivity(client, "spawned Insta-%s™ near %N", SPECIAL_NAMES[special-1], target);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
|
||||
public int ChooseMarkedTroll(Menu menu, MenuAction action, int activator, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
int target = GetClientOfUserId(StringToInt(info));
|
||||
ToggleMarkPlayer(activator, target);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int ChoosePlayerHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
int userid = StringToInt(info);
|
||||
|
||||
Menu trollMenu = new Menu(ChooseModeMenuHandler);
|
||||
trollMenu.SetTitle("Choose a troll mode");
|
||||
//TODO: Update
|
||||
static char id[8];
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
for(int i = 0; i <= MAX_TROLLS; i++) {
|
||||
GetTrollID(i, name);
|
||||
// int trollIndex = GetTrollByKeyIndex(i, troll);
|
||||
// Pass key index
|
||||
Format(id, sizeof(id), "%d|%d", userid, i);
|
||||
trollMenu.AddItem(id, name);
|
||||
}
|
||||
trollMenu.ExitButton = true;
|
||||
trollMenu.Display(param1, 0);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int ChooseModeMenuHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[2][8];
|
||||
ExplodeString(info, "|", str, 2, 8, false);
|
||||
int userid = StringToInt(str[0]);
|
||||
int client = GetClientOfUserId(userid);
|
||||
int keyIndex = StringToInt(str[1]);
|
||||
static Troll troll;
|
||||
static char trollID[MAX_TROLL_NAME_LENGTH];
|
||||
GetTrollByKeyIndex(keyIndex, troll);
|
||||
troll.GetID(trollID, MAX_TROLL_NAME_LENGTH);
|
||||
//If troll has multiple flags, prompt:
|
||||
if(troll.HasMode(TrollMod_Instant) && troll.HasMode
|
||||
(TrollMod_Constant)) {
|
||||
Menu modiferMenu = new Menu(ChooseTrollModiferHandler);
|
||||
modiferMenu.SetTitle("Choose Troll Modifer Option");
|
||||
static char singleUse[16], multiUse[16], bothUse[16];
|
||||
Format(singleUse, sizeof(singleUse), "%d|%d|1", userid, keyIndex);
|
||||
Format(multiUse, sizeof(multiUse), "%d|%d|2", userid, keyIndex);
|
||||
Format(bothUse, sizeof(bothUse), "%d|%d|3", userid, keyIndex);
|
||||
modiferMenu.AddItem(singleUse, "Activate once");
|
||||
modiferMenu.AddItem(multiUse, "Activate Periodically");
|
||||
modiferMenu.AddItem(bothUse, "Activate Periodically & Instantly");
|
||||
modiferMenu.ExitButton = true;
|
||||
modiferMenu.Display(param1, 0);
|
||||
} else {
|
||||
ApplyTroll(client, trollID, param1, troll.GetDefaultMod());
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int ChooseTrollModiferHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[3][8];
|
||||
ExplodeString(info, "|", str, 3, 8, false);
|
||||
int client = GetClientOfUserId(StringToInt(str[0]));
|
||||
int keyIndex = StringToInt(str[1]);
|
||||
static Troll troll;
|
||||
static char trollID[MAX_TROLL_NAME_LENGTH];
|
||||
GetTrollByKeyIndex(keyIndex, troll);
|
||||
troll.GetID(trollID, MAX_TROLL_NAME_LENGTH);
|
||||
int modifier = StringToInt(str[2]);
|
||||
if(modifier == 2 || modifier == 3)
|
||||
ApplyTroll(client, trollID, param1, TrollMod_Repeat);
|
||||
else
|
||||
ApplyTroll(client, trollID, param1, TrollMod_InstantFire);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public void StopItemGive(int client) {
|
||||
g_bPendingItemGive[client] = false;
|
||||
}
|
109
scripting/include/feedthetrolls/misc.inc
Normal file
109
scripting/include/feedthetrolls/misc.inc
Normal file
|
@ -0,0 +1,109 @@
|
|||
#define AUTOPUNISH_FLOW_MIN_DISTANCE 5000.0
|
||||
#define AUTOPUNISH_MODE_COUNT 3
|
||||
|
||||
void ActivateAutoPunish(int client) {
|
||||
if(hAutoPunish.IntValue & 2 == 2)
|
||||
ApplyTroll(lastButtonUser, "SpecialMagnet", 0, TrollMod_Constant);
|
||||
if(hAutoPunish.IntValue & 1 == 1)
|
||||
ApplyTroll(lastButtonUser, "TankMagnet", 0, TrollMod_Constant);
|
||||
if(hAutoPunish.IntValue & 8 == 8)
|
||||
ApplyTroll(lastButtonUser, "VomitPlayer", 0, TrollMod_Instant);
|
||||
else if(hAutoPunish.IntValue & 4 == 4)
|
||||
ApplyTroll(lastButtonUser, "Swarm", 0, TrollMod_Instant);
|
||||
if(hAutoPunishExpire.IntValue > 0) {
|
||||
CreateTimer(60.0 * hAutoPunishExpire.FloatValue, Timer_ResetAutoPunish, GetClientOfUserId(lastButtonUser));
|
||||
}
|
||||
}
|
||||
|
||||
void SetWitchTarget(int witch, int target) {
|
||||
Behavior behavior = Behavior(witch, WITCH_QUERY);
|
||||
BehaviorAction action = behavior.CurrentAction.Last;
|
||||
|
||||
BehaviorAction newaction = view_as<BehaviorAction>(AllocateMemory(18556));
|
||||
SDKCall(g_hWitchAttack, newaction, target);
|
||||
|
||||
IActionResult result; result.Init(CHANGE_TO, newaction);
|
||||
result.ToAction(action);
|
||||
}
|
||||
|
||||
bool ToggleMarkPlayer(int client, int target) {
|
||||
if(g_PendingBanTroll[target]) {
|
||||
g_PendingBanTroll[target] = false;
|
||||
ShowActivity(client, "unmarked %N as troll", target);
|
||||
return true;
|
||||
}else{
|
||||
AdminId admin_client = GetUserAdmin(client);
|
||||
AdminId admin_target = GetUserAdmin(target);
|
||||
if(admin_client != INVALID_ADMIN_ID && admin_target == INVALID_ADMIN_ID ) {
|
||||
Call_StartForward(g_PlayerMarkedForward);
|
||||
Call_PushCell(client);
|
||||
Call_PushCell(target);
|
||||
Call_Finish();
|
||||
g_PendingBanTroll[target] = true;
|
||||
ShowActivity(client, "marked %N as troll", target);
|
||||
return true;
|
||||
}else{
|
||||
ReplyToCommand(client, "cannot mark %N as troll as they are an admin.", target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stock int FindIdlePlayerBot(int client) {
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsFakeClient(i)) {
|
||||
int user = GetEntProp(i, Prop_Send, "m_humanSpectatorUserID");
|
||||
int bot = GetClientOfUserId(user);
|
||||
return bot > 0 ? bot : client;
|
||||
}
|
||||
}
|
||||
return client;
|
||||
}
|
||||
stock bool IsPlayerIncapped(int client) {
|
||||
return GetEntProp(client, Prop_Send, "m_isIncapacitated") == 1;
|
||||
}
|
||||
|
||||
|
||||
#define MAX_PHRASES_PER_WORD 8
|
||||
#define MAX_PHRASE_LENGTH 191
|
||||
StringMap REPLACEMENT_PHRASES;
|
||||
//TODO: Load from cfg
|
||||
/* Example:
|
||||
exWord
|
||||
{
|
||||
"1" "phrase1"
|
||||
"2" "phrase2"
|
||||
}
|
||||
*/
|
||||
void LoadPhrases() {
|
||||
KeyValues kv = new KeyValues("Phrases");
|
||||
ArrayList phrases = new ArrayList(ByteCountToCells(MAX_PHRASE_LENGTH));
|
||||
|
||||
char sPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, sPath, sizeof(sPath), "data/ftt_phrases.cfg");
|
||||
|
||||
if(!FileExists(sPath) || !kv.ImportFromFile(sPath)) {
|
||||
delete kv;
|
||||
PrintToServer("[FTT] Could not load phrase list from data/ftt_phrases.cfg");
|
||||
return;
|
||||
}
|
||||
static char word[32];
|
||||
char phrase[MAX_PHRASE_LENGTH];
|
||||
// Go through all the words:
|
||||
kv.GotoFirstSubKey();
|
||||
int i = 0;
|
||||
static char buffer[4];
|
||||
do {
|
||||
kv.GetSectionName(word, sizeof(word));
|
||||
phrases.Clear();
|
||||
for(;;) {
|
||||
IntToString(++i, buffer, sizeof(buffer));
|
||||
kv.GetString(buffer, phrase, MAX_PHRASE_LENGTH, "_null");
|
||||
if(strcmp(phrase, "_null") == 0) break;
|
||||
phrases.PushString(phrase);
|
||||
}
|
||||
i = 0;
|
||||
REPLACEMENT_PHRASES.SetValue(word, phrases.Clone(), true);
|
||||
} while (kv.GotoNextKey(false));
|
||||
delete kv;
|
||||
}
|
82
scripting/include/feedthetrolls/specials.inc
Normal file
82
scripting/include/feedthetrolls/specials.inc
Normal file
|
@ -0,0 +1,82 @@
|
|||
char SPECIAL_NAMES[][] = {
|
||||
"Smoker", "Boomer", "Hunter", "Spitter", "Jockey", "Charger", "Witch"
|
||||
};
|
||||
|
||||
stock int GetSpecialType(const char[] input) {
|
||||
for(int i = 0; i < sizeof(SPECIAL_NAMES); i++) {
|
||||
if(strcmp(SPECIAL_NAMES[i], input, false) == 0) return i + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
stock bool FindSuitablePosition(int target, const float pos[3], float outputPos[3], float minDistance = 19000.0, int tries = 100) {
|
||||
outputPos = pos;
|
||||
for(int i = tries; i > 0; i--) {
|
||||
// int nav = L4D_GetNearestNavArea(pos);
|
||||
// L4D_FindRandomSpot(nav, testPos);
|
||||
// float dist = GetVectorDistance(testPos, pos, true);
|
||||
outputPos[0] += GetRandomFloat(-30.0, 30.0);
|
||||
outputPos[1] += GetRandomFloat(-30.0, 30.0);
|
||||
float dist = GetVectorDistance(outputPos, pos, true);
|
||||
if(dist >= minDistance && L4D2Direct_GetTerrorNavArea(outputPos) != Address_Null) { //5m^2
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float GetIdealMinDistance(int specialType) {
|
||||
switch(specialType) {
|
||||
// /*Boomer*/ case 2: return 1200.0;
|
||||
/*Charger*/ case 6: return 19000.0;
|
||||
/*Smoker*/ case 1: return 20000.0;
|
||||
|
||||
default:
|
||||
return 12000.0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SpawnSpecialInFace(int target, int specialType) {
|
||||
static float pos[3], ang[3];
|
||||
static float testPos[3];
|
||||
testPos = pos;
|
||||
GetClientAbsOrigin(target, pos);
|
||||
GetClientEyeAngles(target, ang);
|
||||
if(specialType != 5 && specialType != 2) { //If charger/hunter, find a suitable area that is at least 5 m away
|
||||
float minDistance = GetIdealMinDistance(specialType);
|
||||
GetHorizontalPositionFromOrigin(pos, ang, minDistance, testPos);
|
||||
FindSuitablePosition(target, pos, testPos, minDistance, 100);
|
||||
pos = testPos;
|
||||
} else { // Else spawn a little bit off, and above (above for jockeys)
|
||||
pos[2] += 10.0;
|
||||
pos[0] += 5.0;
|
||||
}
|
||||
pos[2] += 1.0;
|
||||
NegateVector(ang);
|
||||
int special = (specialType == 7) ? L4D2_SpawnWitch(pos, ang) : L4D2_SpawnSpecial(specialType, pos, ang);
|
||||
if(special == -1) return false;
|
||||
|
||||
if(specialType == 7)
|
||||
SetWitchTarget(special, target);
|
||||
else
|
||||
g_iAttackerTarget[special] = GetClientUserId(target);
|
||||
|
||||
if(specialType == 2) { //Kill boomer
|
||||
ForcePlayerSuicide(special);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpawnSpecialNear(int target, int specialType) {
|
||||
static float pos[3];
|
||||
if(L4D_GetRandomPZSpawnPosition(target, specialType, 10, pos)) {
|
||||
int special = (specialType == 7) ? L4D2_SpawnWitch(pos, ZERO_VECTOR) : L4D2_SpawnSpecial(specialType, pos, ZERO_VECTOR);
|
||||
if(special == -1) return false;
|
||||
if(specialType == 7)
|
||||
SetWitchTarget(special, target);
|
||||
else
|
||||
g_iAttackerTarget[special] = GetClientUserId(target);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
93
scripting/include/feedthetrolls/timers.inc
Normal file
93
scripting/include/feedthetrolls/timers.inc
Normal file
|
@ -0,0 +1,93 @@
|
|||
public Action Timer_ThrowTimer(Handle timer) {
|
||||
int count = 0;
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && IsTrollActive(i, "ThrowItAll")) {
|
||||
ThrowAllItems(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count > 0 ? Plugin_Continue : Plugin_Stop;
|
||||
}
|
||||
|
||||
public Action Timer_Main(Handle timer) {
|
||||
static int loop;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i)) {
|
||||
if(IsTrollActive(i, "SlowDrain")) {
|
||||
if(loop % 4 == 0) {
|
||||
int hp = GetClientHealth(i);
|
||||
if(hp > 50) {
|
||||
SetEntProp(i, Prop_Send, "m_iHealth", hp - 1);
|
||||
}
|
||||
}
|
||||
}else if(IsTrollActive(i, "TempHealthQuickDrain")) {
|
||||
if(loop % 2 == 0) {
|
||||
float bufferTime = GetEntPropFloat(i, Prop_Send, "m_healthBufferTime");
|
||||
float buffer = GetEntPropFloat(i, Prop_Send, "m_healthBuffer");
|
||||
float tempHealth = GetTempHealth(i);
|
||||
if(tempHealth > 0.0) {
|
||||
PrintToConsole(i, "%f | %f %f", tempHealth, buffer, bufferTime);
|
||||
//SetEntPropFloat(i, Prop_Send, "m_healthBuffer", buffer - 10.0);
|
||||
SetEntPropFloat(i, Prop_Send, "m_healthBufferTime", bufferTime - 7.0);
|
||||
}
|
||||
}
|
||||
}else if(IsTrollActive(i, "Swarm")) {
|
||||
L4D2_RunScript("RushVictim(GetPlayerFromUserID(%d), %d)", GetClientUserId(i), 15000);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(++loop >= 60) {
|
||||
loop = 0;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Timer_GivePistol(Handle timer, int client) {
|
||||
int flags = GetCommandFlags("give");
|
||||
SetCommandFlags("give", flags & ~FCVAR_CHEAT);
|
||||
FakeClientCommand(client, "give pistol");
|
||||
SetCommandFlags("give", flags|FCVAR_CHEAT);
|
||||
}
|
||||
|
||||
public Action Timer_ThrowWeapon(Handle timer, Handle pack) {
|
||||
ResetPack(pack);
|
||||
float dest[3];
|
||||
dest[0] = ReadPackFloat(pack);
|
||||
dest[1] = ReadPackFloat(pack);
|
||||
dest[2] = ReadPackFloat(pack);
|
||||
int slot = ReadPackCell(pack);
|
||||
int victim = ReadPackCell(pack);
|
||||
|
||||
int wpnRef = GetPlayerWeaponSlot(victim, slot);
|
||||
if(wpnRef != -1) {
|
||||
int wpn = EntRefToEntIndex(wpnRef);
|
||||
if(wpn != INVALID_ENT_REFERENCE) {
|
||||
if(slot == 1) {
|
||||
static char name[16];
|
||||
GetEdictClassname(wpn, name, sizeof(name));
|
||||
if(!StrEqual(name, "weapon_pistol", false)) {
|
||||
SDKHooks_DropWeapon(victim, wpn, dest);
|
||||
CreateTimer(0.2, Timer_GivePistol, victim);
|
||||
}
|
||||
}else
|
||||
SDKHooks_DropWeapon(victim, wpn, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_ResetAutoPunish(Handle timer, int user) {
|
||||
int client = GetClientOfUserId(user);
|
||||
if(client) {
|
||||
if(hAutoPunish.IntValue & 2 == 2)
|
||||
DisableTroll(client, "SpecialMagnet");
|
||||
if(hAutoPunish.IntValue & 1 == 1)
|
||||
DisableTroll(client, "TankMagnet");
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_NextWitchSet(Handle timer, DataPack pack) {
|
||||
pack.Reset();
|
||||
int client = GetClientOfUserId(pack.ReadCell());
|
||||
int witch = pack.ReadCell();
|
||||
SetWitchTarget(witch, client);
|
||||
}
|
|
@ -1,9 +1,3 @@
|
|||
#define AUTOPUNISH_FLOW_MIN_DISTANCE 5000.0
|
||||
#define AUTOPUNISH_MODE_COUNT 3
|
||||
// #define TROLL_MODE_COUNT 26
|
||||
//
|
||||
|
||||
|
||||
enum L4D2Infected
|
||||
{
|
||||
L4D2Infected_None = 0,
|
||||
|
@ -37,204 +31,5 @@ int gChargerVictim = -1; //For charge player feature
|
|||
float ZERO_VECTOR[3] = {0.0, 0.0, 0.0};
|
||||
|
||||
#include <feedthetrolls/base>
|
||||
|
||||
void ResetClient(int victim, bool wipe = true) {
|
||||
if(wipe) ActiveTrolls[victim] = 0;
|
||||
SetEntityGravity(victim, 1.0);
|
||||
SetEntPropFloat(victim, Prop_Send, "m_flLaggedMovementValue", 1.0);
|
||||
SDKUnhook(victim, SDKHook_WeaponCanUse, Event_ItemPickup);
|
||||
int wpn = GetClientWeaponEntIndex(victim, 0);
|
||||
if(wpn > -1)
|
||||
SDKUnhook(wpn, SDKHook_Reload, Event_WeaponReload);
|
||||
}
|
||||
|
||||
void ActivateAutoPunish(int client) {
|
||||
if(hAutoPunish.IntValue & 2 == 2)
|
||||
ApplyTroll(lastButtonUser, "SpecialMagnet", 0, TrollMod_None);
|
||||
if(hAutoPunish.IntValue & 1 == 1)
|
||||
ApplyTroll(lastButtonUser, "TankMagnet", 0, TrollMod_None);
|
||||
if(hAutoPunish.IntValue & 8 == 8)
|
||||
ApplyTroll(lastButtonUser, "VomitPlayer", 0, TrollMod_None);
|
||||
else if(hAutoPunish.IntValue & 4 == 4)
|
||||
ApplyTroll(lastButtonUser, "Swarm", 0, TrollMod_None);
|
||||
if(hAutoPunishExpire.IntValue > 0) {
|
||||
CreateTimer(60.0 * hAutoPunishExpire.FloatValue, Timer_ResetAutoPunish, GetClientOfUserId(lastButtonUser));
|
||||
}
|
||||
}
|
||||
|
||||
void SetWitchTarget(int witch, int target) {
|
||||
Behavior behavior = Behavior(witch, WITCH_QUERY);
|
||||
BehaviorAction action = behavior.CurrentAction.Last;
|
||||
|
||||
BehaviorAction newaction = view_as<BehaviorAction>(AllocateMemory(18556));
|
||||
SDKCall(g_hWitchAttack, newaction, target);
|
||||
|
||||
IActionResult result; result.Init(CHANGE_TO, newaction);
|
||||
result.ToAction(action);
|
||||
}
|
||||
|
||||
bool ToggleMarkPlayer(int client, int target) {
|
||||
if(g_PendingBanTroll[target]) {
|
||||
g_PendingBanTroll[target] = false;
|
||||
ShowActivity(client, "unmarked %N as troll", target);
|
||||
return true;
|
||||
}else{
|
||||
AdminId admin_client = GetUserAdmin(client);
|
||||
AdminId admin_target = GetUserAdmin(target);
|
||||
if(admin_client != INVALID_ADMIN_ID && admin_target == INVALID_ADMIN_ID ) {
|
||||
Call_StartForward(g_PlayerMarkedForward);
|
||||
Call_PushCell(client);
|
||||
Call_PushCell(target);
|
||||
Call_Finish();
|
||||
g_PendingBanTroll[target] = true;
|
||||
ShowActivity(client, "marked %N as troll", target);
|
||||
return true;
|
||||
}else{
|
||||
ReplyToCommand(client, "cannot mark %N as troll as they are an admin.", target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stock int FindIdlePlayerBot(int client) {
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsFakeClient(i)) {
|
||||
int user = GetEntProp(i, Prop_Send, "m_humanSpectatorUserID");
|
||||
int bot = GetClientOfUserId(user);
|
||||
return bot > 0 ? bot : client;
|
||||
}
|
||||
}
|
||||
return client;
|
||||
}
|
||||
stock bool IsPlayerIncapped(int client) {
|
||||
return GetEntProp(client, Prop_Send, "m_isIncapacitated") == 1;
|
||||
}
|
||||
char SPECIAL_NAMES[][] = {
|
||||
"Smoker", "Boomer", "Hunter", "Spitter", "Jockey", "Charger", "Witch"
|
||||
};
|
||||
stock int GetSpecialType(const char[] input) {
|
||||
for(int i = 0; i < sizeof(SPECIAL_NAMES); i++) {
|
||||
if(strcmp(SPECIAL_NAMES[i], input, false) == 0) return i + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
stock bool FindSuitablePosition(int target, const float pos[3], float outputPos[3], float minDistance = 19000.0, int tries = 100) {
|
||||
outputPos = pos;
|
||||
for(int i = tries; i > 0; i--) {
|
||||
// int nav = L4D_GetNearestNavArea(pos);
|
||||
// L4D_FindRandomSpot(nav, testPos);
|
||||
// float dist = GetVectorDistance(testPos, pos, true);
|
||||
outputPos[0] += GetRandomFloat(-30.0, 30.0);
|
||||
outputPos[1] += GetRandomFloat(-30.0, 30.0);
|
||||
float dist = GetVectorDistance(outputPos, pos, true);
|
||||
if(dist >= minDistance && L4D2Direct_GetTerrorNavArea(outputPos) != Address_Null) { //5m^2
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MAX_PHRASES_PER_WORD 8
|
||||
#define MAX_PHRASE_LENGTH 191
|
||||
StringMap REPLACEMENT_PHRASES;
|
||||
//TODO: Load from cfg
|
||||
/* Example:
|
||||
exWord
|
||||
{
|
||||
"1" "phrase1"
|
||||
"2" "phrase2"
|
||||
}
|
||||
*/
|
||||
void LoadPhrases() {
|
||||
KeyValues kv = new KeyValues("Phrases");
|
||||
ArrayList phrases = new ArrayList(ByteCountToCells(MAX_PHRASE_LENGTH));
|
||||
|
||||
char sPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, sPath, sizeof(sPath), "data/ftt_phrases.cfg");
|
||||
|
||||
if(!FileExists(sPath) || !kv.ImportFromFile(sPath)) {
|
||||
delete kv;
|
||||
PrintToServer("[FTT] Could not load phrase list from data/ftt_phrases.cfg");
|
||||
return;
|
||||
}
|
||||
static char word[32];
|
||||
char phrase[MAX_PHRASE_LENGTH];
|
||||
// Go through all the words:
|
||||
kv.GotoFirstSubKey();
|
||||
int i = 0;
|
||||
static char buffer[4];
|
||||
do {
|
||||
kv.GetSectionName(word, sizeof(word));
|
||||
phrases.Clear();
|
||||
for(;;) {
|
||||
IntToString(++i, buffer, sizeof(buffer));
|
||||
kv.GetString(buffer, phrase, MAX_PHRASE_LENGTH, "_null");
|
||||
if(strcmp(phrase, "_null") == 0) break;
|
||||
phrases.PushString(phrase);
|
||||
}
|
||||
i = 0;
|
||||
REPLACEMENT_PHRASES.SetValue(word, phrases.Clone(), true);
|
||||
} while (kv.GotoNextKey(false));
|
||||
delete kv;
|
||||
}
|
||||
|
||||
float GetIdealMinDistance(int specialType) {
|
||||
switch(specialType) {
|
||||
// /*Boomer*/ case 2: return 1200.0;
|
||||
/*Charger*/ case 6: return 19000.0;
|
||||
/*Smoker*/ case 1: return 20000.0;
|
||||
|
||||
default:
|
||||
return 12000.0;
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_Kill(Handle h, int client) {
|
||||
AcceptEntityInput(client, "Kill");
|
||||
}
|
||||
//TODO: Add Insta-Witch
|
||||
bool SpawnSpecialInFace(int target, int specialType) {
|
||||
static float pos[3], ang[3];
|
||||
static float testPos[3];
|
||||
testPos = pos;
|
||||
GetClientAbsOrigin(target, pos);
|
||||
GetClientEyeAngles(target, ang);
|
||||
if(specialType != 5 && specialType != 2) { //If charger/hunter, find a suitable area that is at least 5 m away
|
||||
float minDistance = GetIdealMinDistance(specialType);
|
||||
GetHorizontalPositionFromOrigin(pos, ang, minDistance, testPos);
|
||||
FindSuitablePosition(target, pos, testPos, minDistance, 100);
|
||||
pos = testPos;
|
||||
} else { // Else spawn a little bit off, and above (above for jockeys)
|
||||
pos[2] += 10.0;
|
||||
pos[0] += 5.0;
|
||||
}
|
||||
pos[2] += 1.0;
|
||||
NegateVector(ang);
|
||||
int special = (specialType == 7) ? L4D2_SpawnWitch(pos, ang) : L4D2_SpawnSpecial(specialType, pos, ang);
|
||||
if(special == -1) return false;
|
||||
|
||||
if(specialType == 7)
|
||||
SetWitchTarget(special, target);
|
||||
else
|
||||
g_iAttackerTarget[special] = GetClientUserId(target);
|
||||
|
||||
if(specialType == 2) { //Kill boomer
|
||||
ForcePlayerSuicide(special);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpawnSpecialNear(int target, int specialType) {
|
||||
static float pos[3];
|
||||
if(L4D_GetRandomPZSpawnPosition(target, specialType, 10, pos)) {
|
||||
int special = (specialType == 7) ? L4D2_SpawnWitch(pos, ZERO_VECTOR) : L4D2_SpawnSpecial(specialType, pos, ZERO_VECTOR);
|
||||
if(special == -1) return false;
|
||||
if(specialType == 7)
|
||||
SetWitchTarget(special, target);
|
||||
else
|
||||
g_iAttackerTarget[special] = GetClientUserId(target);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#include <feedthetrolls/specials>
|
||||
#include <feedthetrolls/misc>
|
|
@ -102,385 +102,6 @@ public void OnPluginStart() {
|
|||
// EVENTS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void OnPluginEnd() {
|
||||
UnhookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
}
|
||||
public void OnMapEnd() {
|
||||
UnhookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
}
|
||||
public void OnMapStart() {
|
||||
AddFileToDownloadsTable("sound/custom/meow1.mp3");
|
||||
PrecacheSound("custom/meow1.mp3");
|
||||
|
||||
lastButtonUser = -1;
|
||||
HookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
CreateTimer(MAIN_TIMER_INTERVAL_S, Timer_Main, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
PrecacheSound("player/footsteps/clown/concrete1.wav");
|
||||
//CreateTimer(30.0, Timer_AutoPunishCheck, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
public void OnClientPutInServer(int client) {
|
||||
g_PendingBanTroll[client] = false;
|
||||
SDKHook(client, SDKHook_OnTakeDamage, Event_TakeDamage);
|
||||
}
|
||||
public void OnClientAuthorized(int client, const char[] auth) {
|
||||
if(!IsFakeClient(client)) {
|
||||
strcopy(steamids[client], 64, auth);
|
||||
}
|
||||
}
|
||||
public void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(g_PendingBanTroll[client]) {
|
||||
g_PendingBanTroll[client] = false;
|
||||
if(!IsFakeClient(client) && GetUserAdmin(client) == INVALID_ADMIN_ID) {
|
||||
BanIdentity(steamids[client], 0, BANFLAG_AUTHID, "TrollMarked", "ftt", 0);
|
||||
}
|
||||
}
|
||||
steamids[client][0] = '\0';
|
||||
ActiveTrolls[client] = 0;
|
||||
g_iAttackerTarget[client] = 0;
|
||||
}
|
||||
public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
g_iAttackerTarget[client] = 0;
|
||||
}
|
||||
public Action Event_WeaponReload(int weapon) {
|
||||
int client = GetEntPropEnt(weapon, Prop_Send, "m_hOwner");
|
||||
if(IsTrollActive(client, "GunJam")) {
|
||||
float dec = GetRandomFloat(0.0, 1.0);
|
||||
if(FloatCompare(dec, 0.50) == -1) { //10% chance gun jams
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public Action Event_ButtonPress(const char[] output, int entity, int client, float delay) {
|
||||
if(client > 0 && client <= MaxClients) {
|
||||
lastButtonUser = client;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public void Event_PanicEventCreate(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client) {
|
||||
lastButtonUser = client;
|
||||
}
|
||||
}
|
||||
public void Event_CarAlarm(Event event, const char[] name, bool dontBroadcast) {
|
||||
int user = event.GetInt("userid");
|
||||
int client = GetClientOfUserId(user);
|
||||
if(client) {
|
||||
PrintToChatAll("%N has alerted the horde!", client);
|
||||
L4D2_RunScript("RushVictim(GetPlayerFromUserID(%d), %d)", user, 15000);
|
||||
}
|
||||
//Ignore car alarms for autopunish
|
||||
lastButtonUser = -1;
|
||||
}
|
||||
public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
||||
// =========================
|
||||
// OVERRIDE VICTIM
|
||||
// =========================
|
||||
if(hMagnetChance.FloatValue < GetRandomFloat()) return Plugin_Continue;
|
||||
L4D2Infected class = view_as<L4D2Infected>(GetEntProp(attacker, Prop_Send, "m_zombieClass"));
|
||||
int existingTarget = GetClientOfUserId(g_iAttackerTarget[attacker]);
|
||||
if(existingTarget > 0 && IsPlayerAlive(existingTarget) && (hMagnetTargetMode.IntValue & 1 != 1 || !IsPlayerIncapped(existingTarget))) {
|
||||
if(class == L4D2Infected_Tank && (hMagnetTargetMode.IntValue % 2 != 2 || !IsPlayerIncapped(existingTarget))) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}else if(hMagnetTargetMode.IntValue & 1 != 1 || !IsPlayerIncapped(existingTarget)) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
}
|
||||
|
||||
float closestDistance, survPos[3], spPos[3];
|
||||
GetClientAbsOrigin(attacker, spPos);
|
||||
int closestClient = -1;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
//Ignore incapped players if turned on:
|
||||
if(IsPlayerIncapped(i)) {
|
||||
if((class == L4D2Infected_Tank && hMagnetTargetMode.IntValue & 2 == 2) || hMagnetTargetMode.IntValue & 1 == 1 ) continue;
|
||||
}
|
||||
|
||||
if(class == L4D2Infected_Tank && IsTrollActive(i, "TankMagnet") || (class != L4D2Infected_Tank && IsTrollActive(i, "SpecialMagnet"))) {
|
||||
GetClientAbsOrigin(i, survPos);
|
||||
float dist = GetVectorDistance(survPos, spPos, true);
|
||||
if(closestClient == -1 || dist < closestDistance) {
|
||||
closestDistance = dist;
|
||||
closestClient = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(closestClient > 0) {
|
||||
g_iAttackerTarget[attacker] = GetClientUserId(closestClient);
|
||||
curTarget = closestClient;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public Action L4D2_OnEntityShoved(int client, int entity, int weapon, float vecDir[3], bool bIsHighPounce) {
|
||||
if(client > 0 && client <= MaxClients && IsTrollActive(client, "NoShove") && hShoveFailChance.FloatValue > GetRandomFloat()) {
|
||||
return Plugin_Handled;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) {
|
||||
if(sArgs[0] == '@') return Plugin_Continue;
|
||||
if(IsTrollActive(client, "Honk")) {
|
||||
static char strings[32][7];
|
||||
int words = ExplodeString(sArgs, " ", strings, sizeof(strings), 5);
|
||||
for(int i = 0; i < words; i++) {
|
||||
if(GetRandomFloat() <= 0.8) strings[i] = "honk";
|
||||
else strings[i] = "squeak";
|
||||
}
|
||||
int length = 7 * words;
|
||||
char[] message = new char[length];
|
||||
ImplodeStrings(strings, 32, " ", message, length);
|
||||
CPrintToChatAll("{blue}%N {default}: %s", client, message);
|
||||
PrintToServer("%N: %s", client, sArgs);
|
||||
return Plugin_Handled;
|
||||
}else if(IsTrollActive(client, "iCantSpellNoMore")) {
|
||||
int type = GetRandomInt(1, trollKV.Size + 8);
|
||||
char letterSrc, replaceChar;
|
||||
switch(type) {
|
||||
case 1: {
|
||||
letterSrc = 'e';
|
||||
replaceChar = 'b';
|
||||
}
|
||||
case 2: {
|
||||
letterSrc = 't';
|
||||
replaceChar = 'e';
|
||||
}
|
||||
case 3: {
|
||||
letterSrc = 'i';
|
||||
replaceChar = 'e';
|
||||
}
|
||||
case 4: {
|
||||
letterSrc = 'a';
|
||||
replaceChar = 's';
|
||||
}
|
||||
case 5: {
|
||||
letterSrc = 'u';
|
||||
replaceChar = 'i';
|
||||
}
|
||||
case 6: {
|
||||
letterSrc = '.';
|
||||
replaceChar = '/';
|
||||
}
|
||||
case 7: {
|
||||
letterSrc = 'm';
|
||||
replaceChar = 'n';
|
||||
}
|
||||
case 8: {
|
||||
letterSrc = 'n';
|
||||
replaceChar = 'm';
|
||||
}
|
||||
case 9: {
|
||||
letterSrc = 'l';
|
||||
replaceChar = 'b';
|
||||
}
|
||||
case 10: {
|
||||
letterSrc = 'l';
|
||||
replaceChar = 'b';
|
||||
}
|
||||
case 11: {
|
||||
letterSrc = 'h';
|
||||
replaceChar = 'j';
|
||||
}
|
||||
case 12: {
|
||||
letterSrc = 'o';
|
||||
replaceChar = 'i';
|
||||
}
|
||||
case 13: {
|
||||
letterSrc = 'e';
|
||||
replaceChar = 'r';
|
||||
}
|
||||
|
||||
default:
|
||||
return Plugin_Continue;
|
||||
}
|
||||
int strLength = strlen(sArgs);
|
||||
char[] newMessage = new char[strLength + 20];
|
||||
int n = 0;
|
||||
while (sArgs[n] != '\0') {
|
||||
if(sArgs[n] == letterSrc) {
|
||||
newMessage[n] = replaceChar;
|
||||
}else{
|
||||
newMessage[n] = sArgs[n];
|
||||
}
|
||||
n++;
|
||||
}
|
||||
PrintToServer("%N: %s", client, sArgs);
|
||||
CPrintToChatAll("{blue}%N {default}: %s", client, newMessage);
|
||||
return Plugin_Handled;
|
||||
}else if(IsTrollActive(client, "NoProfanity")) {
|
||||
//TODO: Check all replacement words, if none were replaced then do full word
|
||||
//TODO: Lowercase .getstring
|
||||
static char strings[32][MAX_PHRASE_LENGTH];
|
||||
ArrayList phrases;
|
||||
bool foundWord = false;
|
||||
int words = ExplodeString(sArgs, " ", strings, 32, MAX_PHRASE_LENGTH);
|
||||
for(int i = 0; i < words; i++) {
|
||||
if(REPLACEMENT_PHRASES.GetValue(strings[i], phrases) && phrases.Length > 0) {
|
||||
foundWord = true;
|
||||
int c = phrases.GetString(GetRandomInt(0, phrases.Length - 1), strings[i], MAX_PHRASE_LENGTH);
|
||||
PrintToServer("replacement: %s (%d)", strings[i], c);
|
||||
}
|
||||
}
|
||||
int length = MAX_PHRASE_LENGTH * words;
|
||||
char[] message = new char[length];
|
||||
if(foundWord) {
|
||||
ImplodeStrings(strings, 32, " ", message, length);
|
||||
} else {
|
||||
REPLACEMENT_PHRASES.GetValue("_Full Message Phrases", phrases);
|
||||
phrases.GetString(GetRandomInt(0, phrases.Length - 1), message, MAX_PHRASE_LENGTH);
|
||||
}
|
||||
CPrintToChatAll("{blue}%N {default}: %s", client, message);
|
||||
PrintToServer("%N: %s", client, sArgs);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_ItemPickup(int client, int weapon) {
|
||||
if(IsTrollActive(client, "NoPickup")) {
|
||||
return Plugin_Stop;
|
||||
}else{
|
||||
static char wpnName[64];
|
||||
GetEdictClassname(weapon, wpnName, sizeof(wpnName));
|
||||
if(StrContains(wpnName, "rifle") > -1
|
||||
|| StrContains(wpnName, "smg") > -1
|
||||
|| StrContains(wpnName, "weapon_grenade_launcher") > -1
|
||||
|| StrContains(wpnName, "sniper") > -1
|
||||
|| StrContains(wpnName, "shotgun") > -1
|
||||
) {
|
||||
//If 4: Only UZI, if 5: Can't switch.
|
||||
if(IsTrollActive(client, "UziRules")) {
|
||||
static char currentWpn[32];
|
||||
GetClientWeaponName(client, 0, currentWpn, sizeof(currentWpn));
|
||||
if(StrEqual(wpnName, "weapon_smg", true)) {
|
||||
return Plugin_Continue;
|
||||
} else if(StrEqual(currentWpn, "weapon_smg", true)) {
|
||||
return Plugin_Stop;
|
||||
}else{
|
||||
int flags = GetCommandFlags("give");
|
||||
SetCommandFlags("give", flags & ~FCVAR_CHEAT);
|
||||
FakeClientCommand(client, "give smg");
|
||||
SetCommandFlags("give", flags);
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}else if(IsTrollActive(client, "PrimaryDisable")) {
|
||||
return Plugin_Stop;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}else{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) {
|
||||
if(g_bPendingItemGive[client] && !(buttons & IN_ATTACK2)) {
|
||||
int target = GetClientAimTarget(client, true);
|
||||
if(target > -1) {
|
||||
buttons |= IN_ATTACK2;
|
||||
RequestFrame(StopItemGive, client);
|
||||
return Plugin_Changed;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_TakeDamage(int victim, int& attacker, int& inflictor, float& damage, int& damagetype) {
|
||||
//Stop FF from marked:
|
||||
if(attacker > 0 && attacker <= MaxClients && IsClientInGame(attacker) && IsPlayerAlive(attacker)) {
|
||||
if(g_PendingBanTroll[attacker] && GetClientTeam(attacker) == 2 && GetClientTeam(victim) == 2) {
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
if(IsTrollActive(attacker, "DamageBoost")) {
|
||||
damage * 2;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action SoundHook(int[] clients, int& numClients, char sample[PLATFORM_MAX_PATH], int& entity, int& channel, float& volume, int& level, int& pitch, int& flags, char[] soundEntry, int& seed) {
|
||||
if(lastButtonUser > -1 && StrEqual(sample, "npc/mega_mob/mega_mob_incoming.wav")) {
|
||||
PrintToConsoleAll("CRESCENDO STARTED BY %N", lastButtonUser);
|
||||
#if defined DEBUG
|
||||
PrintToChatAll("CRESCENDO STARTED BY %N", lastButtonUser);
|
||||
#endif
|
||||
|
||||
lastCrescendoUser = lastButtonUser;
|
||||
if(IsPlayerFarDistance(lastButtonUser, AUTOPUNISH_FLOW_MIN_DISTANCE)) {
|
||||
NotifyAllAdmins("Autopunishing player %N for activation of event far from team", lastButtonUser);
|
||||
ShowActivity(0, "activated autopunish for crescendo activator %N (auto)", lastButtonUser);
|
||||
ActivateAutoPunish(lastButtonUser);
|
||||
}
|
||||
lastButtonUser = -1;
|
||||
}else if(numClients > 0 && entity > 0 && entity <= MaxClients) {
|
||||
if(StrContains(sample, "survivor\\voice") > -1) {
|
||||
if(IsTrollActive(entity, "Honk")) {
|
||||
strcopy(sample, sizeof(sample), "player/footsteps/clown/concrete1.wav");
|
||||
return Plugin_Changed;
|
||||
} else if(IsTrollActive(entity, "VocalizeGag")) {
|
||||
return Plugin_Handled;
|
||||
} else if(IsTrollActive(entity, "Meow")) {
|
||||
strcopy(sample, sizeof(sample), "custom/meow1.mp3");
|
||||
return Plugin_Changed;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_WitchVictimSet(Event event, const char[] name, bool dontBroadcast) {
|
||||
int witch = event.GetInt("witchid");
|
||||
float closestDistance, survPos[3], witchPos[3];
|
||||
GetEntPropVector(witch, Prop_Send, "m_vecOrigin", witchPos);
|
||||
int closestClient = -1;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
//Ignore incapped players if hWitchIgnoreIncapp turned on:
|
||||
if(IsPlayerIncapped(i) && !hWitchTargetIncapp.BoolValue) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(IsTrollActive(i, "WitchMagnet")) {
|
||||
GetClientAbsOrigin(i, survPos);
|
||||
float dist = GetVectorDistance(survPos, witchPos, true);
|
||||
if(closestClient == -1 || dist < closestDistance) {
|
||||
closestDistance = dist;
|
||||
closestClient = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(closestClient > 0) {
|
||||
DataPack pack;
|
||||
CreateDataTimer(0.1, Timer_NextWitchSet, pack);
|
||||
pack.WriteCell(GetClientUserId(closestClient));
|
||||
pack.WriteCell(witch);
|
||||
CreateDataTimer(0.2, Timer_NextWitchSet, pack);
|
||||
pack.WriteCell(GetClientUserId(closestClient));
|
||||
pack.WriteCell(witch);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_NextWitchSet(Handle timer, DataPack pack) {
|
||||
pack.Reset();
|
||||
int client = GetClientOfUserId(pack.ReadCell());
|
||||
int witch = pack.ReadCell();
|
||||
SetWitchTarget(witch, client);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CVAR CHANGES
|
||||
|
@ -499,591 +120,16 @@ public void Change_ThrowInterval(ConVar convar, const char[] oldValue, const cha
|
|||
// COMMANDS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Action Command_InstaSpecial(int client, int args) {
|
||||
if(args < 1) {
|
||||
Menu menu = new Menu(Insta_PlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
static char userid[8], display[16];
|
||||
Format(userid, sizeof(userid), "%d|0", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
char arg1[32], arg2[32] = "jockey";
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
if(args >= 2) {
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
}
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MaxClients,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
int specialType = GetSpecialType(arg2);
|
||||
static float pos[3];
|
||||
if(specialType == -1) {
|
||||
ReplyToCommand(client, "Unknown special \"%s\"", arg2);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
int target = target_list[i];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
SpawnSpecialNear(target, specialType);
|
||||
}else{
|
||||
ReplyToTargetError(client, target_count);
|
||||
}
|
||||
}
|
||||
ShowActivity(client, "spawned Insta-%s™ near %s", arg2, target_name);
|
||||
}
|
||||
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_InstaSpecialFace(int client, int args) {
|
||||
if(args < 1) {
|
||||
Menu menu = new Menu(Insta_PlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
static char userid[8], display[16];
|
||||
Format(userid, sizeof(userid), "%d|1", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
char arg1[32], arg2[32] = "jockey";
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
if(args >= 2) {
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
}
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MaxClients,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
int specialType = GetSpecialType(arg2);
|
||||
static float pos[3];
|
||||
if(specialType == -1) {
|
||||
ReplyToCommand(client, "Unknown special \"%s\"", arg2);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
int target = target_list[i];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
SpawnSpecialInFace(target, specialType);
|
||||
}else{
|
||||
ReplyToTargetError(client, target_count);
|
||||
}
|
||||
}
|
||||
ShowActivity(client, "spawned Insta-%s™ on %s", arg2, target_name);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
||||
public Action Command_WitchAttack(int client, int args) {
|
||||
if(args < 1) {
|
||||
ReplyToCommand(client, "Usage: sm_witch_attack <user>");
|
||||
} else {
|
||||
char arg1[32];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
1,
|
||||
COMMAND_FILTER_ALIVE | COMMAND_FILTER_NO_MULTI, /* Only allow alive players */
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
int target = target_list[0];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
int witch = INVALID_ENT_REFERENCE;
|
||||
while ((witch = FindEntityByClassname(witch, "witch")) != INVALID_ENT_REFERENCE) {
|
||||
SetWitchTarget(witch, target);
|
||||
|
||||
ShowActivity(client, "all witches target %s", target_name);
|
||||
}
|
||||
}else{
|
||||
ReplyToTargetError(client, target_count);
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_FeedTheCrescendoTroll(int client, int args) {
|
||||
if(lastCrescendoUser > -1) {
|
||||
ActivateAutoPunish(lastCrescendoUser);
|
||||
ReplyToCommand(client, "Activated auto punish on %N", lastCrescendoUser);
|
||||
ShowActivity(client, "activated autopunish for crescendo activator %N",lastCrescendoUser);
|
||||
}else{
|
||||
ReplyToCommand(client, "No player could be found to autopunish.");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ResetUser(int client, int args) {
|
||||
if(args < 1) {
|
||||
ReplyToCommand(client, "Usage: sm_ftr <user(s)>");
|
||||
}else{
|
||||
char arg1[32];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_CONNECTED, /* Only allow alive players */
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
if(ActiveTrolls[target_list[i]] > 0) {
|
||||
ResetClient(target_list[i], true);
|
||||
ShowActivity(client, "reset troll effects on \"%N\". ", target_list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ApplyUser(int client, int args) {
|
||||
if(args < 2) {
|
||||
Menu menu = new Menu(ChoosePlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
static char userid[8], display[16];
|
||||
Format(userid, sizeof(userid), "%d", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
}else{
|
||||
char arg1[32], arg2[32], arg3[8];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
GetCmdArg(3, arg3, sizeof(arg3));
|
||||
|
||||
bool silent = StrEqual(arg3, "silent") || StrEqual(arg3, "quiet") || StrEqual(arg3, "mute");
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
if(!GetTrollID(StringToInt(arg2), name)) {
|
||||
ReplyToCommand(client, "Not a valid mode. Must be greater than 0. Usage: sm_fta [player] [mode]. Use sm_ftr <player> to reset.");
|
||||
}else{
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
if(IsClientInGame(target_list[i]) && GetClientTeam(target_list[i]) == 2)
|
||||
ApplyTroll(target_list[i], name, client,TrollMod_None, silent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ListModes(int client, int args) {
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
static Troll troll;
|
||||
for(int i = 0; i <= MAX_TROLLS; i++) {
|
||||
GetTrollByKeyIndex(i, troll);
|
||||
ReplyToCommand(client, "%d. %s - %s", i, troll.name, troll.description);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_ListTheTrolls(int client, int args) {
|
||||
int count = 0;
|
||||
//TODO: Update
|
||||
char[][] modeListArr = new char[MAX_TROLLS+1][MAX_TROLL_NAME_LENGTH];
|
||||
static char modeList[255];
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && ActiveTrolls[i] > 0) {
|
||||
int modeCount = 0;
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
for(int j = 1; j <= MAX_TROLLS; j++) {
|
||||
GetTrollID(j, name);
|
||||
if(IsTrollActive(i, name)) {
|
||||
strcopy(modeListArr[modeCount], MAX_TROLL_NAME_LENGTH, name);
|
||||
modeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
ImplodeStrings(modeListArr, modeCount, ", ", modeList, sizeof(modeList));
|
||||
ReplyToCommand(client, "%N | %s", i, modeList);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count == 0) {
|
||||
ReplyToCommand(client, "No clients have a mode applied.");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_MarkPendingTroll(int client, int args) {
|
||||
if(args == 0) {
|
||||
Menu menu = new Menu(ChooseMarkedTroll);
|
||||
menu.SetTitle("Choose a troll to mark");
|
||||
static char userid[8], display[16];
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
AdminId admin = GetUserAdmin(i);
|
||||
if(admin == INVALID_ADMIN_ID) {
|
||||
Format(userid, sizeof(userid), "%d", GetClientUserId(i));
|
||||
GetClientName(i, display, sizeof(display));
|
||||
menu.AddItem(userid, display);
|
||||
}else{
|
||||
ReplyToCommand(client, "%N is an admin cannot be marked.", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
char arg1[32];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
1,
|
||||
COMMAND_FILTER_NO_MULTI , /* Only allow alive players */
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0
|
||||
) {
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
int target = target_list[0];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
ToggleMarkPlayer(client, target);
|
||||
}else{
|
||||
ReplyToCommand(client, "Player does not exist or is not a survivor.");
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_FeedTheTrollMenu(int client, int args) {
|
||||
ReplyToCommand(client, "sm_ftl - Lists all the active trolls on players");
|
||||
ReplyToCommand(client, "sm_ftm - Lists all available troll modes & descriptions");
|
||||
ReplyToCommand(client, "sm_ftr - Resets target users' of their trolls");
|
||||
ReplyToCommand(client, "sm_fta - Applies a troll mode on targets");
|
||||
ReplyToCommand(client, "sm_ftt - Opens this menu");
|
||||
ReplyToCommand(client, "sm_ftc - Will apply a punishment to last crescendo activator");
|
||||
ReplyToCommand(client, "sm_mark - Marks the user to be banned on disconnect, prevents their FF.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MENU HANDLER
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int Insta_PlayerHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
|
||||
static char str[2][8];
|
||||
ExplodeString(info, "|", str, 2, 8, false);
|
||||
|
||||
int userid = StringToInt(str[0]);
|
||||
int instaMode = StringToInt(str[1]);
|
||||
|
||||
Menu spMenu = new Menu(Insta_SpecialHandler);
|
||||
spMenu.SetTitle("Choose a Insta-Special™");
|
||||
for(int i = 1; i <= 6; i++) {
|
||||
static char id[8];
|
||||
Format(id, sizeof(id), "%d|%d|%d", userid, instaMode, i);
|
||||
spMenu.AddItem(id, SPECIAL_NAMES[i-1]);
|
||||
}
|
||||
spMenu.ExitButton = true;
|
||||
spMenu.Display(client, 0);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int Insta_SpecialHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[3][8];
|
||||
ExplodeString(info, "|", str, 3, 8, false);
|
||||
int target = GetClientOfUserId(StringToInt(str[0]));
|
||||
bool inFace = StrEqual(str[1], "1");
|
||||
int special = StringToInt(str[2]);
|
||||
if(inFace) {
|
||||
SpawnSpecialInFace(target, special);
|
||||
ShowActivity(client, "spawned Insta-%s™ near %N", SPECIAL_NAMES[special-1], target);
|
||||
} else {
|
||||
SpawnSpecialNear(target, special);
|
||||
ShowActivity(client, "spawned Insta-%s™ near %N", SPECIAL_NAMES[special-1], target);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
|
||||
public int ChooseMarkedTroll(Menu menu, MenuAction action, int activator, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
int target = GetClientOfUserId(StringToInt(info));
|
||||
ToggleMarkPlayer(activator, target);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int ChoosePlayerHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
int userid = StringToInt(info);
|
||||
|
||||
Menu trollMenu = new Menu(ChooseModeMenuHandler);
|
||||
trollMenu.SetTitle("Choose a troll mode");
|
||||
//TODO: Update
|
||||
static char id[8];
|
||||
static char name[MAX_TROLL_NAME_LENGTH];
|
||||
for(int i = 0; i <= MAX_TROLLS; i++) {
|
||||
GetTrollID(i, name);
|
||||
// int trollIndex = GetTrollByKeyIndex(i, troll);
|
||||
// Pass key index
|
||||
Format(id, sizeof(id), "%d|%d", userid, i);
|
||||
trollMenu.AddItem(id, name);
|
||||
}
|
||||
trollMenu.ExitButton = true;
|
||||
trollMenu.Display(param1, 0);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int ChooseModeMenuHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
/* If an option was selected, tell the client about the item. */
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[2][8];
|
||||
ExplodeString(info, "|", str, 2, 8, false);
|
||||
int userid = StringToInt(str[0]);
|
||||
int client = GetClientOfUserId(userid);
|
||||
int keyIndex = StringToInt(str[1]);
|
||||
static Troll troll;
|
||||
static char trollID[MAX_TROLL_NAME_LENGTH];
|
||||
GetTrollByKeyIndex(keyIndex, troll);
|
||||
troll.GetID(trollID, MAX_TROLL_NAME_LENGTH);
|
||||
//If mode has an option to be single-time fired/continous/both, prompt:
|
||||
if(!troll.runsOnce) {
|
||||
Menu modiferMenu = new Menu(ChooseTrollModiferHandler);
|
||||
modiferMenu.SetTitle("Choose Troll Modifer Option");
|
||||
static char singleUse[16], multiUse[16], bothUse[16];
|
||||
Format(singleUse, sizeof(singleUse), "%d|%d|1", userid, keyIndex);
|
||||
Format(multiUse, sizeof(multiUse), "%d|%d|2", userid, keyIndex);
|
||||
Format(bothUse, sizeof(bothUse), "%d|%d|3", userid, keyIndex);
|
||||
modiferMenu.AddItem(singleUse, "Activate once");
|
||||
modiferMenu.AddItem(multiUse, "Activate Periodically");
|
||||
modiferMenu.AddItem(bothUse, "Activate Periodically & Instantly");
|
||||
modiferMenu.ExitButton = true;
|
||||
modiferMenu.Display(param1, 0);
|
||||
} else {
|
||||
ApplyTroll(client, trollID, param1, TrollMod_None);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int ChooseTrollModiferHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[16];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[3][8];
|
||||
ExplodeString(info, "|", str, 3, 8, false);
|
||||
int client = GetClientOfUserId(StringToInt(str[0]));
|
||||
int keyIndex = StringToInt(str[1]);
|
||||
static Troll troll;
|
||||
static char trollID[MAX_TROLL_NAME_LENGTH];
|
||||
GetTrollByKeyIndex(keyIndex, troll);
|
||||
troll.GetID(trollID, MAX_TROLL_NAME_LENGTH);
|
||||
int modifier = StringToInt(str[2]);
|
||||
if(modifier == 2 || modifier == 3)
|
||||
ApplyTroll(client, trollID, param1, TrollMod_Repeat);
|
||||
else
|
||||
ApplyTroll(client, trollID, param1, TrollMod_InstantFire);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public void StopItemGive(int client) {
|
||||
g_bPendingItemGive[client] = false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TIMERS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Action Timer_ThrowTimer(Handle timer) {
|
||||
int count = 0;
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && IsTrollActive(i, "ThrowItAll")) {
|
||||
ThrowAllItems(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count > 0 ? Plugin_Continue : Plugin_Stop;
|
||||
}
|
||||
|
||||
public Action Timer_Main(Handle timer) {
|
||||
static int loop;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i)) {
|
||||
if(IsTrollActive(i, "SlowDrain")) {
|
||||
if(loop % 4 == 0) {
|
||||
int hp = GetClientHealth(i);
|
||||
if(hp > 50) {
|
||||
SetEntProp(i, Prop_Send, "m_iHealth", hp - 1);
|
||||
}
|
||||
}
|
||||
}else if(IsTrollActive(i, "TempHealthQuickDrain")) {
|
||||
if(loop % 2 == 0) {
|
||||
float bufferTime = GetEntPropFloat(i, Prop_Send, "m_healthBufferTime");
|
||||
float buffer = GetEntPropFloat(i, Prop_Send, "m_healthBuffer");
|
||||
float tempHealth = GetTempHealth(i);
|
||||
if(tempHealth > 0.0) {
|
||||
PrintToConsole(i, "%f | %f %f", tempHealth, buffer, bufferTime);
|
||||
//SetEntPropFloat(i, Prop_Send, "m_healthBuffer", buffer - 10.0);
|
||||
SetEntPropFloat(i, Prop_Send, "m_healthBufferTime", bufferTime - 7.0);
|
||||
}
|
||||
}
|
||||
}else if(IsTrollActive(i, "Swarm")) {
|
||||
L4D2_RunScript("RushVictim(GetPlayerFromUserID(%d), %d)", GetClientUserId(i), 15000);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(++loop >= 60) {
|
||||
loop = 0;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Timer_GivePistol(Handle timer, int client) {
|
||||
int flags = GetCommandFlags("give");
|
||||
SetCommandFlags("give", flags & ~FCVAR_CHEAT);
|
||||
FakeClientCommand(client, "give pistol");
|
||||
SetCommandFlags("give", flags|FCVAR_CHEAT);
|
||||
}
|
||||
|
||||
public Action Timer_ThrowWeapon(Handle timer, Handle pack) {
|
||||
ResetPack(pack);
|
||||
float dest[3];
|
||||
dest[0] = ReadPackFloat(pack);
|
||||
dest[1] = ReadPackFloat(pack);
|
||||
dest[2] = ReadPackFloat(pack);
|
||||
int slot = ReadPackCell(pack);
|
||||
int victim = ReadPackCell(pack);
|
||||
|
||||
int wpnRef = GetPlayerWeaponSlot(victim, slot);
|
||||
if(wpnRef != -1) {
|
||||
int wpn = EntRefToEntIndex(wpnRef);
|
||||
if(wpn != INVALID_ENT_REFERENCE) {
|
||||
if(slot == 1) {
|
||||
static char name[16];
|
||||
GetEdictClassname(wpn, name, sizeof(name));
|
||||
if(!StrEqual(name, "weapon_pistol", false)) {
|
||||
SDKHooks_DropWeapon(victim, wpn, dest);
|
||||
CreateTimer(0.2, Timer_GivePistol, victim);
|
||||
}
|
||||
}else
|
||||
SDKHooks_DropWeapon(victim, wpn, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_ResetAutoPunish(Handle timer, int user) {
|
||||
int client = GetClientOfUserId(user);
|
||||
if(client) {
|
||||
if(hAutoPunish.IntValue & 2 == 2)
|
||||
DisableTroll(client, "SpecialMagnet");
|
||||
if(hAutoPunish.IntValue & 1 == 1)
|
||||
DisableTroll(client, "TankMagnet");
|
||||
}
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// NATIVES & FORWARDS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue