mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-05 20:33:20 +00:00
ftt: Upgrade to categories / minor improvements
This commit is contained in:
parent
32dace5bf6
commit
f756ec3100
11 changed files with 397 additions and 92 deletions
Binary file not shown.
|
@ -1,6 +1,6 @@
|
|||
|
||||
#define MAX_TROLL_NAME_LENGTH 32
|
||||
#define MAX_TROLLS 25
|
||||
#define MAX_TROLLS 28
|
||||
//#define DEBUG 1
|
||||
|
||||
enum trollModifier {
|
||||
|
@ -11,14 +11,17 @@ enum trollModifier {
|
|||
|
||||
|
||||
enum struct Troll {
|
||||
char name[32];
|
||||
char name[MAX_TROLL_NAME_LENGTH];
|
||||
char description[128];
|
||||
|
||||
bool runsOnce;
|
||||
int flags;
|
||||
int categoryID;
|
||||
|
||||
void GetID(char[] name, int length) {
|
||||
strcopy(name, length, this.name);
|
||||
char _id[MAX_TROLL_NAME_LENGTH];
|
||||
|
||||
void GetID(char[] name) {
|
||||
strcopy(name, MAX_TROLL_NAME_LENGTH, this.name);
|
||||
ReplaceString(name, MAX_TROLL_NAME_LENGTH, " ", "", false);
|
||||
}
|
||||
|
||||
|
@ -33,6 +36,10 @@ enum struct Troll {
|
|||
else if(this.flags == view_as<int>(TrollMod_Constant)) return TrollMod_Constant;
|
||||
else return TrollMod_Invalid;
|
||||
}
|
||||
|
||||
void Activate(int victim, int activator, trollModifier modifier, bool silent = false) {
|
||||
ApplyTroll(victim, this._id, activator, modifier, silent);
|
||||
}
|
||||
}
|
||||
|
||||
Troll Trolls[MAX_TROLLS+1];
|
||||
|
@ -50,7 +57,8 @@ void ResetClient(int victim, bool wipe = true) {
|
|||
if(wpn > -1)
|
||||
SDKUnhook(wpn, SDKHook_Reload, Event_WeaponReload);
|
||||
}
|
||||
|
||||
ArrayList categories;
|
||||
static int categoryID = 0;
|
||||
int SetupTroll(const char[] name, const char description[128], int flags) {
|
||||
if(flags == 0) {
|
||||
ThrowError("Troll \"%s\" has no flags defined.", name);
|
||||
|
@ -59,11 +67,13 @@ 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].categoryID = categoryID;
|
||||
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);
|
||||
strcopy(trollIds[i], MAX_TROLL_NAME_LENGTH, key);
|
||||
strcopy(Trolls[i]._id, MAX_TROLL_NAME_LENGTH, key);
|
||||
trollKV.SetValue(key, i);
|
||||
return i++;
|
||||
}
|
||||
|
@ -110,7 +120,9 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
victim = FindIdlePlayerBot(victim);
|
||||
}
|
||||
|
||||
ApplyAffect(victim, name, activator, modifier);
|
||||
if(!ApplyAffect(victim, name, activator, modifier)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!silent) {
|
||||
if(IsTrollActive(victim, name)) {
|
||||
|
@ -127,11 +139,11 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
}
|
||||
}
|
||||
|
||||
void ApplyAffect(int victim, const char[] name, int activator, trollModifier modifier) {
|
||||
bool ApplyAffect(int victim, const char[] name, int activator, trollModifier modifier) {
|
||||
if(StrEqual(name, "ResetTroll")) {
|
||||
ShowActivity(activator, "reset troll effects for %N. ", victim);
|
||||
ActiveTrolls[victim] = 0;
|
||||
return;
|
||||
return false;
|
||||
} else if(StrEqual(name, "SlowSpeed"))
|
||||
SetEntPropFloat(victim, Prop_Send, "m_flLaggedMovementValue", 0.8);
|
||||
else if(StrEqual(name, "HigherGravity"))
|
||||
|
@ -151,26 +163,6 @@ void ApplyAffect(int victim, const char[] name, int activator, trollModifier mod
|
|||
DisableTroll(victim, "UziRules");
|
||||
DisableTroll(victim, "PrimaryDisable");
|
||||
SDKHook(victim, SDKHook_WeaponCanUse, Event_ItemPickup);
|
||||
} else if(StrEqual(name, "Clumsy")) {
|
||||
int wpn = GetClientSecondaryWeapon(victim);
|
||||
bool hasMelee = DoesClientHaveMelee(victim);
|
||||
if(hasMelee) {
|
||||
float pos[3];
|
||||
int clients[4];
|
||||
GetClientAbsOrigin(victim, pos);
|
||||
int clientCount = GetClientsInRange(pos, RangeType_Visibility, clients, sizeof(clients));
|
||||
for(int i = 0; i < clientCount; i++) {
|
||||
if(clients[i] != victim) {
|
||||
float targPos[3];
|
||||
GetClientAbsOrigin(clients[i], targPos);
|
||||
SDKHooks_DropWeapon(victim, wpn, targPos);
|
||||
// g_iTrollUsers[victim] = mode;
|
||||
CreateTimer(0.2, Timer_GivePistol);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SDKHooks_DropWeapon(victim, wpn);
|
||||
}
|
||||
} else if(StrEqual(name, "CameTooEarly")) {
|
||||
ReplyToCommand(activator, "This troll mode is not implemented.");
|
||||
} else if(StrEqual(name, "KillMeSoftly")) {
|
||||
|
@ -181,10 +173,10 @@ void ApplyAffect(int victim, const char[] name, int activator, trollModifier mod
|
|||
g_bPendingItemGive[victim] = true;
|
||||
}else{
|
||||
ReplyToCommand(activator, "User does not have pills or adrenaline");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
//TODO: Implement TrollMod_Constant
|
||||
return;
|
||||
return false;
|
||||
} else if(StrEqual(name, "ThrowItAll")) {
|
||||
if(modifier == TrollMod_Instant)
|
||||
ThrowAllItems(victim);
|
||||
|
@ -198,7 +190,7 @@ void ApplyAffect(int victim, const char[] name, int activator, trollModifier mod
|
|||
|
||||
}else{
|
||||
ReplyToCommand(activator, "Invalid modifier for mode.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
} else if(StrEqual(name, "GunJam")) {
|
||||
int wpn = GetClientWeaponEntIndex(victim, 0);
|
||||
|
@ -208,12 +200,19 @@ void ApplyAffect(int victim, const char[] name, int activator, trollModifier mod
|
|||
ReplyToCommand(activator, "Victim does not have a primary weapon.");
|
||||
} else if(StrEqual(name, "VomitPlayer"))
|
||||
L4D_CTerrorPlayer_OnVomitedUpon(victim, victim);
|
||||
else {
|
||||
else if(StrEqual(name, "InfaceSpecial")) {
|
||||
FakeClientCommand(victim, "sm_inface");
|
||||
return false;
|
||||
} else if(StrEqual(name, "InstaSpecial")) {
|
||||
FakeClientCommand(victim, "sm_insta");
|
||||
return false;
|
||||
} else {
|
||||
#if defined DEBUG
|
||||
PrintToServer("[FTT] Possibly invalid troll, no action: %s", name);
|
||||
ReplyToCommand(activator, "[FTT/Debug] If nothing occurs, this troll possibly was not implemented correctly. ");
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsTrollActive(int client, const char[] troll) {
|
||||
|
@ -238,34 +237,53 @@ void DisableTroll(int client, const char[] troll) {
|
|||
}
|
||||
}
|
||||
|
||||
void SetCategory(const char[] newCat) {
|
||||
categoryID = categories.PushString(newCat);
|
||||
}
|
||||
void GetCategory(int category, char[] buffer, int size) {
|
||||
categories.GetString(category, buffer, size);
|
||||
}
|
||||
|
||||
void SetupTrolls() {
|
||||
trollKV = new StringMap();
|
||||
categories = new ArrayList(ByteCountToCells(16));
|
||||
SetupTroll("Reset Troll", "Resets the user, removes all troll effects", TrollMod_Instant);
|
||||
|
||||
SetCategory("Magnet / Horde");
|
||||
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("Swarm", "Swarms a player with zombies. Requires swarm plugin", TrollMod_Instant | TrollMod_Constant);
|
||||
SetupTroll("Vomit Player", "Shortcut to sm_vomitplayer. vomits the player.", TrollMod_Instant);
|
||||
SetupTroll("Throw It All", "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("Primary Disable", "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("Gun Jam", "On reload, small chance their gun gets jammed - Can't reload.", TrollMod_Constant);
|
||||
SetupTroll("Inface Special", "Shortcut to sm_inface", TrollMod_Instant);
|
||||
SetupTroll("Insta Special", "Shortcut to sm_insta", TrollMod_Instant);
|
||||
|
||||
SetCategory("Items");
|
||||
SetupTroll("Throw It All", "Player throws their item(s) periodically to a nearby player", TrollMod_Instant);
|
||||
SetupTroll("Bad Throw", "Player drops throwables on throw, and biles/molotovs themselves", TrollMod_Constant);
|
||||
SetupTroll("No Pickup", "Prevents a player from picking up ANY (new) item. Use ThrowItAll to make them drop", TrollMod_Constant);
|
||||
SetupTroll("UziRules", "Picking up a weapon gives them a UZI instead", TrollMod_Constant);
|
||||
SetupTroll("Primary Disable", "Player cannot pickup any weapons, only melee/pistols", TrollMod_Constant);
|
||||
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_Instant);
|
||||
SetupTroll("No Profanity", "Replaces some words with random phrases", TrollMod_Constant);
|
||||
SetupTroll("Vocalize Gag", "Prevents player from sending any vocalizations (even automatic)", TrollMod_Constant);
|
||||
SetupTroll("Honk", "Honk", TrollMod_Constant);
|
||||
SetupTroll("No Shove", "Prevents a player from shoving", TrollMod_Constant);
|
||||
SetupTroll("Meow", "Makes the player meow", TrollMod_Constant);
|
||||
|
||||
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);
|
||||
|
||||
SetCategory("Misc");
|
||||
SetupTroll("Gun Jam", "On reload, small chance their gun gets jammed - Can't reload.", 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("No Shove", "Prevents a player from shoving", TrollMod_Constant);
|
||||
SetupTroll("CameTooEarly", "When they shoot, random chance they empty whole clip", TrollMod_Constant);
|
||||
SetupTroll("Meow", "Makes the player meow", TrollMod_Constant);
|
||||
//INFO: UP MAX_TROLLS when adding new trolls!
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
public Action Command_InstaSpecial(int client, int args) {
|
||||
if(args < 1) {
|
||||
Menu menu = new Menu(Insta_PlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
menu.SetTitle("InstaSpecial: 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];
|
||||
|
@ -59,7 +59,7 @@ public Action Command_InstaSpecial(int client, int args) {
|
|||
public Action Command_InstaSpecialFace(int client, int args) {
|
||||
if(args < 1) {
|
||||
Menu menu = new Menu(Insta_PlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
menu.SetTitle("Inface: 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];
|
||||
|
@ -201,7 +201,7 @@ public Action Command_ResetUser(int client, int args) {
|
|||
public Action Command_ApplyUser(int client, int args) {
|
||||
if(args < 2) {
|
||||
Menu menu = new Menu(ChoosePlayerHandler);
|
||||
menu.SetTitle("Choose a player");
|
||||
menu.SetTitle("Choose a player to troll");
|
||||
for(int i = 1; i < MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2) {
|
||||
static char userid[8], display[16];
|
||||
|
|
|
@ -12,6 +12,8 @@ public void OnMapStart() {
|
|||
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");
|
||||
PrecacheSound("weapons/ceda_jar/ceda_jar_explode.wav");
|
||||
PrecacheSound("weapons/molotov/molotov_detonate_1.wav");
|
||||
//CreateTimer(30.0, Timer_AutoPunishCheck, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
public void OnClientPutInServer(int client) {
|
||||
|
@ -219,7 +221,8 @@ public Action OnClientSayCommand(int client, const char[] command, const char[]
|
|||
int words = ExplodeString(sArgs, " ", strings, 32, MAX_PHRASE_LENGTH);
|
||||
for(int i = 0; i < words; i++) {
|
||||
//TODO: Check for valid working
|
||||
if((phrases = GetPhrasesArray(strings[i])) && phrases.Length > 0) {
|
||||
phrases = GetPhrasesArray(strings[i]);
|
||||
if(phrases != null && 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);
|
||||
|
@ -369,3 +372,47 @@ public Action Event_WitchVictimSet(Event event, const char[] name, bool dontBroa
|
|||
pack.WriteCell(witch);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEntityCreated(int entity, const char[] classname) {
|
||||
if(IsValidEntity(entity) && StrContains(classname, "_projectile", true) > -1 ) {
|
||||
RequestFrame(EntityCreateCallback, entity);
|
||||
}
|
||||
}
|
||||
void EntityCreateCallback(int entity) {
|
||||
if(!HasEntProp(entity, Prop_Send, "m_hOwnerEntity") || !IsValidEntity(entity)) return;
|
||||
static char class[16];
|
||||
|
||||
GetEntityClassname(entity, class, sizeof(class));
|
||||
int entOwner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
|
||||
if(entOwner > 0 && entOwner <= MaxClients && IsTrollActive(entOwner, "BadThrow")) {
|
||||
static float pos[3];
|
||||
GetClientEyePosition(entOwner, pos);
|
||||
if(StrContains(class, "vomitjar", true) > -1) {
|
||||
AcceptEntityInput(entity, "Kill");
|
||||
if(hBadThrowHitSelf.FloatValue > 0.0 && GetRandomFloat() > hBadThrowHitSelf.FloatValue) {
|
||||
L4D_CTerrorPlayer_OnVomitedUpon(entOwner, entOwner);
|
||||
EmitSoundToAll("weapons/ceda_jar/ceda_jar_explode.wav", entOwner);
|
||||
FindClosestClient(entOwner, false, pos);
|
||||
}
|
||||
SpawnItem("vomitjar", pos);
|
||||
} else if(StrContains(class, "molotov", true) > -1) {
|
||||
// Burn them if no one near :)
|
||||
if(hBadThrowHitSelf.FloatValue > 0.0 && GetRandomFloat() > hBadThrowHitSelf.FloatValue) {
|
||||
GetClientAbsOrigin(entOwner, pos);
|
||||
if(IsAnyPlayerNear(entOwner, 500.0)) {
|
||||
AcceptEntityInput(entity, "Kill");
|
||||
EmitSoundToAll("weapons/molotov/molotov_detonate_1.wav", entOwner);
|
||||
} else { // or delete if there is
|
||||
TeleportEntity(entity, pos, NULL_VECTOR, NULL_VECTOR);
|
||||
}
|
||||
} else {
|
||||
SpawnItem("molotov", pos);
|
||||
AcceptEntityInput(entity, "Kill");
|
||||
}
|
||||
} else if(StrContains(class, "pipe_bomb", true) > -1) {
|
||||
if(hBadThrowHitSelf.FloatValue > 0.0 && GetRandomFloat() > hBadThrowHitSelf.FloatValue)
|
||||
TeleportEntity(entity, pos, NULL_VECTOR, NULL_VECTOR);
|
||||
SpawnItem("pipe_bomb", pos);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,9 +13,8 @@ public int Insta_PlayerHandler(Menu menu, MenuAction action, int client, int par
|
|||
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]);
|
||||
Format(info, sizeof(info), "%d|%d|%d", userid, instaMode, i);
|
||||
spMenu.AddItem(info, SPECIAL_NAMES[i-1]);
|
||||
}
|
||||
spMenu.ExitButton = true;
|
||||
spMenu.Display(client, 0);
|
||||
|
@ -58,21 +57,42 @@ public int ChooseMarkedTroll(Menu menu, MenuAction action, int activator, int pa
|
|||
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];
|
||||
static char info[8];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
int userid = StringToInt(info);
|
||||
|
||||
SetupCategoryMenu(param1, userid);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public int ChooseCategoryHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[32];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[2][8];
|
||||
ExplodeString(info, "|", str, 2, 8, false);
|
||||
int userid = StringToInt(str[0]);
|
||||
int category = StringToInt(str[1]);
|
||||
|
||||
Menu trollMenu = new Menu(ChooseModeMenuHandler);
|
||||
trollMenu.SetTitle("Choose a troll mode");
|
||||
GetCategory(category, info, sizeof(info));
|
||||
Format(info, sizeof(info), "Category: %s", info);
|
||||
trollMenu.SetTitle(info);
|
||||
//TODO: Update
|
||||
static char id[8];
|
||||
static Troll troll;
|
||||
for(int i = 0; i <= MAX_TROLLS; i++) {
|
||||
|
||||
// add 'return' btn
|
||||
Format(info, sizeof(info), "%d|-1", userid);
|
||||
trollMenu.AddItem(info, "<= Go Back");
|
||||
|
||||
// Add all menus that have same category
|
||||
for(int i = 0; i < trollKV.Size; i++) {
|
||||
GetTrollByKeyIndex(i, troll);
|
||||
// int trollIndex = GetTrollByKeyIndex(i, troll);
|
||||
// Pass key index
|
||||
Format(id, sizeof(id), "%d|%d", userid, i);
|
||||
trollMenu.AddItem(id, troll.name);
|
||||
if(troll.categoryID == category) {
|
||||
Format(info, sizeof(info), "%d|%d", userid, i);
|
||||
trollMenu.AddItem(info, troll.name);
|
||||
}
|
||||
}
|
||||
trollMenu.ExitButton = true;
|
||||
trollMenu.Display(param1, 0);
|
||||
|
@ -81,7 +101,6 @@ public int ChoosePlayerHandler(Menu menu, MenuAction action, int param1, int par
|
|||
}
|
||||
|
||||
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));
|
||||
|
@ -90,21 +109,44 @@ public int ChooseModeMenuHandler(Menu menu, MenuAction action, int param1, int p
|
|||
int userid = StringToInt(str[0]);
|
||||
int client = GetClientOfUserId(userid);
|
||||
int keyIndex = StringToInt(str[1]);
|
||||
if(keyIndex == -1) {
|
||||
SetupCategoryMenu(param1, userid);
|
||||
return;
|
||||
}
|
||||
static Troll troll;
|
||||
static char trollID[MAX_TROLL_NAME_LENGTH];
|
||||
GetTrollByKeyIndex(keyIndex, troll);
|
||||
troll.GetID(trollID, MAX_TROLL_NAME_LENGTH);
|
||||
troll.GetID(trollID);
|
||||
//If troll has multiple flags, prompt:
|
||||
if(troll.HasMod(TrollMod_Instant) && troll.HasMod(TrollMod_Constant)) {
|
||||
if(StrEqual(trollID, "ThrowItAll")) {
|
||||
// Setup menu to call itself, but with an extra data point
|
||||
Menu itmMenu = new Menu(ChooseClumsySlotHandler);
|
||||
itmMenu.SetTitle("Choose Item To Throw");
|
||||
|
||||
static char itmName[32];
|
||||
Format(info, sizeof(info), "%d|-1", userid);
|
||||
itmMenu.AddItem(info, "All Items");
|
||||
for(int slot = 0; slot <= 4; slot++) {
|
||||
int item = GetPlayerWeaponSlot(client, slot);
|
||||
if(item > -1) {
|
||||
GetEdictClassname(item, itmName, sizeof(itmName));
|
||||
Format(info, sizeof(info), "%d|%d", userid, slot);
|
||||
itmMenu.AddItem(info, itmName[7]);
|
||||
}
|
||||
}
|
||||
itmMenu.ExitButton = true;
|
||||
itmMenu.Display(param1, 0);
|
||||
} else if(troll.HasMod(TrollMod_Instant) && troll.HasMod(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");
|
||||
|
||||
Format(info, sizeof(info), "%d|%d|1", userid, keyIndex);
|
||||
modiferMenu.AddItem(info, "Activate once");
|
||||
Format(info, sizeof(info), "%d|%d|2", userid, keyIndex);
|
||||
modiferMenu.AddItem(info, "Activate Periodically");
|
||||
Format(info, sizeof(info), "%d|%d|3", userid, keyIndex);
|
||||
modiferMenu.AddItem(info, "Activate Periodically & Instantly");
|
||||
|
||||
modiferMenu.ExitButton = true;
|
||||
modiferMenu.Display(param1, 0);
|
||||
} else {
|
||||
|
@ -114,6 +156,27 @@ public int ChooseModeMenuHandler(Menu menu, MenuAction action, int param1, int p
|
|||
delete menu;
|
||||
}
|
||||
|
||||
public int ChooseClumsySlotHandler(Menu menu, MenuAction action, int param1, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
static char info[8];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
static char str[2][8];
|
||||
ExplodeString(info, "|", str, 2, 8, false);
|
||||
int client = GetClientOfUserId(StringToInt(str[0]));
|
||||
int slot = StringToInt(str[1]);
|
||||
PrintToChatAll("%d", slot);
|
||||
if(slot == -1) {
|
||||
for(int i = 0; i <= 4; i++) {
|
||||
ThrowItemToClosestPlayer(client, i);
|
||||
}
|
||||
} else {
|
||||
ThrowItemToClosestPlayer(client, slot);
|
||||
}
|
||||
ShowActivity(param1, "activated troll \"Throw It All\" for %N. ", client);
|
||||
} 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];
|
||||
|
@ -122,15 +185,17 @@ public int ChooseTrollModiferHandler(Menu menu, MenuAction action, int param1, i
|
|||
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 flags = StringToInt(str[2]);
|
||||
|
||||
static Troll troll;
|
||||
GetTrollByKeyIndex(keyIndex, troll);
|
||||
|
||||
if(flags == 1 || flags == 3)
|
||||
ApplyTroll(client, trollID, param1, TrollMod_Instant);
|
||||
troll.Activate(client, param1, TrollMod_Instant);
|
||||
// ApplyTroll(client, trollID, param1, TrollMod_Instant);
|
||||
if(flags == 2 || flags == 3)
|
||||
ApplyTroll(client, trollID, param1, TrollMod_Constant);
|
||||
troll.Activate(client, param1, TrollMod_Constant);
|
||||
// ApplyTroll(client, trollID, param1, TrollMod_Constant);
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
@ -138,3 +203,16 @@ public int ChooseTrollModiferHandler(Menu menu, MenuAction action, int param1, i
|
|||
public void StopItemGive(int client) {
|
||||
g_bPendingItemGive[client] = false;
|
||||
}
|
||||
|
||||
void SetupCategoryMenu(int client, int victimUserID) {
|
||||
Menu categoryMenu = new Menu(ChooseCategoryHandler);
|
||||
categoryMenu.SetTitle("Choose a troll category");
|
||||
static char category[16], id[8];
|
||||
for(int i = 0; i < categories.Length; i++) {
|
||||
categories.GetString(i, category, sizeof(category));
|
||||
Format(id, sizeof(id), "%d|%d", victimUserID, i);
|
||||
categoryMenu.AddItem(id, category);
|
||||
}
|
||||
categoryMenu.ExitButton = true;
|
||||
categoryMenu.Display(client, 0);
|
||||
}
|
|
@ -116,6 +116,116 @@ ArrayList GetPhrasesArray(const char[] key) {
|
|||
keyLower[i] = CharToLower(key[i]);
|
||||
}
|
||||
ArrayList phrases;
|
||||
REPLACEMENT_PHRASES.GetValue(keyLower, phrases);
|
||||
if(REPLACEMENT_PHRASES.GetValue(keyLower, phrases)) {
|
||||
return phrases;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FindClosestClientAdminPriority(int source, bool ignoreBots, float pos[3]) {
|
||||
int c = FindClosestAdmin(source, ignoreBots, pos);
|
||||
if(c == -1) return FindClosestClient(source, ignoreBots, pos);
|
||||
else return c;
|
||||
}
|
||||
|
||||
int FindClosestClient(int source, bool ignoreBots, float pos[3]) {
|
||||
int closest = -1;
|
||||
float minDist = -1.0;
|
||||
static float pos1[3];
|
||||
static float pos2[3];
|
||||
GetClientAbsOrigin(source, pos1);
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && (!ignoreBots || !IsFakeClient(i)) && i != source) {
|
||||
GetClientAbsOrigin(i, pos2);
|
||||
float dist = GetVectorDistance(pos1, pos2);
|
||||
if(minDist == -1.0 || dist <= minDist) {
|
||||
closest = i;
|
||||
minDist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
GetClientEyePosition(closest, pos);
|
||||
return closest;
|
||||
}
|
||||
|
||||
int FindClosestAdmin(int source, bool ignoreBots, float pos[3]) {
|
||||
int closest = -1;
|
||||
float minDist = -1.0;
|
||||
static float pos1[3];
|
||||
static float pos2[3];
|
||||
GetClientAbsOrigin(source, pos);
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && (|ignoreBots || !IsFakeClient(i)) && GetUserAdmin(i) != INVALID_ADMIN_ID && i != source) {
|
||||
GetClientAbsOrigin(i, pos2);
|
||||
float dist = GetVectorDistance(pos1, pos2);
|
||||
if(minDist == -1.0 || dist <= minDist) {
|
||||
closest = i;
|
||||
minDist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
GetClientEyePosition(closest, pos);
|
||||
return closest;
|
||||
}
|
||||
|
||||
int SpawnItem(const char[] entityName, float pos[3], float ang[3] = NULL_VECTOR) {
|
||||
static char classname[32];
|
||||
Format(classname, sizeof(classname), "weapon_%s", entityName);
|
||||
int spawner = CreateEntityByName(classname);
|
||||
if(spawner == -1) return -1;
|
||||
DispatchKeyValue(spawner, "solid", "6");
|
||||
// DispatchKeyValue(entity_weapon, "model", g_bLeft4Dead2 ? g_sWeaponModels2[model] : g_sWeaponModels[model]);
|
||||
DispatchKeyValue(spawner, "rendermode", "3");
|
||||
DispatchKeyValue(spawner, "disableshadows", "1");
|
||||
TeleportEntity(spawner, pos, ang, NULL_VECTOR);
|
||||
DispatchSpawn(spawner);
|
||||
TeleportEntity(spawner, pos, ang, NULL_VECTOR);
|
||||
return spawner;
|
||||
}
|
||||
|
||||
bool IsAnyPlayerNear(int source, float range) {
|
||||
static float pos1[3];
|
||||
static float pos2[3];
|
||||
GetClientAbsOrigin(source, pos1);
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && i != source) {
|
||||
GetClientAbsOrigin(i, pos2);
|
||||
float dist = GetVectorDistance(pos1, pos2);
|
||||
PrintToChatAll("%f <= %f: %b", dist, range, (dist <= range));
|
||||
if(dist <= range) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ThrowItemToClosestPlayer(int victim, int slot) {
|
||||
int wpn = GetPlayerWeaponSlot(victim, slot);
|
||||
if(slot != 1 || DoesClientHaveMelee(victim)) {
|
||||
static float pos[3];
|
||||
int clients[4];
|
||||
GetClientAbsOrigin(victim, pos);
|
||||
int clientCount = GetClientsInRange(pos, RangeType_Visibility, clients, sizeof(clients));
|
||||
for(int i = 0; i < clientCount; i++) {
|
||||
if(clients[i] != victim) {
|
||||
static float targPos[3];
|
||||
GetClientAbsOrigin(clients[i], targPos);
|
||||
SDKHooks_DropWeapon(victim, wpn, targPos);
|
||||
if(slot == 1)
|
||||
CreateTimer(0.2, Timer_GivePistol, GetClientUserId(victim));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No client found, drop on ground:
|
||||
SDKHooks_DropWeapon(victim, wpn, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
void DropItem(int victim, int slot) {
|
||||
int wpn = GetPlayerWeaponSlot(victim, slot);
|
||||
if(slot != 1 || DoesClientHaveMelee(victim)) {
|
||||
SDKHooks_DropWeapon(victim, wpn, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ bool SpawnSpecialNear(int target, int specialType) {
|
|||
if(specialType >= sizeof(SPECIAL_NAMES)) return false;
|
||||
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);
|
||||
int special = (specialType == 7) ? L4D2_SpawnWitch(pos, NULL_VECTOR) : L4D2_SpawnSpecial(specialType, pos, NULL_VECTOR);
|
||||
if(special == -1) return false;
|
||||
if(specialType == 7)
|
||||
SetWitchTarget(special, target);
|
||||
|
|
|
@ -42,11 +42,14 @@ public Action Timer_Main(Handle timer) {
|
|||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Timer_GivePistol(Handle timer, int client) {
|
||||
public Action Timer_GivePistol(Handle timer, int user) {
|
||||
int client = GetClientOfUserId(user);
|
||||
if(client > 0) {
|
||||
int flags = GetCommandFlags("give");
|
||||
SetCommandFlags("give", flags & ~FCVAR_CHEAT);
|
||||
FakeClientCommand(client, "give pistol");
|
||||
SetCommandFlags("give", flags|FCVAR_CHEAT);
|
||||
SetCommandFlags("give", flags);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_ThrowWeapon(Handle timer, Handle pack) {
|
||||
|
@ -67,7 +70,7 @@ public Action Timer_ThrowWeapon(Handle timer, Handle pack) {
|
|||
GetEdictClassname(wpn, name, sizeof(name));
|
||||
if(!StrEqual(name, "weapon_pistol", false)) {
|
||||
SDKHooks_DropWeapon(victim, wpn, dest);
|
||||
CreateTimer(0.2, Timer_GivePistol, victim);
|
||||
CreateTimer(0.2, Timer_GivePistol, GetClientUserId(victim));
|
||||
}
|
||||
}else
|
||||
SDKHooks_DropWeapon(victim, wpn, dest);
|
||||
|
|
|
@ -21,6 +21,7 @@ Handle g_hWitchAttack;
|
|||
Handle hThrowTimer;
|
||||
//CONVARS
|
||||
ConVar hVictimsList, hThrowItemInterval, hAutoPunish, hMagnetChance, hShoveFailChance, hAutoPunishExpire, hMagnetTargetMode, hWitchTargetIncapp;
|
||||
ConVar hBadThrowHitSelf;
|
||||
//BOOLS
|
||||
bool lateLoaded; //Is plugin late loaded
|
||||
bool bChooseVictimAvailable = false; //For charge player feature, is it available?
|
||||
|
@ -28,7 +29,7 @@ bool bChooseVictimAvailable = false; //For charge player feature, is it availabl
|
|||
int g_iAmmoTable; //Loads the ammo table to get ammo amounts
|
||||
int gChargerVictim = -1; //For charge player feature
|
||||
|
||||
float ZERO_VECTOR[3] = {0.0, 0.0, 0.0};
|
||||
|
||||
|
||||
#include <feedthetrolls/base>
|
||||
#include <feedthetrolls/specials>
|
||||
|
|
|
@ -67,6 +67,7 @@ public void OnPluginStart() {
|
|||
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");
|
||||
hShoveFailChance = CreateConVar("sm_ftt_shove_fail_chance", "0.5", "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.");
|
||||
RegAdminCmd("sm_ftm", Command_ListModes, ADMFLAG_KICK, "Lists all the troll modes and their description");
|
||||
|
@ -94,7 +95,6 @@ public void OnPluginStart() {
|
|||
HookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CVAR CHANGES
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -201,7 +201,7 @@ stock bool SetPrimaryReserveAmmo(int client, int amount) {
|
|||
}
|
||||
|
||||
stock void SendChatToAll(int client, const char[] message) {
|
||||
char nameBuf[MAX_NAME_LENGTH];
|
||||
static char nameBuf[MAX_NAME_LENGTH];
|
||||
|
||||
for (int i = 1; i <= MaxClients; i++) {
|
||||
if (IsClientInGame(i) && IsFakeClient(i)) {
|
||||
|
@ -213,7 +213,7 @@ stock void SendChatToAll(int client, const char[] message) {
|
|||
|
||||
stock float GetTempHealth(int client) {
|
||||
//First filter -> Must be a valid client, successfully in-game and not an spectator (The dont have health).
|
||||
if(!client || !IsValidEntity(client) || !IsClientInGame(client)|| !IsPlayerAlive(client) || IsClientObserver(client)) {
|
||||
if(client <= 0 || !IsValidEntity(client) || !IsClientInGame(client)|| !IsPlayerAlive(client) || IsClientObserver(client)) {
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
|
|
48
scripting/l4d2_forceset.sp
Normal file
48
scripting/l4d2_forceset.sp
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <left4dhooks>
|
||||
|
||||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
|
||||
ConVar g_cvSurvivorSet;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "[L4D2] Survivor Set Enforcer",
|
||||
author = "DeathChaos, modified by Psyk0tik (Crasher_3637)",
|
||||
description = "Forces L4D2 survivor set.",
|
||||
version = "1.0",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
g_cvSurvivorSet = CreateConVar("l4d_force_survivorset", "0", "Forces specified survivor set (0 - no change, 1 - force L4D1, 2 - Force L4D2)", _, true, 0.0, true, 2.0);
|
||||
}
|
||||
|
||||
public Action L4D_OnGetSurvivorSet(int &retVal)
|
||||
{
|
||||
int iSet = g_cvSurvivorSet.IntValue;
|
||||
if (iSet > 0)
|
||||
{
|
||||
retVal = iSet;
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action L4D_OnFastGetSurvivorSet(int &retVal)
|
||||
{
|
||||
int iSet = g_cvSurvivorSet.IntValue;
|
||||
if (iSet > 0)
|
||||
{
|
||||
retVal = iSet;
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue