diff --git a/plugins/l4d2_feedthetrolls.smx b/plugins/l4d2_feedthetrolls.smx index 92c1260..8785bdd 100644 Binary files a/plugins/l4d2_feedthetrolls.smx and b/plugins/l4d2_feedthetrolls.smx differ diff --git a/scripting/include/feedthetrolls/commands.inc b/scripting/include/feedthetrolls/commands.inc index c47a12f..fc12b8e 100644 --- a/scripting/include/feedthetrolls/commands.inc +++ b/scripting/include/feedthetrolls/commands.inc @@ -39,9 +39,9 @@ public Action Command_InstaSpecial(int client, int args) { ReplyToTargetError(client, target_count); return Plugin_Handled; } - int specialType = GetSpecialType(arg2); + SpecialType specialType = GetSpecialType(arg2); static float pos[3]; - if(specialType == -1) { + if(specialType == Special_Invalid) { ReplyToCommand(client, "Unknown special \"%s\"", arg2); return Plugin_Handled; } @@ -108,9 +108,9 @@ public Action Command_InstaSpecialFace(int client, int args) { ReplyToTargetError(client, target_count); return Plugin_Handled; } - int specialType = GetSpecialType(arg2); + SpecialType specialType = GetSpecialType(arg2); static float pos[3]; - if(specialType == -1) { + if(specialType == Special_Invalid) { ReplyToCommand(client, "Unknown special \"%s\"", arg2); return Plugin_Handled; } diff --git a/scripting/include/feedthetrolls/events.inc b/scripting/include/feedthetrolls/events.inc index 7c531a1..e2b91e5 100644 --- a/scripting/include/feedthetrolls/events.inc +++ b/scripting/include/feedthetrolls/events.inc @@ -30,11 +30,15 @@ public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast } 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) { gInstaSpecialType = -1; + // Set special to only attack them: g_iAttackerTarget[special] = gInstaSpecialTarget; + // Incremenet count of specials targetting player: gInstaSpecialMagnet[GetClientOfUserId(gInstaSpecialTarget)]++; TeleportEntity(special, gInstaSpecialSpawnPos, gInstaSpecialSpawnAng, NULL_VECTOR); @@ -95,9 +99,8 @@ public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadca } public Action Event_WeaponReload(int weapon) { int client = GetEntPropEnt(weapon, Prop_Send, "m_hOwner"); - if(IsTrollActive(client, "Gun Jam")) { - float dec = GetRandomFloat(0.0, 1.0); - if(FloatCompare(dec, 0.50) == -1) { //10% chance gun jams + if(client > 0 && IsTrollActive(client, "Gun Jam")) { + if(GetRandomFloat() < 0.10) { //10% chance gun jams return Plugin_Stop; } } @@ -140,7 +143,7 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) { int existingTarget = GetClientOfUserId(g_iAttackerTarget[attacker]); if(existingTarget > 0) { if(IsPlayerAlive(existingTarget)) { - // Insta-specials ALWAYS target + // Insta-specials ALWAYS target, if target has any attackers remaining if(gInstaSpecialMagnet[existingTarget] > 0) { curTarget = existingTarget; return Plugin_Changed; @@ -708,7 +711,7 @@ 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) { - int special = GetRandomInt(0,6); + SpecialType special = view_as(GetRandomInt(0,6)); iLastAntiRushEvent[client] = GetGameTime(); SpawnSpecialNear(client, special); PrintToConsoleAll("[FTT] Spawning anti-rush special on %N (dist=%f) (special=%d)", client, distance, special); diff --git a/scripting/include/feedthetrolls/menus.inc b/scripting/include/feedthetrolls/menus.inc index 0f3c290..d157028 100644 --- a/scripting/include/feedthetrolls/menus.inc +++ b/scripting/include/feedthetrolls/menus.inc @@ -31,18 +31,23 @@ public int Insta_SpecialHandler(Menu menu, MenuAction action, int client, int pa ExplodeString(info, "|", str, 3, 8, false); int target = GetClientOfUserId(StringToInt(str[0])); bool inFace = StrEqual(str[1], "1"); - int special = StringToInt(str[2]); + int specialInt = StringToInt(str[2]); + if(specialInt < 0 || specialInt > 8) { + ReplyToCommand(client, "Invalid special id"); + return; + } + SpecialType special = view_as(specialInt); if(inFace) { if(SpawnSpecialInFace(target, special)) { - LogAction(client, target, "\"%L\" spawned Insta-%s™ on \"%L\"", client, SPECIAL_NAMES[special-1], target); - ShowActivityEx(client, "[FTT] ", "spawned Insta-%s™ on %N", SPECIAL_NAMES[special-1], target); + 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)) { - LogAction(client, target, "\"%L\" spawned Insta-%s™ near \"%L\"", client, SPECIAL_NAMES[special-1], target); - ShowActivityEx(client, "[FTT] ", "spawned Insta-%s™ near %N", SPECIAL_NAMES[special-1], 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 { ReplyToCommand(client, "Could not spawn special."); } diff --git a/scripting/include/feedthetrolls/specials.inc b/scripting/include/feedthetrolls/specials.inc index 559b011..f2b7668 100644 --- a/scripting/include/feedthetrolls/specials.inc +++ b/scripting/include/feedthetrolls/specials.inc @@ -1,12 +1,23 @@ char SPECIAL_NAMES[][] = { "Smoker", "Boomer", "Hunter", "Spitter", "Jockey", "Charger", "Witch", "Tank" }; +enum SpecialType { + Special_Invalid = -1, + Special_Smoker = 0, + Special_Boomer, + Special_Hunter, + Special_Spitter, + Special_Jockey, + Special_Charger, + Special_Witch, + Special_Tank +} -stock int GetSpecialType(const char[] input) { +stock SpecialType GetSpecialType(const char[] input) { for(int i = 0; i < 8; i++) { - if(strcmp(SPECIAL_NAMES[i], input, false) == 0) return i + 1; + if(strcmp(SPECIAL_NAMES[i], input, false) == 0) return view_as(i + 1); } - return -1; + return Special_Invalid; } stock bool FindSuitablePosition(int target, const float pos[3], float outputPos[3], float minDistance = 19000.0, int tries = 100) { @@ -25,7 +36,7 @@ stock bool FindSuitablePosition(int target, const float pos[3], float outputPos[ return false; } -float GetIdealMinDistance(int specialType) { +float GetIdealMinDistance(SpecialType specialType) { switch(specialType) { // /*Boomer*/ case 2: return 1200.0; /*Charger*/ case 6: return 19500.0; @@ -36,20 +47,19 @@ float GetIdealMinDistance(int specialType) { } } -bool SpawnSpecialInFace(int target, int specialType) { - if(specialType > 8) return false; +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 == 2) + if(specialType == Special_Boomer) gInstaSpecialInstaKill = true; - if(specialType != 5 && specialType != 2) { //If not jockey/hunter find a suitable area that is at least 5 m away + if(specialType != Special_Jockey && specialType != Special_Hunter) { //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(target, pos, testPos, minDistance, 100)) { - L4D_GetRandomPZSpawnPosition(target, specialType, 10, testPos); + L4D_GetRandomPZSpawnPosition(target, view_as(specialType), 10, testPos); } pos = testPos; } else { // Else spawn a little bit off, and above (above for jockeys) @@ -62,12 +72,11 @@ bool SpawnSpecialInFace(int target, int specialType) { return SpawnSpecialInternal(specialType, target, pos, NULL_VECTOR) != -1; } -bool SpawnSpecialNear(int target, int specialType) { +bool SpawnSpecialNear(int target, SpecialType type) { 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) != -1; + if(L4D_GetRandomPZSpawnPosition(target, view_as(type), 10, pos)) { + return SpawnSpecialInternal(type, target, pos, NULL_VECTOR) != -1; } return false; } @@ -81,10 +90,10 @@ void BypassLimit() { } } -int SpawnSpecialInternal(int type, int target, float pos[3], float ang[3]) { - if(type <= 6) { +int SpawnSpecialInternal(SpecialType type, int target, float pos[3], float ang[3]) { + if(view_as(type) <= 6) { // Bypass limit: - gInstaSpecialType = type; + gInstaSpecialType = view_as(type); gInstaSpecialTarget = GetClientUserId(target); gInstaSpecialSpawnPos = pos; gInstaSpecialSpawnAng = pos; @@ -94,16 +103,16 @@ int SpawnSpecialInternal(int type, int target, float pos[3], float ang[3]) { ChangeClientTeam(bot, 3); CreateTimer(0.1, Timer_KickBot, bot); } - CheatCommand(target, "z_spawn_old", SPECIAL_NAMES[type-1], "auto"); + CheatCommand(target, "z_spawn_old", SPECIAL_NAMES[view_as(type) = -1], "auto"); return 0; } - else if(type == 7) { + else if(type == Special_Witch) { int witch = L4D2_SpawnWitch(pos, ang); if(witch != -1) SetWitchTarget(witch, target); return witch; } - else if(type == 8) { + else if(type == Special_Tank) { // BypassLimit(); int tank = L4D2_SpawnTank(pos, ang); if(tank <= 0 || !IsClientConnected(tank)) return -1;