mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 05:13:21 +00:00
ftt: Use a queue for special spawning
This commit is contained in:
parent
c3e43d744a
commit
d9241b2949
11 changed files with 329 additions and 158 deletions
Binary file not shown.
|
@ -4,7 +4,7 @@
|
|||
//Allow MAX_TROLLS to be defined elsewhere
|
||||
#if defined MAX_TROLLS
|
||||
#else
|
||||
#define MAX_TROLLS 34
|
||||
#define MAX_TROLLS 37
|
||||
#endif
|
||||
|
||||
enum trollModifier {
|
||||
|
@ -35,6 +35,10 @@ bool SilentMenuSelected[MAXPLAYERS+1];
|
|||
static int g_trollAddPromptIndex;
|
||||
ArrayList gRandomClients;
|
||||
|
||||
char SPECIAL_NAMES[][] = {
|
||||
"Smoker", "Boomer", "Hunter", "Spitter", "Jockey", "Charger", "Witch", "Tank"
|
||||
};
|
||||
|
||||
enum struct TrollFlagPrompt {
|
||||
char promptText[MAX_TROLL_FLAG_LENGTH];
|
||||
int flags;
|
||||
|
@ -53,6 +57,15 @@ enum struct TrollFlagPrompt {
|
|||
}
|
||||
}
|
||||
|
||||
int GetIndexFromPower(int powerOfTwo) {
|
||||
for(int i = 0; i < 16; i++) {
|
||||
if(1 << i == powerOfTwo) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
enum struct Troll {
|
||||
int id;
|
||||
int categoryID;
|
||||
|
@ -112,9 +125,11 @@ enum struct Troll {
|
|||
int AddFlag(const char[] name, bool defaultOn) {
|
||||
if(this.flagNames == null) this.flagNames = new ArrayList(MAX_TROLL_FLAG_LENGTH);
|
||||
|
||||
// Check if flag already added
|
||||
int flagIndex = this.GetFlagIndex(name);
|
||||
if(flagIndex == -1) flagIndex = this.flagNames.PushString(name);
|
||||
|
||||
// Grab the prompt
|
||||
static TrollFlagPrompt prompt;
|
||||
this.flagPrompts.GetArray(g_trollAddPromptIndex, prompt);
|
||||
|
||||
|
@ -346,20 +361,33 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
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 {
|
||||
static char flagName[MAX_TROLL_FLAG_LENGTH];
|
||||
if(flags > 0 && flags & flags - 1 == 0) {
|
||||
// Get the flag name if there is only one flag set
|
||||
troll.GetFlagName(GetIndexFromPower(flags), flagName, sizeof(flagName));
|
||||
}
|
||||
if(modifier & TrollMod_Constant) {
|
||||
if(flags > 0) {
|
||||
if(flagName[0] != '\0') {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated constant troll \"%s\" (%s) for %N. ", troll.name, flagName, victim);
|
||||
} else {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated constant troll \"%s\" (%d) for %N. ", troll.name, flags, victim);
|
||||
}
|
||||
} else
|
||||
ShowActivityEx(activator, "[FTT] ", "activated constant troll \"%s\" for %N. ", troll.name, victim);
|
||||
} else if(flags > 0)
|
||||
} else if(flags > 0) {
|
||||
if(flagName[0] != '\0') {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated troll \"%s\" (%s) for %N. ", troll.name, flagName, victim);
|
||||
} else {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated troll \"%s\" (%d) for %N. ", troll.name, flags, victim);
|
||||
else
|
||||
}
|
||||
} else
|
||||
ShowActivityEx(activator, "[FTT] ", "activated troll \"%s\" for %N. ", troll.name, victim);
|
||||
|
||||
LogAction(activator, victim, "\"%L\" activated troll \"%s\" (%d) for \"%L\"", activator, troll.name, flags, victim);
|
||||
}
|
||||
} else {
|
||||
ReplyToCommand(activator, "apply troll \"%s\" flags=%d on %N", troll.name, flags, victim);
|
||||
ReplyToCommand(activator, "ftt: Applied Troll \"%s\" on %N with flags=%d", troll.name, victim, flags);
|
||||
}
|
||||
// Toggle on flags for client, if it's not a single run.
|
||||
if(modifier & TrollMod_Constant) {
|
||||
|
|
|
@ -13,10 +13,6 @@ 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) {
|
||||
|
@ -49,7 +45,7 @@ public Action Command_InstaSpecial(int client, int args) {
|
|||
for (int i = 0; i < target_count; i++) {
|
||||
int target = target_list[i];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
if(SpawnSpecialNear(target, specialType)) {
|
||||
if(SpawnSpecialForTarget(specialType, target)) {
|
||||
LogAction(client, target, "\"%L\" spawned Insta-%s™ nearby \"%L\"", client, arg2, target);
|
||||
successes++;
|
||||
} else {
|
||||
|
@ -82,10 +78,6 @@ 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) {
|
||||
|
@ -118,7 +110,7 @@ public Action Command_InstaSpecialFace(int client, int args) {
|
|||
for (int i = 0; i < target_count; i++) {
|
||||
int target = target_list[i];
|
||||
if(GetClientTeam(target) == 2) {
|
||||
if(SpawnSpecialInFace(target, specialType)) {
|
||||
if(SpawnSpecialForTarget(specialType, target, Special_OnTarget)) {
|
||||
LogAction(client, target, "\"%L\" spawned Insta-%s™ at player \"%L\"", client, arg2, target);
|
||||
successes++;
|
||||
} else {
|
||||
|
|
|
@ -15,6 +15,9 @@ public void OnMapStart() {
|
|||
PrecacheSound("player/footsteps/clown/concrete1.wav");
|
||||
PrecacheSound("weapons/ceda_jar/ceda_jar_explode.wav");
|
||||
PrecacheSound("weapons/molotov/molotov_detonate_1.wav");
|
||||
|
||||
g_spSpawnQueue.Clear();
|
||||
spIsActive = false;
|
||||
//CreateTimer(30.0, Timer_AutoPunishCheck, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
public void OnClientPutInServer(int client) {
|
||||
|
@ -26,36 +29,47 @@ public void OnClientPutInServer(int client) {
|
|||
}
|
||||
public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||
int userid = event.GetInt("userid");
|
||||
if(spIsActive)
|
||||
CreateTimer(0.1, Timer_CheckSpecial, userid);
|
||||
}
|
||||
public void Event_DoorToggle(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client && Trolls[slipperyShoesIndex].IsActive(client) && Trolls[slipperyShoesIndex].activeFlagClients[client] & 2) {
|
||||
L4D_StaggerPlayer(client, client, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
public void Event_SecondaryHealthUsed(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client && Trolls[slipperyShoesIndex].IsActive(client) && Trolls[slipperyShoesIndex].activeFlagClients[client] & 8) {
|
||||
L4D_StaggerPlayer(client, client, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
public Action Timer_CheckSpecial(Handle h, int specialID) {
|
||||
int special = GetClientOfUserId(specialID);
|
||||
// Check if new player is the spawned special:
|
||||
if(special > 0 && gInstaSpecialType > -1 && IsFakeClient(special) && GetClientTeam(special) == 3) {
|
||||
int type = GetEntProp(special, Prop_Send, "m_zombieClass");
|
||||
// Verify type of special is spawned special
|
||||
if(type == gInstaSpecialType) {
|
||||
// Ignore 'ManualDirectorBot' or abm bots
|
||||
if(spIsActive && special > 0 && IsFakeClient(special) && GetClientTeam(special) == 3) {
|
||||
SpecialType type = view_as<SpecialType>(GetEntProp(special, Prop_Send, "m_zombieClass"));
|
||||
if(type == spActiveRequest.type) {
|
||||
// Ignore any fake clients with 'Bot' in name
|
||||
static char buf[32];
|
||||
GetClientName(special, buf, sizeof(buf));
|
||||
if(StrContains(buf, "bot", false) == -1) {
|
||||
gInstaSpecialType = -1;
|
||||
// Set special to only attack them:
|
||||
g_iAttackerTarget[special] = gInstaSpecialTarget;
|
||||
// Incremenet count of specials targetting player:
|
||||
gInstaSpecialMagnet[GetClientOfUserId(gInstaSpecialTarget)]++;
|
||||
if(spActiveRequest.targetUserId)
|
||||
g_iAttackerTarget[special] = spActiveRequest.targetUserId;
|
||||
gInstaSpecialMagnet[GetClientOfUserId(spActiveRequest.targetUserId)]++;
|
||||
|
||||
TeleportEntity(special, gInstaSpecialSpawnPos, gInstaSpecialSpawnAng, NULL_VECTOR);
|
||||
if(gInstaSpecialInstaKill) {
|
||||
TeleportEntity(special, spActiveRequest.position, spActiveRequest.angle, NULL_VECTOR);
|
||||
if(spActiveRequest.flags & view_as<int>(SPI_KillOnSpawn)) {
|
||||
RequestFrame(Frame_Boom, special);
|
||||
}
|
||||
|
||||
ProcessSpecialQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Frame_Boom(int special) {
|
||||
SDKHooks_TakeDamage(special, special, special, 1000.0);
|
||||
gInstaSpecialInstaKill = false;
|
||||
}
|
||||
public void Event_PlayerFirstSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
|
@ -136,6 +150,12 @@ public void Event_CarAlarm(Event event, const char[] name, bool dontBroadcast) {
|
|||
//Ignore car alarms for autopunish
|
||||
lastButtonUser = -1;
|
||||
}
|
||||
public void Event_EnteredSpit(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client) {
|
||||
g_iInSpit[client] = true;
|
||||
}
|
||||
}
|
||||
public Action RushPlayer(Handle h, int user) {
|
||||
L4D2_RunScript("RushVictim(GetPlayerFromUserID(%d), %d)", user, 15000);
|
||||
}
|
||||
|
@ -407,6 +427,11 @@ static char AWP[16] = "sniper_awp";
|
|||
public Action Event_ItemPickup(int client, int weapon) {
|
||||
static int NoPickupIndex;
|
||||
if(NoPickupIndex == 0) NoPickupIndex = GetTrollID("No Pickup");
|
||||
static int SpicyGasIndex;
|
||||
if(SpicyGasIndex == 0) SpicyGasIndex = GetTrollID("Spicy Gas");
|
||||
static int UziRulesIndex;
|
||||
if(UziRulesIndex == 0) UziRulesIndex = GetTrollID("UziRules / AwpSmells");
|
||||
|
||||
static char wpnName[64];
|
||||
if(Trolls[NoPickupIndex].IsActive(client)) {
|
||||
int flags = Trolls[NoPickupIndex].activeFlagClients[client];
|
||||
|
@ -425,9 +450,10 @@ public Action Event_ItemPickup(int client, int weapon) {
|
|||
} else if(flags & 16 && GetPlayerWeaponSlot(client, view_as<int>(L4DWeaponSlot_Pills)) == weapon) {
|
||||
// No Pills / Adr
|
||||
return Plugin_Handled;
|
||||
} else if(flags & 32 && GetEntityClassname(weapon, wpnName, sizeof(wpnName)) && StrEqual(wpnName, "weapon_gascan")) {
|
||||
return Plugin_Handled;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
} else {
|
||||
} else if(Trolls[UziRulesIndex].IsActive(client) || IsTrollActive(client, "Primary Disable")) {
|
||||
GetEdictClassname(weapon, wpnName, sizeof(wpnName));
|
||||
if(strcmp(wpnName[7], "rifle") >= 0
|
||||
|| strcmp(wpnName[7], "smg") >= 0
|
||||
|
@ -435,8 +461,6 @@ public Action Event_ItemPickup(int client, int weapon) {
|
|||
|| strcmp(wpnName[7], "sniper") > -1
|
||||
|| StrContains(wpnName, "shotgun") > -1
|
||||
) {
|
||||
static int UziRulesIndex;
|
||||
if(UziRulesIndex == 0) UziRulesIndex = GetTrollID("UziRules / AwpSmells");
|
||||
//If 4: Only UZI, if 5: Can't switch.
|
||||
if(Trolls[UziRulesIndex].IsActive(client)) {
|
||||
static char comp[16];
|
||||
|
@ -461,10 +485,23 @@ public Action Event_ItemPickup(int client, int weapon) {
|
|||
return Plugin_Stop;
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
} else if(Trolls[SpicyGasIndex].IsActive(client)) {
|
||||
PrintToChat(client, "spice active");
|
||||
if(GetEntityClassname(weapon, wpnName, sizeof(wpnName))) {
|
||||
float max = 1.0;
|
||||
if(Trolls[SpicyGasIndex].activeFlagClients[client] & 2) max = 0.5;
|
||||
else if(Trolls[SpicyGasIndex].activeFlagClients[client] & 4) max = 0.1;
|
||||
if(GetRandomFloat() <= max) {
|
||||
if(StrEqual(wpnName, "weapon_gascan")) {
|
||||
AcceptEntityInput(weapon, "Ignite", client, client);
|
||||
} else if(StrEqual(wpnName, "weapon_propanetank") || StrEqual(wpnName, "weapon_oxygentank")) {
|
||||
ExplodeProjectile(weapon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 'KillMeSoftly' activated:
|
||||
|
@ -529,17 +566,29 @@ public Action Event_TakeDamage(int victim, int& attacker, int& inflictor, float&
|
|||
//Stop FF from marked:
|
||||
static int reverseFF;
|
||||
if(reverseFF == 0) reverseFF = GetTrollID("Reverse FF");
|
||||
if(attacker > 0 && attacker <= MaxClients && GetClientTeam(attacker) == 4 && IsFakeClient(attacker)) return Plugin_Stop;
|
||||
if(attacker > 0 && attacker <= MaxClients && GetClientTeam(attacker) == 4 && IsFakeClient(attacker)) return Plugin_Continue;
|
||||
|
||||
if (victim > 0 && victim <= MaxClients && damagetype != 263168 && damagetype != 265216) {
|
||||
PrintToChat(victim, "you are in spit.");
|
||||
}
|
||||
|
||||
if(attacker > 0 && victim <= MaxClients && attacker <= MaxClients && IsClientInGame(attacker) && IsPlayerAlive(attacker)) {
|
||||
if(shootAtTarget[attacker] == victim) return Plugin_Continue;
|
||||
if(g_PendingBanTroll[attacker] > 0 && GetClientTeam(attacker) == 2 && GetClientTeam(victim) == 2) {
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(damage > 0.0 && victim != attacker && Trolls[slipperyShoesIndex].IsActive(victim) && Trolls[slipperyShoesIndex].activeFlagClients[victim] & 16) {
|
||||
L4D_StaggerPlayer(victim, victim, NULL_VECTOR);
|
||||
}
|
||||
|
||||
if(IsTrollActive(victim, "Damage Boost")) {
|
||||
damage * 2;
|
||||
return Plugin_Changed;
|
||||
} else if(Trolls[reverseFF].IsActive(attacker) && damagetype != DMG_BURN && attacker != victim && GetClientTeam(attacker) == GetClientTeam(victim)) {
|
||||
|
||||
float returnDmg = damage; //default is 1:1
|
||||
if(Trolls[reverseFF].activeFlagClients[attacker] & 4) {
|
||||
returnDmg /= 2.0;
|
||||
|
@ -668,9 +717,7 @@ void EntityCreateCallback(int entity) {
|
|||
static char class[16];
|
||||
|
||||
static int badThrowID;
|
||||
if(badThrowID == 0) {
|
||||
badThrowID = GetTrollID("Bad Throw");
|
||||
}
|
||||
if(badThrowID == 0) badThrowID = GetTrollID("Bad Throw");
|
||||
|
||||
GetEntityClassname(entity, class, sizeof(class));
|
||||
int entOwner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
|
||||
|
@ -701,10 +748,16 @@ void EntityCreateCallback(int entity) {
|
|||
AcceptEntityInput(entity, "Kill");
|
||||
}
|
||||
} else if(Trolls[badThrowID].IsFlagActive(entOwner, Flag_3) && StrContains(class, "pipe_bomb", true) > -1) {
|
||||
if(hBadThrowHitSelf.FloatValue > 0.0 && GetRandomFloat() <= hBadThrowHitSelf.FloatValue)
|
||||
if(hBadThrowHitSelf.FloatValue > 0.0 && GetRandomFloat() <= hBadThrowHitSelf.FloatValue) {
|
||||
TeleportEntity(entity, pos, NULL_VECTOR, NULL_VECTOR);
|
||||
ExplodeProjectile(entity);
|
||||
}
|
||||
SpawnItem("pipe_bomb", pos);
|
||||
}
|
||||
} else if(Trolls[slipperyShoesIndex].IsActive(entOwner)) {
|
||||
if(Trolls[slipperyShoesIndex].activeFlagClients[entOwner] & 4) {
|
||||
L4D_StaggerPlayer(entOwner, entOwner, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -738,13 +791,12 @@ public bool TraceEntityFilterPlayer(int entity, int mask, any data) {
|
|||
|
||||
float iLastAntiRushEvent[MAXPLAYERS+1];
|
||||
public Action OnAntiRush(int client, int &type, float distance) {
|
||||
PrintToConsoleAll("[FTT] Antirush: %N (dist=%d) (GameTime=%f)", client, distance, GetGameTime());
|
||||
if(type == 3 && IsPlayerAlive(client) && !IsPlayerIncapped(client)) {
|
||||
if(GetGameTime() - iLastAntiRushEvent[client] > 30.0) {
|
||||
SpecialType special = view_as<SpecialType>(GetRandomInt(0,6));
|
||||
SpecialType special = view_as<SpecialType>(GetRandomInt(1,6));
|
||||
iLastAntiRushEvent[client] = GetGameTime();
|
||||
SpawnSpecialNear(client, special);
|
||||
PrintToConsoleAll("[FTT] Spawning anti-rush special on %N (dist=%f) (special=%d)", client, distance, special);
|
||||
SpawnSpecialForTarget(special, client);
|
||||
PrintToConsoleAll("[FTT] Spawning anti-rush special on %N (dist=%f) (special=%N)", client, distance, SPECIAL_NAMES[view_as<int>(special)-1]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,14 +38,14 @@ public int Insta_SpecialHandler(Menu menu, MenuAction action, int client, int pa
|
|||
}
|
||||
SpecialType special = view_as<SpecialType>(specialInt);
|
||||
if(inFace) {
|
||||
if(SpawnSpecialInFace(target, special)) {
|
||||
if(SpawnSpecialForTarget(special, target, Special_OnTarget)) {
|
||||
LogAction(client, target, "\"%L\" spawned Insta-%s™ on \"%L\"", client, SPECIAL_NAMES[specialInt-1], target);
|
||||
ShowActivityEx(client, "[FTT] ", "spawned Insta-%s™ on %N", SPECIAL_NAMES[specialInt-1], target);
|
||||
} else {
|
||||
ReplyToCommand(client, "Could not spawn special.");
|
||||
}
|
||||
} else {
|
||||
if(SpawnSpecialNear(target, special)) {
|
||||
if(SpawnSpecialForTarget(special, target)) {
|
||||
LogAction(client, target, "\"%L\" spawned Insta-%s™ near \"%L\"", client, SPECIAL_NAMES[specialInt-1], target);
|
||||
ShowActivityEx(client, "[FTT] ", "spawned Insta-%s™ near %N", SPECIAL_NAMES[specialInt-1], target);
|
||||
} else {
|
||||
|
@ -488,7 +488,7 @@ void ShowThrowItAllMenu(int client, int userid) {
|
|||
}
|
||||
|
||||
// Grab all the items the player has, add to menu
|
||||
for(int slot = 0; slot <= 4; slot++) {
|
||||
for(int slot = 0; slot <= 5; slot++) {
|
||||
int item = GetPlayerWeaponSlot(victim, slot);
|
||||
if(item > -1) {
|
||||
GetEdictClassname(item, itmName, sizeof(itmName));
|
||||
|
|
|
@ -368,3 +368,11 @@ bool SetBotTarget(int bot, int target, int targetHP, int loops = 15) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from https://forums.alliedmods.net/showthread.php?t=220132&page=2
|
||||
stock void ExplodeProjectile(int entity) {
|
||||
SetEntProp(entity, Prop_Data, "m_takedamage", 2);
|
||||
SetEntProp(entity, Prop_Data, "m_iHealth", 1);
|
||||
SDKHooks_TakeDamage(entity, 0, 0, 1.0);
|
||||
SetEntProp(entity, Prop_Data, "m_nNextThinkTick", 1); //for smoke
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
char SPECIAL_NAMES[][] = {
|
||||
"Smoker", "Boomer", "Hunter", "Spitter", "Jockey", "Charger", "Witch", "Tank"
|
||||
};
|
||||
|
||||
enum SpecialType {
|
||||
Special_Invalid = -1,
|
||||
Special_Smoker = 1,
|
||||
|
@ -13,6 +11,104 @@ enum SpecialType {
|
|||
Special_Tank
|
||||
}
|
||||
|
||||
|
||||
enum struct SpecialSpawnRequest {
|
||||
SpecialType type;
|
||||
int targetUserId;
|
||||
float position[3];
|
||||
float angle[3];
|
||||
int flags;
|
||||
}
|
||||
|
||||
ArrayList g_spSpawnQueue;
|
||||
|
||||
// Finds position, sends to SpawnSpecialAtPosition
|
||||
// target client index
|
||||
stock bool SpawnSpecialForTarget(SpecialType specialType, int target, SpecialSpawnFlags spawnFlags = Special_Anywhere) {
|
||||
static float pos[3];
|
||||
int internalFlags = 0;
|
||||
if(spawnFlags == Special_OnTarget) {
|
||||
static float ang[3];
|
||||
static float testPos[3];
|
||||
testPos = pos;
|
||||
|
||||
GetClientAbsOrigin(target, pos);
|
||||
GetClientEyeAngles(target, ang);
|
||||
|
||||
if(specialType == Special_Boomer)
|
||||
internalFlags |= view_as<int>(SPI_KillOnSpawn);
|
||||
|
||||
if(specialType == Special_Jockey || specialType == Special_Boomer) { // Else spawn a little bit off, and above (above for jockeys)
|
||||
pos[2] += 25.0;
|
||||
pos[0] += 5.0;
|
||||
} else { //If not jockey/hunter find a suitable area that is at least 5 m away
|
||||
float minDistance = GetIdealMinDistance(specialType);
|
||||
GetHorizontalPositionFromOrigin(pos, ang, minDistance, testPos);
|
||||
if(!FindSuitablePosition(pos, testPos, minDistance, 100)) {
|
||||
L4D_GetRandomPZSpawnPosition(target, view_as<int>(specialType), 10, testPos);
|
||||
}
|
||||
pos = testPos;
|
||||
}
|
||||
pos[2] += 1.0;
|
||||
return SpawnSpecialAtPosition(specialType, pos, ang, target, internalFlags);
|
||||
} else {
|
||||
if(L4D_GetRandomPZSpawnPosition(target, view_as<int>(specialType), 10, pos)) {
|
||||
return SpawnSpecialAtPosition(specialType, pos, NULL_VECTOR, target, internalFlags);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Target is optional
|
||||
stock bool SpawnSpecialAtPosition(SpecialType special, const float destination[3], const float angle[3], int target = 0, int flags) {
|
||||
SpecialSpawnRequest request;
|
||||
request.type = special;
|
||||
if(target)
|
||||
request.targetUserId = GetClientUserId(target);
|
||||
request.flags = flags;
|
||||
request.position = destination;
|
||||
request.angle = angle;
|
||||
g_spSpawnQueue.PushArray(request);
|
||||
if(!spIsActive) ProcessSpecialQueue();
|
||||
return true;
|
||||
}
|
||||
|
||||
SpecialSpawnRequest spActiveRequest;
|
||||
|
||||
bool ProcessSpecialQueue() {
|
||||
if(g_spSpawnQueue.Length > 0) {
|
||||
if(g_spSpawnQueue.GetArray(0, spActiveRequest, sizeof(spActiveRequest))) {
|
||||
spIsActive = true;
|
||||
}
|
||||
g_spSpawnQueue.Erase(0);
|
||||
|
||||
int target = GetClientOfUserId(spActiveRequest.targetUserId);
|
||||
if(view_as<int>(spActiveRequest.type) <= 6) {
|
||||
// CreateTimer(2.0, Timer_CheckSpecialSpawn, spCurrentId);
|
||||
int bot = CreateFakeClient("FTTSpecialBot");
|
||||
if (bot != 0) {
|
||||
ChangeClientTeam(bot, 3);
|
||||
CreateTimer(0.1, Timer_KickBot, bot);
|
||||
}
|
||||
CheatCommand(target, "z_spawn_old", SPECIAL_NAMES[view_as<int>(spActiveRequest.type) - 1], "auto");
|
||||
} else if(spActiveRequest.type == Special_Witch) {
|
||||
int witch = L4D2_SpawnWitch(spActiveRequest.position, spActiveRequest.angle);
|
||||
if(witch != -1)
|
||||
SetWitchTarget(witch, target);
|
||||
return ProcessSpecialQueue();
|
||||
} else if(spActiveRequest.type == Special_Tank) {
|
||||
// BypassLimit();
|
||||
int tank = L4D2_SpawnTank(spActiveRequest.position, spActiveRequest.angle);
|
||||
if(tank > 0 && IsClientConnected(tank))
|
||||
g_iAttackerTarget[tank] = spActiveRequest.targetUserId;
|
||||
return ProcessSpecialQueue();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
spIsActive = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
stock SpecialType GetSpecialType(const char[] input) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(strcmp(SPECIAL_NAMES[i], input, false) == 0) return view_as<SpecialType>(i + 1);
|
||||
|
@ -47,85 +143,6 @@ float GetIdealMinDistance(SpecialType specialType) {
|
|||
}
|
||||
}
|
||||
|
||||
bool SpawnSpecialInFace(int target, SpecialType specialType) {
|
||||
static float pos[3], ang[3];
|
||||
static float testPos[3];
|
||||
testPos = pos;
|
||||
|
||||
GetClientAbsOrigin(target, pos);
|
||||
GetClientEyeAngles(target, ang);
|
||||
|
||||
if(specialType == Special_Boomer)
|
||||
gInstaSpecialInstaKill = true;
|
||||
|
||||
if(specialType == Special_Jockey || specialType == Special_Boomer) { // Else spawn a little bit off, and above (above for jockeys)
|
||||
pos[2] += 25.0;
|
||||
pos[0] += 5.0;
|
||||
} else { //If not jockey/hunter find a suitable area that is at least 5 m away
|
||||
float minDistance = GetIdealMinDistance(specialType);
|
||||
GetHorizontalPositionFromOrigin(pos, ang, minDistance, testPos);
|
||||
if(!FindSuitablePosition(pos, testPos, minDistance, 100)) {
|
||||
L4D_GetRandomPZSpawnPosition(target, view_as<int>(specialType), 10, testPos);
|
||||
}
|
||||
pos = testPos;
|
||||
}
|
||||
pos[2] += 1.0;
|
||||
// NegateVector(ang);
|
||||
|
||||
return SpawnSpecialInternal(specialType, target, pos, NULL_VECTOR) != -1;
|
||||
}
|
||||
|
||||
bool SpawnSpecialNear(int target, SpecialType type) {
|
||||
gInstaSpecialInstaKill = false;
|
||||
static float pos[3];
|
||||
if(L4D_GetRandomPZSpawnPosition(target, view_as<int>(type), 10, pos)) {
|
||||
return SpawnSpecialInternal(type, target, pos, NULL_VECTOR) != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// doesnt seem to work with l4dhooks methods
|
||||
void BypassLimit() {
|
||||
int bot = CreateFakeClient("Infected Bot");
|
||||
if (bot != 0) {
|
||||
ChangeClientTeam(bot, 3);
|
||||
CreateTimer(0.1, Timer_KickBot, bot);
|
||||
}
|
||||
}
|
||||
|
||||
int SpawnSpecialInternal(SpecialType type, int target, float pos[3], float ang[3]) {
|
||||
if(view_as<int>(type) <= 6) {
|
||||
// Bypass limit:
|
||||
gInstaSpecialType = view_as<int>(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[view_as<int>(type) - 1], "auto");
|
||||
return 0;
|
||||
}
|
||||
else if(type == Special_Witch) {
|
||||
int witch = L4D2_SpawnWitch(pos, ang);
|
||||
if(witch != -1)
|
||||
SetWitchTarget(witch, target);
|
||||
return witch;
|
||||
}
|
||||
else if(type == Special_Tank) {
|
||||
// BypassLimit();
|
||||
int tank = L4D2_SpawnTank(pos, ang);
|
||||
if(tank <= 0 || !IsClientConnected(tank)) return -1;
|
||||
if(tank != -1)
|
||||
g_iAttackerTarget[tank] = GetClientUserId(target);
|
||||
return tank;
|
||||
}
|
||||
else return -1;
|
||||
}
|
||||
|
||||
stock bool GetGroundBehind(int client, float vPos[3], float vAng[3]) {
|
||||
GetClientEyePosition(client, vPos);
|
||||
GetClientEyeAngles(client, vAng);
|
||||
|
|
|
@ -11,18 +11,25 @@ public Action Timer_ThrowTimer(Handle timer) {
|
|||
}
|
||||
|
||||
public Action Timer_Main(Handle timer) {
|
||||
static int loop;
|
||||
static int loopTick;
|
||||
static int slowDrainIndex;
|
||||
if(!slowDrainIndex) slowDrainIndex = GetTrollID("Slow Drain");
|
||||
static int tempHealthQuickDrainIndex;
|
||||
if(!tempHealthQuickDrainIndex) tempHealthQuickDrainIndex = GetTrollID("Temp Health Quick Drain");
|
||||
static int swarmIndex;
|
||||
if(!swarmIndex) swarmIndex = GetTrollID("Swarm");
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i)) {
|
||||
if(IsTrollActive(i, "Slow Drain")) {
|
||||
if(loop % 4 == 0) {
|
||||
if(Trolls[slowDrainIndex].IsActive(i)) {
|
||||
if(loopTick % 4 == 0) {
|
||||
int hp = GetClientHealth(i);
|
||||
if(hp > 50) {
|
||||
SetEntProp(i, Prop_Send, "m_iHealth", hp - 1);
|
||||
}
|
||||
}
|
||||
}else if(IsTrollActive(i, "Temp Health Quick Drain")) {
|
||||
if(loop % 2 == 0) {
|
||||
}else if(Trolls[tempHealthQuickDrainIndex].IsActive(i)) {
|
||||
if(loopTick % 2 == 0) {
|
||||
float bufferTime = GetEntPropFloat(i, Prop_Send, "m_healthBufferTime");
|
||||
float buffer = GetEntPropFloat(i, Prop_Send, "m_healthBuffer");
|
||||
float tempHealth = GetTempHealth(i);
|
||||
|
@ -32,13 +39,17 @@ public Action Timer_Main(Handle timer) {
|
|||
SetEntPropFloat(i, Prop_Send, "m_healthBufferTime", bufferTime - 7.0);
|
||||
}
|
||||
}
|
||||
}else if(IsTrollActive(i, "Swarm")) {
|
||||
}else if(Trolls[swarmIndex].IsActive(i)) {
|
||||
L4D2_RunScript("RushVictim(GetPlayerFromUserID(%d), %d)", GetClientUserId(i), 15000);
|
||||
} else if(Trolls[slipperyShoesIndex].IsActive(i) && Trolls[slipperyShoesIndex].activeFlagClients[i] & 1) {
|
||||
if(GetRandomFloat() <= 0.4) {
|
||||
L4D_StaggerPlayer(i, i, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(++loop >= 60) {
|
||||
loop = 0;
|
||||
}
|
||||
if(++loopTick >= 60) {
|
||||
loopTick = 0;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
@ -102,13 +113,6 @@ public Action Timer_KickBot(Handle timer, int client) {
|
|||
}
|
||||
}
|
||||
|
||||
public Action Timer_InstaFailed(Handle h) {
|
||||
if(gInstaSpecialType != -1) {
|
||||
gInstaSpecialType = -1;
|
||||
gInstaSpecialTarget = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_ShootReverse(Handle h, DataPack pack) {
|
||||
pack.Reset();
|
||||
int attacker = pack.ReadCell();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// UP THE VALUE 'MAX_TROLLS' in base.inc before adding new ones!
|
||||
|
||||
int slipperyShoesIndex = 0;
|
||||
|
||||
void SetupTrolls() {
|
||||
trollKV = new StringMap();
|
||||
categories = new ArrayList(ByteCountToCells(16));
|
||||
|
@ -7,6 +9,7 @@ void SetupTrolls() {
|
|||
int index;
|
||||
SetupTroll("Reset User", "Resets the user, removes all troll effects", TrollMod_Instant);
|
||||
|
||||
/// CATEGORY: Magnets
|
||||
SetCategory("Magnets");
|
||||
index = SetupTroll("Special Magnet", "Attracts ALL specials to any alive target with this troll enabled", TrollMod_Constant);
|
||||
AddMagnetFlags(index);
|
||||
|
@ -14,13 +17,23 @@ void SetupTrolls() {
|
|||
AddMagnetFlags(index);
|
||||
index = SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", TrollMod_Constant);
|
||||
|
||||
/// CATEGORY: Infected
|
||||
SetCategory("Infected");
|
||||
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("Inface Special", "Shortcut to sm_inface", TrollMod_Instant);
|
||||
SetupTroll("Insta Special", "Shortcut to sm_insta", TrollMod_Instant);
|
||||
SetupTroll("Goo", "Spawns a spitter puddle underneath them", TrollMod_Instant);
|
||||
index = SetupTroll("Amazon Special Combo", "Choose multiple different specials to spawn", TrollMod_Instant);
|
||||
Trolls[index].AddFlagPrompt(true);
|
||||
for(int i = 0; i < 8; i++) {
|
||||
Trolls[index].AddFlag(SPECIAL_NAMES[i], false); // 1 << 7 max
|
||||
}
|
||||
Trolls[index].AddFlagPrompt(false);
|
||||
Trolls[index].AddFlag("Spawn On Face", false); // 1 << 8
|
||||
Trolls[index].AddFlag("Spawn Near", false); // 1 << 9
|
||||
|
||||
// CATEGORY: Items
|
||||
SetCategory("Items");
|
||||
index = SetupTroll("Throw It All", "Player throws their item(s) periodically to a nearby player", TrollMod_Instant);
|
||||
//Can't add directly, is custom troll:
|
||||
|
@ -32,6 +45,11 @@ void SetupTrolls() {
|
|||
Trolls[index].AddFlag("Biles", true);
|
||||
Trolls[index].AddFlag("Molotovs", true);
|
||||
Trolls[index].AddFlag("Pipebombs", true);
|
||||
index = SetupTroll("Spicy Gas", "Gascans player picks up just ignite. Magic.", TrollMod_Constant);
|
||||
Trolls[index].AddFlagPrompt(false);
|
||||
Trolls[index].AddFlag("Always (100%)", false);
|
||||
Trolls[index].AddFlag("Half Time (50%)", true);
|
||||
Trolls[index].AddFlag("Rare (10%)", false);
|
||||
index = SetupTroll("No Pickup", "Prevents a player from picking up ANY (new) item. Use ThrowItAll to make them drop", TrollMod_Constant);
|
||||
Trolls[index].AddFlagPrompt(true);
|
||||
Trolls[index].AddFlag("No Primary", false);
|
||||
|
@ -39,6 +57,7 @@ void SetupTrolls() {
|
|||
Trolls[index].AddFlag("No Throwables", true);
|
||||
Trolls[index].AddFlag("No Kits", true);
|
||||
Trolls[index].AddFlag("No Pills / Adr", true);
|
||||
Trolls[index].AddFlag("No GASCANS", true);
|
||||
index = SetupTroll("UziRules / AwpSmells", "Picking up a weapon gives them a UZI or AWP instead", TrollMod_Constant);
|
||||
Trolls[index].AddFlagPrompt(false);
|
||||
Trolls[index].AddFlag("UZI Only", true);
|
||||
|
@ -51,6 +70,7 @@ void SetupTrolls() {
|
|||
Trolls[index].AddFlag("Rare (10%)", false);
|
||||
SetupTroll("Half Primary Ammo", "Cuts their primary reserve ammo in half", TrollMod_Instant);
|
||||
|
||||
/// CATEGORY: Chat
|
||||
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);
|
||||
|
@ -75,6 +95,7 @@ void SetupTrolls() {
|
|||
SetupTroll("Reversed", "Reserves their message", TrollMod_Constant);
|
||||
SetupTroll("Voice Mute", "Mutes from voice", TrollMod_Constant);
|
||||
|
||||
/// CATEGORY: Health
|
||||
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);
|
||||
|
@ -87,15 +108,28 @@ void SetupTrolls() {
|
|||
Trolls[index].AddFlag("0.5x Ratio", false); //4
|
||||
Trolls[index].AddFlag("0.0x Ratio (None)", false); //8
|
||||
Trolls[index].AddFlag("3x Ratio", false); //16
|
||||
Trolls[index].AddFlag("-2x Ratio", false); //16
|
||||
|
||||
SetCategory("Misc");
|
||||
SetupTroll("Gun Jam", "On reload, small chance their gun gets jammed - Can't reload.", TrollMod_Constant);
|
||||
/// CATEGORY: Movement
|
||||
SetCategory("Movement");
|
||||
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("Stagger", "Like a slap, but different", TrollMod_Instant);
|
||||
index = SetupTroll("Slippery Shoes", "Periodically stumbles around.", TrollMod_Constant);
|
||||
Trolls[index].AddFlagPrompt(true);
|
||||
Trolls[index].AddFlag("Periodically", true);
|
||||
Trolls[index].AddFlag("When using doors", false);
|
||||
Trolls[index].AddFlag("On throwable use", false);
|
||||
Trolls[index].AddFlag("On pills/adrenaline use", false);
|
||||
Trolls[index].AddFlag("On zombie bite", false);
|
||||
slipperyShoesIndex = index;
|
||||
|
||||
/// CATEGORY: MISC
|
||||
SetCategory("Misc");
|
||||
SetupTroll("Gun Jam", "On reload, small chance their gun gets jammed - Can't reload.", 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);
|
||||
index = SetupTroll("Meta: Inverse", "Uhm you are not supposed to see this...", TrollMod_Instant);
|
||||
Trolls[index].hidden = true;
|
||||
Trolls[index].AddFlagPrompt(false);
|
||||
|
@ -142,7 +176,6 @@ bool ApplyAffect(int victim, const Troll troll, int activator, trollModifier mod
|
|||
} else if(StrEqual(troll.name, "UziRules / AwpSmells")) {
|
||||
DisableTroll(victim, "No Pickup");
|
||||
DisableTroll(victim, "Primary Disable");
|
||||
SDKHook(victim, SDKHook_WeaponCanUse, Event_ItemPickup);
|
||||
} else if(StrEqual(troll.name, "Primary Disable")) {
|
||||
DisableTroll(victim, "UziRules / AwpSmells");
|
||||
DisableTroll(victim, "No Pickup");
|
||||
|
@ -201,6 +234,17 @@ bool ApplyAffect(int victim, const Troll troll, int activator, trollModifier mod
|
|||
L4D_StaggerPlayer(victim, victim, NULL_VECTOR);
|
||||
} else if(StrEqual(troll.name, "Voice Mute")) {
|
||||
BaseComm_SetClientMute(victim, !isActive);
|
||||
} else if(StrEqual(troll.name, "Spicy Gas")) {
|
||||
SDKHook(victim, SDKHook_WeaponCanUse, Event_ItemPickup);
|
||||
} else if(StrEqual(troll.name, "Amazon Special Combo")) {
|
||||
SpecialSpawnFlags spawnFlag = Special_Anywhere;
|
||||
if(flags & (1 << 8)) spawnFlag = Special_OnTarget;
|
||||
PrintToChatAll("spawnFlag: %d", spawnFlag);
|
||||
for(int i = 1; i < 7; i++) {
|
||||
if(flags & (1 << i)) {
|
||||
SpawnSpecialForTarget(view_as<SpecialType>(i), victim, spawnFlag);
|
||||
}
|
||||
}
|
||||
} else if(modifier != TrollMod_Constant) {
|
||||
PrintToServer("[FTT] Warn: Possibly invalid troll, no apply action defined for \"%s\"", troll.name);
|
||||
#if defined DEBUG
|
||||
|
|
|
@ -37,12 +37,9 @@ int lastButtonUser;
|
|||
int lastCrescendoUser;
|
||||
int g_iAttackerTarget[MAXPLAYERS+1];
|
||||
int g_PendingBanTroll[MAXPLAYERS+1];
|
||||
int g_iInSpit[MAXPLAYERS+1];
|
||||
Timer g_inSpitTimer;
|
||||
|
||||
int gInstaSpecialType = -1;
|
||||
int gInstaSpecialTarget;
|
||||
float gInstaSpecialSpawnPos[3];
|
||||
float gInstaSpecialSpawnAng[3];
|
||||
bool gInstaSpecialInstaKill;
|
||||
int gInstaSpecialMagnet[MAXPLAYERS+1];
|
||||
|
||||
char steamids[MAXPLAYERS+1][64];
|
||||
|
@ -51,6 +48,17 @@ int shootAtTarget[MAXPLAYERS+1];
|
|||
int shootAtTargetLoops[MAXPLAYERS+1];
|
||||
int shootAtTargetHP[MAXPLAYERS+1];
|
||||
|
||||
bool spIsActive;
|
||||
enum SpecialSpawnFlags {
|
||||
Special_Anywhere = 0,
|
||||
Special_OnTarget = 1
|
||||
}
|
||||
|
||||
enum SpecialInternalFlags {
|
||||
SPI_KillOnSpawn = 1
|
||||
}
|
||||
|
||||
|
||||
#include <feedthetrolls/base>
|
||||
#include <feedthetrolls/trolls>
|
||||
#include <feedthetrolls/combos>
|
||||
|
|
|
@ -20,6 +20,17 @@
|
|||
#include <l4d_anti_rush>
|
||||
|
||||
|
||||
/*
|
||||
TODO IDEAS:
|
||||
1. [x] Instant pipebomb explosion
|
||||
2. [x] Spicy gas (instant ignite), ignite propane/gas canisters
|
||||
3. [x] Amazon Special Combo (flags, choose combinations) (NEED QUEUE)
|
||||
4. Random weapons (on interval, possible second option of random capacity)
|
||||
5. [x] Slippery shoes (periodic stagger, or on certain events)
|
||||
6. (on hold) Sticky goo (slow user down in goo, or freezes)
|
||||
7. Follow goo
|
||||
*/
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "L4D2 Feed The Trolls",
|
||||
|
@ -47,6 +58,8 @@ public void OnPluginStart() {
|
|||
SetupTrolls();
|
||||
SetupsTrollCombos();
|
||||
|
||||
g_spSpawnQueue = new ArrayList(sizeof(SpecialSpawnRequest));
|
||||
|
||||
// Witch target overwrite stuff:
|
||||
|
||||
GameData data = new GameData("l4d2_behavior");
|
||||
|
@ -96,16 +109,21 @@ public void OnPluginStart() {
|
|||
HookEvent("player_death", Event_PlayerDeath);
|
||||
HookEvent("triggered_car_alarm", Event_CarAlarm);
|
||||
HookEvent("witch_harasser_set", Event_WitchVictimSet);
|
||||
HookEvent("door_open", Event_DoorToggle);
|
||||
HookEvent("door_close", Event_DoorToggle);
|
||||
HookEvent("adrenaline_used", Event_SecondaryHealthUsed);
|
||||
HookEvent("pills_used", Event_SecondaryHealthUsed);
|
||||
|
||||
AddNormalSoundHook(view_as<NormalSHook>(SoundHook));
|
||||
|
||||
AutoExecConfig(true, "l4d2_feedthetrolls");
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i))
|
||||
if(IsClientConnected(i) && IsClientInGame(i)) {
|
||||
SDKHook(i, SDKHook_OnTakeDamage, Event_TakeDamage);
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CVAR CHANGES
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue