mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-07 14:23:20 +00:00
Update FTT
This commit is contained in:
parent
956df81ba8
commit
ca2831ec53
10 changed files with 271 additions and 127 deletions
Binary file not shown.
|
@ -4,13 +4,14 @@
|
|||
//Allow MAX_TROLLS to be defined elsewhere
|
||||
#if defined MAX_TROLLS
|
||||
#else
|
||||
#define MAX_TROLLS 32
|
||||
#define MAX_TROLLS 33
|
||||
#endif
|
||||
|
||||
enum trollModifier {
|
||||
TrollMod_Invalid = 0,
|
||||
TrollMod_Instant = 1,
|
||||
TrollMod_Constant = 2
|
||||
TrollMod_Instant = 1 << 0,
|
||||
TrollMod_Constant = 1 << 1,
|
||||
TrollMod_PlayerOnly = 1 << 2, // Does the troll only work on players, not bots? If set, troll only applied on real user. If not, troll applied to both bot and idler
|
||||
}
|
||||
|
||||
//up to 30 flags technically possiible
|
||||
|
@ -32,6 +33,7 @@ char DEFAULT_FLAG_PROMPT[] = "Choose flags";
|
|||
bool SilentMenuSelected[MAXPLAYERS+1];
|
||||
|
||||
static int g_trollAddPromptIndex;
|
||||
ArrayList gRandomClients;
|
||||
|
||||
enum struct TrollFlagPrompt {
|
||||
char promptText[MAX_TROLL_FLAG_LENGTH];
|
||||
|
@ -57,13 +59,14 @@ enum struct Troll {
|
|||
|
||||
char name[MAX_TROLL_NAME_LENGTH];
|
||||
char description[128];
|
||||
bool hidden;
|
||||
|
||||
int mods;
|
||||
|
||||
// Flags
|
||||
int activeFlagClients[MAXPLAYERS+1];
|
||||
ArrayList flagNames;
|
||||
bool flagsMultiselectable;
|
||||
char flagPrompt[MAX_TROLL_FLAG_LENGTH];
|
||||
ArrayList flagNames;
|
||||
ArrayList flagPrompts;
|
||||
|
||||
bool HasMod(trollModifier mod) {
|
||||
|
@ -177,6 +180,7 @@ enum struct Troll {
|
|||
|
||||
void Activate(int client, int activator, trollModifier modifier = TrollMod_Invalid, int flags = 0) {
|
||||
if(modifier == TrollMod_Invalid) modifier = this.GetDefaultMod();
|
||||
// Sadly, unable to pass in <this> to ApplyTroll, so it has to do unnecessary lookup via string
|
||||
ApplyTroll(client, this.name, activator, modifier, flags);
|
||||
}
|
||||
|
||||
|
@ -195,6 +199,17 @@ enum struct Troll {
|
|||
bool IsActive(int client) {
|
||||
return this.activeFlagClients[client] != -1;
|
||||
}
|
||||
|
||||
int GetRandomClient(int start = 0) {
|
||||
gRandomClients.Clear();
|
||||
for(int i = start + 1; i <= MaxClients; i++) {
|
||||
if(this.activeFlagClients[i] != -1) {
|
||||
gRandomClients.Push(i);
|
||||
}
|
||||
}
|
||||
if(gRandomClients.Length == 0) return -1;
|
||||
return GetRandomInt(0, gRandomClients.Length);
|
||||
}
|
||||
}
|
||||
|
||||
Troll Trolls[MAX_TROLLS+1];
|
||||
|
@ -203,12 +218,13 @@ ArrayList categories;
|
|||
static int categoryID = -1;
|
||||
|
||||
void ResetClient(int victim, bool wipe = true) {
|
||||
if(victim == 0) return;
|
||||
if(victim == 0 || !IsClientConnected(victim)) return;
|
||||
if(wipe) {
|
||||
for(int i = 0; i <= MAX_TROLLS; i++) {
|
||||
Trolls[i].activeFlagClients[victim] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
SetEntityGravity(victim, 1.0);
|
||||
SetEntPropFloat(victim, Prop_Send, "m_flLaggedMovementValue", 1.0);
|
||||
SDKUnhook(victim, SDKHook_WeaponCanUse, Event_ItemPickup);
|
||||
|
@ -217,14 +233,14 @@ void ResetClient(int victim, bool wipe = true) {
|
|||
SDKUnhook(wpn, SDKHook_Reload, Event_WeaponReload);
|
||||
}
|
||||
|
||||
int SetupTroll(const char[] name, const char description[128], int mods, bool flagsMultiselectable = false) {
|
||||
if(mods == 0) {
|
||||
ThrowError("Troll \"%s\" has no flags defined.", name);
|
||||
return -1;
|
||||
}
|
||||
int SetupTroll(const char[] name, const char description[128], int mods) {
|
||||
static int i = 0;
|
||||
if(i == MAX_TROLLS + 1) {
|
||||
if(mods == 0) {
|
||||
ThrowError("Troll \"%s\" has no modifiers defined.", name);
|
||||
return -1;
|
||||
} else if(i == MAX_TROLLS + 1) {
|
||||
ThrowError("Maximum number of trolls (%d) reached. Up MAX_TROLLS value.", MAX_TROLLS);
|
||||
return -1;
|
||||
}
|
||||
g_trollAddPromptIndex = 0;
|
||||
Trolls[i].id = i;
|
||||
|
@ -232,7 +248,6 @@ int SetupTroll(const char[] name, const char description[128], int mods, bool fl
|
|||
strcopy(Trolls[i].description, 128, description);
|
||||
Trolls[i].categoryID = categoryID;
|
||||
Trolls[i].mods = mods;
|
||||
Trolls[i].flagsMultiselectable = flagsMultiselectable;
|
||||
Trolls[i].flagPrompts = new ArrayList(sizeof(TrollFlagPrompt));
|
||||
|
||||
strcopy(trollIds[i], MAX_TROLL_NAME_LENGTH, name);
|
||||
|
@ -284,7 +299,7 @@ void ToggleTroll(int client, const char[] name, int flags = 0) {
|
|||
troll.activeFlagClients[client] = flags;
|
||||
}
|
||||
|
||||
void ApplyTroll(int victim, const char[] name, int activator, trollModifier modifier, int flags = 0) {
|
||||
void ApplyTroll(int victim, const char[] name, int activator, trollModifier modifier, int flags = 0, bool silent = false) {
|
||||
static Troll troll;
|
||||
int trollIndex = GetTroll(name, troll);
|
||||
if(trollIndex == -1) {
|
||||
|
@ -292,21 +307,46 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
return;
|
||||
}
|
||||
|
||||
if(GetClientTeam(victim) == 1) {
|
||||
//Victim is spectating, find its bot
|
||||
victim = FindIdlePlayerBot(victim);
|
||||
if(!silent && SilentMenuSelected[activator]) silent = true;
|
||||
|
||||
static int MetaInverseTrollID;
|
||||
if(!MetaInverseTrollID) MetaInverseTrollID = GetTrollID("Meta: Inverse");
|
||||
|
||||
if(activator > 0 && Trolls[MetaInverseTrollID].IsActive(activator)) {
|
||||
float max = 1.0;
|
||||
if(Trolls[MetaInverseTrollID].activeFlagClients[activator] & 2) max = 0.5;
|
||||
else if(Trolls[MetaInverseTrollID].activeFlagClients[activator] & 4) max = 0.1;
|
||||
if(GetRandomFloat() <= max) {
|
||||
victim = activator;
|
||||
}
|
||||
}
|
||||
|
||||
// If victim is a survivor bot, check if has an idle player
|
||||
if(IsFakeClient(victim) && GetClientTeam(victim) == 2) {
|
||||
int player = GetSpectatorClient(victim);
|
||||
if(player > 0) {
|
||||
// If there is an idle player, apply troll to them
|
||||
ApplyTroll(player, name, activator, modifier, flags, silent);
|
||||
// And continue IF there is TrollMod_PlayerOnly mod
|
||||
if(troll.mods & view_as<int>(TrollMod_PlayerOnly)) return;
|
||||
// Don't want to show two logs, so just ignore the bot
|
||||
silent = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Applies any custom logic needed for a troll, mostly only used for TrollMod_Instant
|
||||
if(!ApplyAffect(victim, troll, activator, modifier, flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Log all actions, indicating if constant or single-fire, and if any flags
|
||||
bool isActive = IsTrollActive(victim, troll.name);
|
||||
if(!SilentMenuSelected[activator]) {
|
||||
if(!silent) {
|
||||
if(isActive) {
|
||||
ShowActivityEx(activator, "[FTT] ", "deactivated troll \"%s\" on %N. ", troll.name, victim);
|
||||
LogAction(activator, victim, "\"%L\" deactivated troll \"%s\" on \"%L\"", activator, troll.name, victim);
|
||||
} else {
|
||||
if(modifier == TrollMod_Constant) {
|
||||
if(modifier & TrollMod_Constant) {
|
||||
if(flags > 0) {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated constant troll \"%s\" (%d) for %N. ", troll.name, flags, victim);
|
||||
} else
|
||||
|
@ -318,8 +358,11 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
|
||||
LogAction(activator, victim, "\"%L\" activated troll \"%s\" (%d) for \"%L\"", activator, troll.name, flags, victim);
|
||||
}
|
||||
} else SilentMenuSelected[activator] = false;
|
||||
if(modifier == TrollMod_Constant) {
|
||||
} else {
|
||||
ReplyToCommand(activator, "apply troll \"%s\" flags=%d on %N", troll.name, flags, victim);
|
||||
}
|
||||
// Toggle on flags for client, if it's not a single run.
|
||||
if(modifier & TrollMod_Constant) {
|
||||
Trolls[troll.id].activeFlagClients[victim] = isActive ? -1 : flags;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ public Action Command_InstaSpecial(int client, int args) {
|
|||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
if(gInstaSpecialType > -1) {
|
||||
ReplyToCommand(client, "Please wait for last Insta to spawn.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
char arg1[32], arg2[32] = "jockey";
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
if(args >= 2) {
|
||||
|
@ -78,6 +82,10 @@ public Action Command_InstaSpecialFace(int client, int args) {
|
|||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
if(gInstaSpecialType > -1) {
|
||||
ReplyToCommand(client, "Please wait for last Insta to spawn.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
char arg1[32], arg2[32] = "jockey";
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
if(args >= 2) {
|
||||
|
@ -215,6 +223,7 @@ public Action Command_ResetUser(int client, int args) {
|
|||
|
||||
public Action Command_ApplyUser(int client, int args) {
|
||||
if(args < 1) {
|
||||
SilentMenuSelected[client] = false;
|
||||
ShowTrollMenu(client);
|
||||
}else{
|
||||
char arg1[32], arg2[16];
|
||||
|
@ -244,12 +253,14 @@ public Action Command_ApplyUser(int client, int args) {
|
|||
for(int i = 0; i < categories.Length; i++) {
|
||||
categories.GetString(i, key, sizeof(key));
|
||||
if(StrEqual(key, arg2, false)) {
|
||||
SilentMenuSelected[client] = false;
|
||||
ShowTrollsForCategory(client, GetClientUserId(target_list[0]), i);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
ReplyToCommand(client, "[FTT] Unknown category: '%s'", arg2);
|
||||
}
|
||||
SilentMenuSelected[client] = false;
|
||||
SetupCategoryMenu(client, target_list[0]);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
|
@ -304,6 +315,7 @@ public Action Command_ListModes(int client, int args) {
|
|||
static Troll troll;
|
||||
for(int i = 0; i <= MAX_TROLLS; i++) {
|
||||
GetTrollByKeyIndex(i, troll);
|
||||
if(troll.hidden) continue;
|
||||
ReplyToCommand(client, "%d. %s - %s", i, troll.name, troll.description);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
|
@ -346,6 +358,7 @@ public Action Command_ListTheTrolls(int client, int args) {
|
|||
}
|
||||
|
||||
for(int j = 1; j <= MAX_TROLLS; j++) {
|
||||
if(Trolls[j].hidden) continue;
|
||||
if(trollIds[j][0] != '\0' && IsTrollActive(target, trollIds[j])) {
|
||||
if(Trolls[j].activeFlagClients[target] > 0) {
|
||||
static char list[MAX_TROLL_FLAG_LENGTH*8]; //May in future need to up magic number 8 (supports 8 active flags )
|
||||
|
@ -423,7 +436,7 @@ public Action Command_MarkPendingTroll(int client, int args) {
|
|||
menu.ExitButton = true;
|
||||
menu.Display(client, 0);
|
||||
} else {
|
||||
char arg1[32];
|
||||
static char arg1[32];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
char target_name[MAX_TARGET_LENGTH];
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
|
@ -452,13 +465,45 @@ public Action Command_MarkPendingTroll(int client, int args) {
|
|||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_MarkNoob(int client, int args) {
|
||||
if(args == 0) {
|
||||
ReplyToCommand(client, "sm_noob <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
static char target_name[MAX_TARGET_LENGTH];
|
||||
GetCmdArg(1, target_name, sizeof(target_name));
|
||||
|
||||
int target_list[MAXPLAYERS], target_count;
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
target_name,
|
||||
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];
|
||||
//Todo: Check if marked as noob or not, undo if so, add if not
|
||||
|
||||
ShowActivityEx(client, "[FTT] ", "marked %N as a noob", target_name);
|
||||
LogAction(client, target, "\"%L\" marked \"%L\" as a noob", client, target);
|
||||
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_ftl [player(s)] - Lists all the active trolls on players. Will show flag names if a player is specified.");
|
||||
ReplyToCommand(client, "sm_ftm - Lists all available trolls & descriptions");
|
||||
ReplyToCommand(client, "sm_ftr <player(s)> - Resets target users' of any active trolls");
|
||||
ReplyToCommand(client, "sm_fta [player] [category] - Apply a troll on a player, with optional shortcut to player and/or category");
|
||||
ReplyToCommand(client, "sm_ftt - Shows this text");
|
||||
ReplyToCommand(client, "sm_ftc - Will apply a punishment to the last crescendo/event activator");
|
||||
ReplyToCommand(client, "sm_mark - Marks the user to be banned on disconnect, prevents their FF.");
|
||||
return Plugin_Handled;
|
||||
}
|
|
@ -19,6 +19,29 @@ public void OnMapStart() {
|
|||
public void OnClientPutInServer(int client) {
|
||||
g_PendingBanTroll[client] = 0;
|
||||
SDKHook(client, SDKHook_OnTakeDamage, Event_TakeDamage);
|
||||
}
|
||||
public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||
int userid = event.GetInt("userid");
|
||||
CreateTimer(0.1, Timer_CheckSpecial, userid);
|
||||
}
|
||||
public Action Timer_CheckSpecial(Handle h, int specialID) {
|
||||
int special = GetClientOfUserId(specialID);
|
||||
if(special > 0 && gInstaSpecialType > -1 && IsFakeClient(special) && GetClientTeam(special) == 3) {
|
||||
int type = GetEntProp(special, Prop_Send, "m_zombieClass");
|
||||
if(type == gInstaSpecialType) {
|
||||
gInstaSpecialType = -1;
|
||||
g_iAttackerTarget[special] = gInstaSpecialTarget;
|
||||
gInstaSpecialMagnet[GetClientOfUserId(gInstaSpecialTarget)]++;
|
||||
|
||||
TeleportEntity(special, gInstaSpecialSpawnPos, gInstaSpecialSpawnAng, NULL_VECTOR);
|
||||
if(gInstaSpecialInstaKill) {
|
||||
SDKHooks_TakeDamage(special, special, special, 1000.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Frame_InstaSpawned(int special) {
|
||||
|
||||
}
|
||||
public void OnClientAuthorized(int client, const char[] auth) {
|
||||
if(!IsFakeClient(client)) {
|
||||
|
@ -39,6 +62,14 @@ public void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroa
|
|||
}
|
||||
public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client > 0 && g_iAttackerTarget[client] > 0) {
|
||||
int target = GetClientOfUserId(g_iAttackerTarget[client]);
|
||||
gInstaSpecialMagnet[target]--;
|
||||
if(gInstaSpecialMagnet[target] == 0) {
|
||||
PrintToServer("[FTT] gInstaSpecialMagnet droped below 0");
|
||||
gInstaSpecialMagnet[target] = 0;
|
||||
}
|
||||
}
|
||||
g_iAttackerTarget[client] = 0;
|
||||
}
|
||||
public Action Event_WeaponReload(int weapon) {
|
||||
|
@ -85,11 +116,14 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
|||
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))) {
|
||||
if(existingTarget > 0 && IsPlayerAlive(existingTarget)) {
|
||||
if(gInstaSpecialMagnet[existingTarget] > 0) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}else if(hMagnetTargetMode.IntValue & 1 != 1 || !IsPlayerIncapped(existingTarget)) {
|
||||
} else if(class == L4D2Infected_Tank && (!IsPlayerIncapped(existingTarget) || hMagnetTargetMode.IntValue & 2) && WillMagnetRun(Trolls[tankMagnetID], existingTarget)) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}else if((!IsPlayerIncapped(existingTarget) || hMagnetTargetMode.IntValue & 1) && WillMagnetRun(Trolls[spMagnetID], existingTarget)) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
|
@ -102,7 +136,7 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
|||
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 && hMagnetTargetMode.IntValue & 2) || (class != L4D2Infected_Tank && hMagnetTargetMode.IntValue & 1)) continue;
|
||||
}
|
||||
|
||||
if(class == L4D2Infected_Tank && Trolls[tankMagnetID].IsActive(i) || (class != L4D2Infected_Tank && Trolls[spMagnetID].IsActive(i))) {
|
||||
|
@ -355,10 +389,10 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
return Plugin_Continue;
|
||||
}
|
||||
static int invertedTrollIndex;
|
||||
if(invertedTrollIndex <= 0) {
|
||||
if(invertedTrollIndex == 0) {
|
||||
invertedTrollIndex = GetTrollID("Inverted Controls");
|
||||
}
|
||||
if(IsTrollActiveByRawID(client, invertedTrollIndex)) {
|
||||
if(Trolls[invertedTrollIndex].IsActive(client)) {
|
||||
if(buttons & IN_MOVELEFT || buttons & IN_MOVERIGHT) {
|
||||
vel[1] = -vel[1];
|
||||
}
|
||||
|
@ -397,7 +431,7 @@ public Action Event_TakeDamage(int victim, int& attacker, int& inflictor, float&
|
|||
if(IsTrollActive(victim, "Damage Boost")) {
|
||||
damage * 2;
|
||||
return Plugin_Changed;
|
||||
} else if(Trolls[reverseFF].IsActive(attacker) && attacker != victim && GetClientTeam(attacker) != GetClientTeam(victim)) {
|
||||
} else if(Trolls[reverseFF].IsActive(attacker) && attacker != victim && GetClientTeam(attacker) == GetClientTeam(victim)) {
|
||||
float returnDmg = damage; //default is 1:1
|
||||
if(Trolls[reverseFF].activeFlagClients[attacker] & 4) {
|
||||
returnDmg /= 2.0;
|
||||
|
@ -413,6 +447,8 @@ public Action Event_TakeDamage(int victim, int& attacker, int& inflictor, float&
|
|||
}
|
||||
|
||||
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) {
|
||||
static int honkID;
|
||||
if(honkID == 0) honkID = GetTrollID("Honk / Meow");
|
||||
if(lastButtonUser > -1 && StrEqual(sample, "npc/mega_mob/mega_mob_incoming.wav")) {
|
||||
PrintToConsoleAll("CRESCENDO STARTED BY %N", lastButtonUser);
|
||||
#if defined DEBUG
|
||||
|
@ -429,22 +465,16 @@ public Action SoundHook(int[] clients, int& numClients, char sample[PLATFORM_MAX
|
|||
lastButtonUser = -1;
|
||||
}else if(numClients > 0 && entity > 0 && entity <= MaxClients) {
|
||||
if(StrContains(sample, "survivor\\voice") > -1) {
|
||||
static int honkID;
|
||||
if(honkID == 0) {
|
||||
honkID = GetTrollID("Honk / Meow");
|
||||
}
|
||||
if(Trolls[honkID].IsActive(entity)) {
|
||||
if(Trolls[honkID].activeFlagClients[entity] & 1)
|
||||
strcopy(sample, sizeof(sample), "player/footsteps/clown/concrete1.wav");
|
||||
else if(Trolls[honkID].activeFlagClients[entity] & 2)
|
||||
strcopy(sample, sizeof(sample), "custom/meow1.mp3");
|
||||
else return Plugin_Continue;
|
||||
return Plugin_Changed;
|
||||
} else if(IsTrollActive(entity, "Vocalize Gag")) {
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
@ -457,7 +487,7 @@ public Action Event_WitchVictimSet(Event event, const char[] name, bool dontBroa
|
|||
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) {
|
||||
if(IsPlayerIncapped(i) && ~hMagnetTargetMode.IntValue & 4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -227,14 +227,15 @@ public int ChooseTrollFlagHandler(Menu menu, MenuAction action, int param1, int
|
|||
if (action == MenuAction_Select) {
|
||||
static char info[32];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[5][8];
|
||||
ExplodeString(info, "|", str, 5, 8, false);
|
||||
static char str[6][8];
|
||||
ExplodeString(info, "|", str, 6, 8, false);
|
||||
int userid = StringToInt(str[0]);
|
||||
int client = GetClientOfUserId(userid);
|
||||
int keyIndex = StringToInt(str[1]);
|
||||
int modifiers = StringToInt(str[2]);
|
||||
int flags = StringToInt(str[3]);
|
||||
int nextIndex = StringToInt(str[4]);
|
||||
int index = StringToInt(str[4]);
|
||||
bool isDone = StringToInt(str[5]) == 1; // 0 = cont, 1 = done
|
||||
|
||||
if(client == 0) {
|
||||
ReplyToCommand(param1, "FTT: Could not acquire player");
|
||||
|
@ -247,13 +248,17 @@ public int ChooseTrollFlagHandler(Menu menu, MenuAction action, int param1, int
|
|||
static TrollFlagPrompt prompt;
|
||||
// If told to go to next prompt, find the next VALID prompt
|
||||
// Valid prompt is one where the required flags for it, are active
|
||||
if(nextIndex != -1) {
|
||||
nextIndex = GetNextPrompt(troll, flags, nextIndex);
|
||||
if(isDone || index == -1) {
|
||||
int nextIndex = GetNextPrompt(troll, flags, index);
|
||||
// If there is a prompt available, show it, else fall down
|
||||
if(nextIndex != -1) {
|
||||
ShowSelectFlagMenu(param1, userid, modifiers, troll, flags, nextIndex);
|
||||
return;
|
||||
}
|
||||
// else fall through & apply
|
||||
} else {
|
||||
ShowSelectFlagMenu(param1, userid, modifiers, troll, flags, index);
|
||||
return;
|
||||
}
|
||||
|
||||
// Done with prompts, apply flags & modifiers
|
||||
|
@ -302,6 +307,7 @@ void ShowTrollMenu(int client) {
|
|||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
IntToString(GetClientUserId(i), userid, sizeof(userid));
|
||||
int specClient = GetSpectatorClient(i);
|
||||
// Incase player is idle, grab their bot instead of them
|
||||
if(specClient > 0)
|
||||
Format(display, sizeof(display), "%N (Idle)", specClient);
|
||||
else
|
||||
|
@ -328,6 +334,8 @@ void ShowTrollsForCategory(int client, int userid, int category) {
|
|||
static char name[MAX_TROLL_NAME_LENGTH+8];
|
||||
for(int i = 0; i < trollKV.Size; i++) {
|
||||
GetTrollByKeyIndex(i, troll);
|
||||
// If troll is hidden and using normal menu, do not show
|
||||
if(troll.hidden && !SilentMenuSelected[client]) continue;
|
||||
if(troll.categoryID == category) {
|
||||
Format(info, sizeof(info), "%d|%d", userid, i);
|
||||
if(troll.IsActive(victim)) {
|
||||
|
@ -356,19 +364,11 @@ void ShowSelectFlagMenu(int activator, int victimUserID, int modifiers, Troll tr
|
|||
Format(info, sizeof(info), "%s: %s", troll.name, info);
|
||||
flagMenu.SetTitle(info);
|
||||
|
||||
// If there is another prompt, go to this index, or be done (-1)
|
||||
int nextIndex = (promptIndex < troll.flagPrompts.Length - 1) ? promptIndex + 1 : -1;
|
||||
|
||||
if(prompt.multiselect) {
|
||||
if(prevFlags == 0) prevFlags = prompt.defaults;
|
||||
|
||||
// If there is a next prompt (even if may not be suitable), show a "next prompt" msg instead
|
||||
Format(info, sizeof(info), "%d|%d|%d|%d|%d", victimUserID, troll.id, modifiers, prevFlags, nextIndex);
|
||||
if(nextIndex == -1)
|
||||
flagMenu.AddItem(info, "Apply Troll / Finish");
|
||||
else
|
||||
flagMenu.AddItem(info, "Next Prompt");
|
||||
|
||||
Format(info, sizeof(info), "%d|%d|%d|%d|%d|1", victimUserID, troll.id, modifiers, prevFlags, promptIndex);
|
||||
flagMenu.AddItem(info, "Apply / Next Prompt");
|
||||
|
||||
for(int i = 0; i < troll.flagNames.Length; i++) {
|
||||
int a = 1 << i;
|
||||
|
@ -378,21 +378,22 @@ void ShowSelectFlagMenu(int activator, int victimUserID, int modifiers, Troll tr
|
|||
if(prevFlags > 0 && prevFlags & a)
|
||||
Format(name, sizeof(name), "%s (On)", name);
|
||||
int newFlags = prevFlags ^ a; //Toggle the flag instead of setting like below, as it's toggleable here
|
||||
Format(info, sizeof(info), "%d|%d|%d|%d|%d", victimUserID, troll.id, modifiers, newFlags, promptIndex);
|
||||
Format(info, sizeof(info), "%d|%d|%d|%d|%d|0", victimUserID, troll.id, modifiers, newFlags, promptIndex);
|
||||
flagMenu.AddItem(info, name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Single choice only
|
||||
for(int i = 0; i < troll.flagNames.Length; i++) {
|
||||
if(prompt.flags & 1 << i) {
|
||||
int a = 1 << i;
|
||||
if(prompt.flags & a) {
|
||||
troll.flagNames.GetString(i, name, sizeof(name));
|
||||
// Add (default) indicator
|
||||
|
||||
if(prompt.defaults & 1 << i)
|
||||
if(prompt.defaults & a)
|
||||
Format(name, sizeof(name), "%s (default)", name);
|
||||
int newFlags = prevFlags | 1 << i; //Set flag with any from previous prompts
|
||||
Format(info, sizeof(info), "%d|%d|%d|%d|%d", victimUserID, troll.id, modifiers, newFlags, nextIndex);
|
||||
int newFlags = prevFlags | a; //Set flag with any from previous prompts
|
||||
Format(info, sizeof(info), "%d|%d|%d|%d|%d|1", victimUserID, troll.id, modifiers, newFlags, promptIndex);
|
||||
flagMenu.AddItem(info, name);
|
||||
}
|
||||
}
|
||||
|
@ -433,7 +434,8 @@ void ShowThrowItAllMenu(int client, int userid) {
|
|||
int GetNextPrompt(Troll troll, int flags, int currentPrompt = 0) {
|
||||
static TrollFlagPrompt prompt;
|
||||
//If this prompt requires flags but they don't exist, skip to next that is valid or be done:
|
||||
for(int i = currentPrompt; i < troll.flagPrompts.Length; i++) {
|
||||
if(currentPrompt + 1 == troll.flagPrompts.Length) return -1;
|
||||
for(int i = currentPrompt + 1; i < troll.flagPrompts.Length; i++) {
|
||||
troll.GetFlagPrompt(i, prompt);
|
||||
if(prompt.requireFlags & flags) {
|
||||
return i;
|
||||
|
|
|
@ -53,16 +53,18 @@ bool ToggleMarkPlayer(int client, int target) {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
// Finds the survivor bot that took over an idle player
|
||||
int GetSpectatorClient(int bot) {
|
||||
if(!IsFakeClient(bot)) return -1;
|
||||
static char netclass[16];
|
||||
GetEntityNetClass(bot, netclass, sizeof(netclass));
|
||||
if(strcmp(netclass, "SurvivorBot") == 0 ) {
|
||||
int user = GetEntProp(bot, Prop_Send, "m_humanSpectatorUserID");
|
||||
if(user > 0) return GetClientOfUserId(user);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
stock bool IsPlayerIncapped(int client) {
|
||||
return GetEntProp(client, Prop_Send, "m_isIncapacitated") == 1;
|
||||
}
|
||||
|
@ -238,14 +240,3 @@ void DropItem(int victim, int slot) {
|
|||
SDKHooks_DropWeapon(victim, wpn, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
int GetSpectatorClient(int bot) {
|
||||
if(!IsFakeClient(bot)) return -1;
|
||||
static char netclass[16];
|
||||
GetEntityNetClass(bot, netclass, sizeof(netclass));
|
||||
if(strcmp(netclass, "SurvivorBot") == 0 ) {
|
||||
int user = GetEntProp(bot, Prop_Send, "m_humanSpectatorUserID");
|
||||
if(user > 0) return GetClientOfUserId(user);
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -43,6 +43,8 @@ bool SpawnSpecialInFace(int target, int specialType) {
|
|||
testPos = pos;
|
||||
GetClientAbsOrigin(target, pos);
|
||||
GetClientEyeAngles(target, ang);
|
||||
if(specialType == 2)
|
||||
gInstaSpecialInstaKill = true;
|
||||
if(specialType != 5 && specialType != 2) { //If not jockey/hunter find a suitable area that is at least 5 m away
|
||||
float minDistance = GetIdealMinDistance(specialType);
|
||||
GetHorizontalPositionFromOrigin(pos, ang, minDistance, testPos);
|
||||
|
@ -57,14 +59,15 @@ bool SpawnSpecialInFace(int target, int specialType) {
|
|||
pos[2] += 1.0;
|
||||
NegateVector(ang);
|
||||
|
||||
return SpawnSpecialInternal(specialType, target, pos, NULL_VECTOR) > 0;
|
||||
return SpawnSpecialInternal(specialType, target, pos, NULL_VECTOR) != -1;
|
||||
}
|
||||
|
||||
bool SpawnSpecialNear(int target, int specialType) {
|
||||
gInstaSpecialInstaKill = false;
|
||||
if(specialType > 8) return false;
|
||||
static float pos[3];
|
||||
if(L4D_GetRandomPZSpawnPosition(target, specialType, 10, pos)) {
|
||||
return SpawnSpecialInternal(specialType, target, pos, NULL_VECTOR) > 0;
|
||||
return SpawnSpecialInternal(specialType, target, pos, NULL_VECTOR) != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -80,11 +83,19 @@ void BypassLimit() {
|
|||
|
||||
int SpawnSpecialInternal(int type, int target, float pos[3], float ang[3]) {
|
||||
if(type <= 6) {
|
||||
// BypassLimit();
|
||||
int special = L4D2_SpawnSpecial(type, pos, ang);
|
||||
if(special != -1)
|
||||
g_iAttackerTarget[special] = GetClientUserId(target);
|
||||
return special;
|
||||
// Bypass limit:
|
||||
gInstaSpecialType = type;
|
||||
gInstaSpecialTarget = GetClientUserId(target);
|
||||
gInstaSpecialSpawnPos = pos;
|
||||
gInstaSpecialSpawnAng = pos;
|
||||
CreateTimer(2.0, Timer_InstaFailed);
|
||||
int bot = CreateFakeClient("ManualDirectorBot");
|
||||
if (bot != 0) {
|
||||
ChangeClientTeam(bot, 3);
|
||||
CreateTimer(0.1, Timer_KickBot, bot);
|
||||
}
|
||||
CheatCommand(target, "z_spawn_old", SPECIAL_NAMES[type-1], "auto");
|
||||
return 0;
|
||||
}
|
||||
else if(type == 7) {
|
||||
int witch = L4D2_SpawnWitch(pos, ang);
|
||||
|
@ -102,3 +113,9 @@ int SpawnSpecialInternal(int type, int target, float pos[3], float ang[3]) {
|
|||
}
|
||||
else return -1;
|
||||
}
|
||||
|
||||
/* TODO: Bypass limit:
|
||||
Spawn special auto, far away, mark with global vars:
|
||||
1. special type (check)
|
||||
2. its target
|
||||
3. float[3] to TP it to
|
|
@ -101,3 +101,10 @@ public Action Timer_KickBot(Handle timer, int client) {
|
|||
if(IsFakeClient(client)) KickClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_InstaFailed(Handle h) {
|
||||
if(gInstaSpecialType != -1) {
|
||||
gInstaSpecialType = -1;
|
||||
gInstaSpecialTarget = 0;
|
||||
}
|
||||
}
|
|
@ -3,15 +3,16 @@
|
|||
void SetupTrolls() {
|
||||
trollKV = new StringMap();
|
||||
categories = new ArrayList(ByteCountToCells(16));
|
||||
gRandomClients = new ArrayList();
|
||||
int index;
|
||||
SetupTroll("Reset User", "Resets the user, removes all troll effects", TrollMod_Instant);
|
||||
|
||||
SetCategory("Magnets");
|
||||
index = SetupTroll("Special Magnet", "Attracts ALL specials to any alive target with this troll enabled", TrollMod_Constant, false);
|
||||
index = SetupTroll("Special Magnet", "Attracts ALL specials to any alive target with this troll enabled", TrollMod_Constant);
|
||||
AddMagnetFlags(index);
|
||||
index = SetupTroll("Tank Magnet", "Attracts ALL tanks to any alive target with this troll enabled", TrollMod_Constant, false);
|
||||
index = SetupTroll("Tank Magnet", "Attracts ALL tanks to any alive target with this troll enabled", TrollMod_Constant);
|
||||
AddMagnetFlags(index);
|
||||
index = SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", TrollMod_Constant, false);
|
||||
index = SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", TrollMod_Constant);
|
||||
|
||||
SetCategory("Infected");
|
||||
SetupTroll("Swarm", "Swarms a player with zombies. Requires swarm plugin", TrollMod_Instant | TrollMod_Constant);
|
||||
|
@ -21,12 +22,12 @@ void SetupTrolls() {
|
|||
SetupTroll("Goo", "Spawns a spitter puddle underneath them", TrollMod_Instant);
|
||||
|
||||
SetCategory("Items");
|
||||
index = SetupTroll("Throw It All", "Player throws their item(s) periodically to a nearby player", TrollMod_Instant, false);
|
||||
index = SetupTroll("Throw It All", "Player throws their item(s) periodically to a nearby player", TrollMod_Instant);
|
||||
//Can't add directly, is custom troll:
|
||||
// Trolls[index].AddFlag("Throw to Admin", true);
|
||||
// Trolls[index].AddFlag("Drop At Feet", false);
|
||||
// Trolls[index].AddFlag("Drop At Admin", false);
|
||||
index = SetupTroll("Bad Throw", "Player drops throwables on throw, and biles/molotovs themselves", TrollMod_Constant, true);
|
||||
index = SetupTroll("Bad Throw", "Player drops throwables on throw, and biles/molotovs themselves", TrollMod_Constant | TrollMod_PlayerOnly);
|
||||
Trolls[index].AddFlagPrompt(true);
|
||||
Trolls[index].AddFlag("Biles", true);
|
||||
Trolls[index].AddFlag("Molotovs", true);
|
||||
|
@ -42,8 +43,8 @@ void SetupTrolls() {
|
|||
SetupTroll("Half Primary Ammo", "Cuts their primary reserve ammo in half", TrollMod_Instant);
|
||||
|
||||
SetCategory("Chat");
|
||||
SetupTroll("iCantSpellNoMore", "Chat messages letter will randomly changed with wrong letters", TrollMod_Constant);
|
||||
index = SetupTroll("No Profanity", "Replaces some words with random phrases", TrollMod_Constant);
|
||||
SetupTroll("iCantSpellNoMore", "Chat messages letter will randomly changed with wrong letters", TrollMod_Constant | TrollMod_PlayerOnly);
|
||||
index = SetupTroll("No Profanity", "Replaces some words with random phrases", TrollMod_Constant | TrollMod_PlayerOnly);
|
||||
Trolls[index].AddFlagPrompt(false);
|
||||
Trolls[index].AddFlag("Only Replace Swears", false);
|
||||
Trolls[index].AddFlag("Replace Full Messages", true);
|
||||
|
@ -51,21 +52,21 @@ void SetupTrolls() {
|
|||
Trolls[index].AddFlag("Show Modified to Them", true);
|
||||
Trolls[index].AddFlag("Show Original to Them", false);
|
||||
SetupTroll("Vocalize Gag", "Prevents player from sending any vocalizations (even automatic)", TrollMod_Constant);
|
||||
index = SetupTroll("Honk / Meow", "Honk or Meow", TrollMod_Constant, false);
|
||||
index = SetupTroll("Honk / Meow", "Honk or Meow", TrollMod_Constant);
|
||||
Trolls[index].AddCustomFlagPrompt("Choose Sound Type:");
|
||||
Trolls[index].AddFlag("Honk", true);
|
||||
Trolls[index].AddFlag("Meow", false);
|
||||
Trolls[index].AddCustomFlagPrompt("Choose Chat modifier:", false, 1);
|
||||
Trolls[index].AddFlag("Show Modified to Them", true);
|
||||
Trolls[index].AddFlag("Show Original to Them", false);
|
||||
SetupTroll("Reversed", "Reserves their message", TrollMod_Constant);
|
||||
SetupTroll("Reversed", "Reserves their message", TrollMod_Constant | TrollMod_PlayerOnly);
|
||||
|
||||
SetCategory("Health");
|
||||
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("KillMeSoftly", "Make player eat or waste pills whenever possible", TrollMod_Instant | TrollMod_Constant);
|
||||
index = SetupTroll("Reverse FF", "All damage dealt to a player is reversed", TrollMod_Constant, false);
|
||||
index = SetupTroll("Reverse FF", "All damage dealt to a player is reversed", TrollMod_Constant);
|
||||
Trolls[index].AddCustomFlagPrompt("Choose Reverse FF", false);
|
||||
Trolls[index].AddFlag("1:1 Ratio", true);
|
||||
Trolls[index].AddFlag("2x Ratio", false);
|
||||
|
@ -76,9 +77,15 @@ void SetupTrolls() {
|
|||
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("No Shove", "Prevents a player from shoving", TrollMod_Constant);
|
||||
SetupTroll("CameTooEarly", "When they shoot, random chance they empty whole clip", TrollMod_Constant);
|
||||
SetupTroll("Inverted Controls", "Well, aint it obvious", TrollMod_Constant);
|
||||
SetupTroll("CameTooEarly", "When they shoot, random chance they empty whole clip", TrollMod_Constant | TrollMod_PlayerOnly);
|
||||
SetupTroll("Inverted Controls", "Well, aint it obvious", TrollMod_Constant | TrollMod_PlayerOnly);
|
||||
SetupTroll("Stagger", "Like a slap, but different", TrollMod_Instant);
|
||||
index = SetupTroll("Meta: Inverse", "Uhm you are not supposed to see this...", TrollMod_Instant | TrollMod_PlayerOnly);
|
||||
Trolls[index].hidden = true;
|
||||
Trolls[index].AddFlagPrompt(false);
|
||||
Trolls[index].AddFlag("100%", true);
|
||||
Trolls[index].AddFlag("50%", false);
|
||||
Trolls[index].AddFlag("10%", false);
|
||||
//INFO: UP MAX_TROLLS when adding new trolls!
|
||||
|
||||
|
||||
|
@ -142,13 +149,13 @@ bool ApplyAffect(int victim, const Troll troll, int activator, trollModifier mod
|
|||
//TODO: Implement TrollMod_Constant
|
||||
return false;
|
||||
} else if(StrEqual(troll.name, "Throw It All")) {
|
||||
if(modifier == TrollMod_Instant)
|
||||
if(modifier & TrollMod_Instant)
|
||||
ThrowAllItems(victim);
|
||||
if(hThrowTimer == INVALID_HANDLE && modifier == TrollMod_Constant) {
|
||||
if(hThrowTimer == INVALID_HANDLE && modifier & TrollMod_Constant) {
|
||||
hThrowTimer = CreateTimer(hThrowItemInterval.FloatValue, Timer_ThrowTimer, _, TIMER_REPEAT);
|
||||
}
|
||||
} else if(StrEqual(troll.name, "Swarm")) {
|
||||
if(modifier == TrollMod_Instant) {
|
||||
if(modifier & TrollMod_Instant) {
|
||||
L4D2_RunScript("RushVictim(GetPlayerFromUserID(%d), %d)", victim, 15000);
|
||||
}
|
||||
return true;
|
||||
|
@ -163,10 +170,10 @@ bool ApplyAffect(int victim, const Troll troll, int activator, trollModifier mod
|
|||
} else if(StrEqual(troll.name, "Vomit Player"))
|
||||
L4D_CTerrorPlayer_OnVomitedUpon(victim, victim);
|
||||
else if(StrEqual(troll.name, "Inface Special")) {
|
||||
FakeClientCommand(victim, "sm_inface");
|
||||
FakeClientCommand(activator, "sm_inface");
|
||||
return false;
|
||||
} else if(StrEqual(troll.name, "Insta Special")) {
|
||||
FakeClientCommand(victim, "sm_insta");
|
||||
FakeClientCommand(activator, "sm_insta");
|
||||
return false;
|
||||
} else if(StrEqual(troll.name, "Goo")) {
|
||||
static float pos[3], ang[3];
|
||||
|
|
|
@ -38,14 +38,16 @@ public void OnPluginStart() {
|
|||
SetFailState("This plugin is for L4D/L4D2 only.");
|
||||
}
|
||||
LoadTranslations("common.phrases");
|
||||
g_iAmmoTable = FindSendPropInfo("CTerrorPlayer", "m_iAmmo");
|
||||
|
||||
g_PlayerMarkedForward = new GlobalForward("FTT_OnClientMarked", ET_Ignore, Param_Cell, Param_Cell);
|
||||
|
||||
// Load core things (trolls & phrases):
|
||||
REPLACEMENT_PHRASES = new StringMap();
|
||||
LoadPhrases();
|
||||
SetupTrolls();
|
||||
|
||||
// Witch target overwrite stuff:
|
||||
|
||||
GameData data = new GameData("l4d2_behavior");
|
||||
|
||||
StartPrepSDKCall(SDKCall_Raw);
|
||||
|
@ -60,9 +62,8 @@ public void OnPluginStart() {
|
|||
hAutoPunish = CreateConVar("sm_ftt_autopunish_action", "0", "Setup automatic punishment of players. Add bits together\n0=Disabled, 1=Tank magnet, 2=Special magnet, 4=Swarm, 8=InstantVomit", FCVAR_NONE, true, 0.0);
|
||||
hAutoPunishExpire = CreateConVar("sm_ftt_autopunish_expire", "0", "How many minutes of gametime until autopunish is turned off? 0 for never.", FCVAR_NONE, true, 0.0);
|
||||
hMagnetChance = CreateConVar("sm_ftt_magnet_chance", "1.0", "% of the time that the magnet will work on a player.", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hMagnetTargetMode = CreateConVar("sm_ftt_magnet_targetting", "1", "How does the specials target players. Add bits together\n0= Target until Dead, 1=Specials ignore incapped, 2=Tank ignores incapped");
|
||||
hMagnetTargetMode = CreateConVar("sm_ftt_magnet_targetting", "6", "How does the specials target players. Add bits together\n0=Incapped are ignored, 1=Specials targets incapped, 2=Tank targets incapped 4=Witch targets incapped");
|
||||
hShoveFailChance = CreateConVar("sm_ftt_shove_fail_chance", "0.65", "The % chance that a shove fails", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hWitchTargetIncapp = CreateConVar("sm_ftt_witch_target_incapped", "1", "Should the witch target witch magnet victims who are incapped?\n 0 = No, 1 = Yes", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hBadThrowHitSelf = CreateConVar("sm_ftt_badthrow_fail_chance", "1", "The % chance that on a throw, they will instead hit themselves. 0 to disable", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
|
||||
RegAdminCmd("sm_ftl", Command_ListTheTrolls, ADMFLAG_KICK, "Lists all the trolls currently ingame.");
|
||||
|
@ -77,7 +78,9 @@ public void OnPluginStart() {
|
|||
RegAdminCmd("sm_insta", Command_InstaSpecial, ADMFLAG_KICK, "Spawns a special that targets them, close to them.");
|
||||
RegAdminCmd("sm_instaface", Command_InstaSpecialFace, ADMFLAG_KICK, "Spawns a special that targets them, right in their face.");
|
||||
RegAdminCmd("sm_inface", Command_InstaSpecialFace, ADMFLAG_KICK, "Spawns a special that targets them, right in their face.");
|
||||
RegAdminCmd("sm_noob", Command_MarkNoob, ADMFLAG_KICK, "Marks a player as a noob. stored in a database");
|
||||
|
||||
HookEvent("player_spawn", Event_PlayerSpawn);
|
||||
HookEvent("player_disconnect", Event_PlayerDisconnect);
|
||||
HookEvent("player_death", Event_PlayerDeath);
|
||||
HookEvent("triggered_car_alarm", Event_CarAlarm);
|
||||
|
@ -86,6 +89,8 @@ public void OnPluginStart() {
|
|||
AddNormalSoundHook(view_as<NormalSHook>(SoundHook));
|
||||
|
||||
AutoExecConfig(true, "l4d2_feedthetrolls");
|
||||
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CVAR CHANGES
|
||||
|
@ -103,11 +108,12 @@ public void Change_ThrowInterval(ConVar convar, const char[] oldValue, const cha
|
|||
// METHODS - Old methods, some are also in feedthetrolls/misc.inc
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void ThrowAllItems(int victim) {
|
||||
float vicPos[3], destPos[3];
|
||||
int clients[4];
|
||||
GetClientAbsOrigin(victim, vicPos);
|
||||
//Find a bot to throw to
|
||||
//Find a survivor to throw to (grabs the first nearest non-self survivor)
|
||||
int clientCount = GetClientsInRange(vicPos, RangeType_Visibility, clients, sizeof(clients));
|
||||
for(int i = 0; i < clientCount; i++) {
|
||||
if(clients[i] != victim) {
|
||||
|
@ -126,7 +132,6 @@ void ThrowAllItems(int victim) {
|
|||
WritePackFloat(pack, destPos[2]);
|
||||
WritePackCell(pack, slot);
|
||||
WritePackCell(pack, victim);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,18 +169,15 @@ bool IsPlayerFarDistance(int client, float distance) {
|
|||
|
||||
stock int GetPrimaryReserveAmmo(int client) {
|
||||
int weapon = GetPlayerWeaponSlot(client, 0);
|
||||
if(weapon > -1) {
|
||||
int primaryAmmoType = GetEntProp(weapon, Prop_Send, "m_iPrimaryAmmoType");
|
||||
return GetEntData(client, g_iAmmoTable + (primaryAmmoType * 4));
|
||||
if(weapon > 0) {
|
||||
return GetEntProp(client, Prop_Send, "m_iAmmo", _, GetEntProp(weapon, Prop_Send, "m_iPrimaryAmmoType"));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
stock bool SetPrimaryReserveAmmo(int client, int amount) {
|
||||
int weapon = GetPlayerWeaponSlot(client, 0);
|
||||
if(weapon > -1) {
|
||||
int primaryAmmoType = GetEntProp(weapon, Prop_Send, "m_iPrimaryAmmoType");
|
||||
SetEntData(client, g_iAmmoTable + (primaryAmmoType * 4), amount);
|
||||
return true;
|
||||
SetEntProp(client, Prop_Send, "m_iAmmo", amount, _, GetEntProp(weapon, Prop_Send, "m_iPrimaryAmmoType"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue