From 745340646b04270efffd0be2cc6ebb9af4673ebb Mon Sep 17 00:00:00 2001 From: Jackz Date: Fri, 8 Jan 2021 21:17:26 -0600 Subject: [PATCH] l4d2_autobotcrown: Split main timer into two, minor fixes - A Scan timer and an active timer to save resoruces --- plugins/l4d2_autobotcrown.smx | Bin 6529 -> 8213 bytes scripting/l4d2_autobotcrown.sp | 114 +++++++++++++++++++++++++++------ 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/plugins/l4d2_autobotcrown.smx b/plugins/l4d2_autobotcrown.smx index 180e37264c0b003fe6be87c0abd25fe0ae34215f..47d90ca0c6a4e6067ad0e65535742e994833a53c 100644 GIT binary patch delta 8068 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 diff --git a/scripting/l4d2_autobotcrown.sp b/scripting/l4d2_autobotcrown.sp index 6f977fc..2752a5b 100644 --- a/scripting/l4d2_autobotcrown.sp +++ b/scripting/l4d2_autobotcrown.sp @@ -3,6 +3,12 @@ #define PLUGIN_VERSION "1.0" +//#define DEBUG 0 + +#define SCAN_INTERVAL 5.0 +#define SCAN_RANGE 750.0 +#define ACTIVE_INTERVAL 0.4 + #include #include #include @@ -17,12 +23,15 @@ public Plugin myinfo = url = "" }; +//TODO: Performance checks, split main loop into scan loop / active loop, and convars for allowed gamemodes / difficulties + static ArrayList WitchList; static Handle timer = INVALID_HANDLE; static bool lateLoaded = false, AutoCrownInPosition = false; -static int AutoCrownBot = -1, AutoCrownTarget; +static int AutoCrownBot = -1, AutoCrownTarget, currentDifficulty; static float CrownPos[3], CrownAng[3]; +static ConVar hValidDifficulties, hAllowedGamemodes; public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { if(late) lateLoaded = true; @@ -35,7 +44,7 @@ public void OnPluginStart() SetFailState("This plugin is for L4D/L4D2 only."); } - WitchList = new ArrayList(1, 1); + WitchList = new ArrayList(1, 0); if(lateLoaded) { char classname[32]; for(int i = MaxClients; i < 2048; i++) { @@ -44,18 +53,56 @@ public void OnPluginStart() if(StrEqual(classname, "witch", false)) { WitchList.Push(i); if(timer == INVALID_HANDLE) { - timer = CreateTimer(0.4, Timer_BotControlTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + timer = CreateTimer(SCAN_INTERVAL, Timer_Scan, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); } } } } } + hValidDifficulties = CreateConVar("l4d2_autocrown_allowed_difficulty", "7", "The difficulties the plugin is active on. 1=Easy, 2=Normal 4=Advanced 8=Expert. Add numbers together.", FCVAR_NONE); + hAllowedGamemodes = CreateConVar("l4d2_autocrown_modes_tog", "7", "Turn on the plugin in these game modes. 0=All, 1=Coop, 2=Survival, 4=Versus, 8=Scavenge. Add numbers together.", FCVAR_NONE); + + char diff[16]; + FindConVar("z_difficulty").GetString(diff, sizeof(diff)); + currentDifficulty = GetDifficultyInt(diff); + + FindConVar("mp_gamemode").AddChangeHook(Change_Gamemode); + + AutoExecConfig(true); + HookEvent("witch_spawn", Event_WitchSpawn); HookEvent("witch_killed", Event_WitchKilled); + HookEvent("difficulty_changed", Event_DifficultyChanged); + + RegAdminCmd("sm_ws", Cmd_Status, ADMFLAG_ROOT); +} +public Action Cmd_Status(int client, int args) { + ReplyToCommand(client, "Scan Timer: %b | Active: %b | In Position %b | Witches %d", timer != INVALID_HANDLE, AutoCrownBot > -1, AutoCrownInPosition, WitchList.Length); + return Plugin_Handled; +} +public void Event_DifficultyChanged(Event event, const char[] name, bool dontBroadcast) { + char diff[16]; + event.GetString("newDifficulty", diff, sizeof(diff)); + currentDifficulty = GetDifficultyInt(diff); + if(hAllowedGamemodes.IntValue & currentDifficulty > 0) { + if(timer == INVALID_HANDLE) { + timer = CreateTimer(SCAN_INTERVAL, Timer_Scan, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + } + }else{ + CloseHandle(timer); + } +} +public void Change_Gamemode(ConVar convar, const char[] oldValue, const char[] newValue) { + if(StrEqual(newValue, "realism")) { + CloseHandle(timer); + } } +public bool IsGamemodeAllowed() { + return true; +} public Action Event_WitchSpawn(Event event, const char[] name, bool dontBroadcast) { int witchID = event.GetInt("witchid"); @@ -64,7 +111,7 @@ public Action Event_WitchSpawn(Event event, const char[] name, bool dontBroadcas PrintToServer("Witch spawned: %d", witchID); #endif if(timer == INVALID_HANDLE) { - timer = CreateTimer(0.4, Timer_BotControlTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + timer = CreateTimer(SCAN_INTERVAL, Timer_Scan, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); } } @@ -87,8 +134,7 @@ public Action Event_WitchKilled(Event event, const char[] name, bool dontBroadca #endif } } - -public Action Timer_BotControlTimer(Handle hdl) { +public Action Timer_Active(Handle hdl) { float botPosition[3], witchPos[3]; if(WitchList.Length == 0) { #if defined DEBUG @@ -98,38 +144,53 @@ public Action Timer_BotControlTimer(Handle hdl) { } //TODO: Also check if startled and cancel it immediately. if(AutoCrownBot > -1) { - GetEntPropVector(AutoCrownTarget, Prop_Send, "m_vecOrigin", witchPos); - GetClientAbsOrigin(AutoCrownBot, botPosition); - + int client = GetClientOfUserId(AutoCrownBot); if(!IsValidEntity(AutoCrownTarget)) { ResetAutoCrown(); #if defined DEBUG PrintToServer("Could not find valid AutoCrownTarget"); #endif - }else if(!IsClientConnected(AutoCrownBot) || !IsPlayerAlive(AutoCrownBot)) { + return Plugin_Stop; + }else if(client <= 0 || !IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) { AutoCrownBot = -1; AutoCrownTarget = -1; #if defined DEBUG PrintToServer("Could not find valid AutoCrownBot"); #endif + return Plugin_Stop; } + GetEntPropVector(AutoCrownTarget, Prop_Send, "m_vecOrigin", witchPos); + GetClientAbsOrigin(client, botPosition); + float distance = GetVectorDistance(botPosition, witchPos); if(distance <= 60) { float botAngles[3]; - GetClientAbsAngles(AutoCrownBot, botAngles); + GetClientAbsAngles(client, botAngles); botAngles[0] = 60.0; botAngles[1] = RadToDeg(ArcTangent2( botPosition[1] - witchPos[1], botPosition[0] - witchPos[0])) + 180.0; //Is In Position - ClientCommand(AutoCrownBot, "slot0"); - TeleportEntity(AutoCrownBot, NULL_VECTOR, botAngles, NULL_VECTOR); + ClientCommand(client, "slot0"); + TeleportEntity(client, NULL_VECTOR, botAngles, NULL_VECTOR); AutoCrownInPosition = true; }else{ - L4D2_RunScript("CommandABot({cmd=1,bot=GetPlayerFromUserID(%i),pos=Vector(%f,%f,%f)})", GetClientUserId(AutoCrownBot), witchPos[0], witchPos[1], witchPos[2]); + L4D2_RunScript("CommandABot({cmd=1,bot=GetPlayerFromUserID(%i),pos=Vector(%f,%f,%f)})", AutoCrownBot, witchPos[0], witchPos[1], witchPos[2]); } return Plugin_Continue; + }else{ + timer = CreateTimer(SCAN_INTERVAL, Timer_Scan, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + return Plugin_Stop; + } +} +public Action Timer_Scan(Handle hdl) { + float botPosition[3], witchPos[3]; + if(WitchList.Length == 0) { + #if defined DEBUG + PrintToServer("No witches detected, ending timer"); + #endif + return Plugin_Stop; } for(int bot = 1; bot < MaxClients+1; bot++) { if(IsClientConnected(bot) && IsClientInGame(bot) && IsFakeClient(bot) && IsPlayerAlive(bot)) { @@ -143,16 +204,20 @@ public Action Timer_BotControlTimer(Handle hdl) { for(int i = 0; i < WitchList.Length; i++) { int witchID = WitchList.Get(i); - if(IsValidEntity(witchID) && GetEntPropFloat(witchID, Prop_Send, "m_rage") <= 0.4) { + if(IsValidEntity(witchID) && HasEntProp(witchID, Prop_Send, "m_rage") && GetEntPropFloat(witchID, Prop_Send, "m_rage") <= 0.4) { GetEntPropVector(witchID, Prop_Send, "m_vecOrigin", witchPos); //TODO: Calculate closest witch - if(GetVectorDistance(botPosition, witchPos) <= 570) { + if(GetVectorDistance(botPosition, witchPos) <= SCAN_RANGE) { //GetEntPropVector(witchID, Prop_Send, "m_angRotation", witchAng); - + //TODO: Implement a line-of-sight trace + #if defined DEBUG + PrintToChatAll("Found a valid witch in range of %N: %d", bot, witchID); + #endif L4D2_RunScript("CommandABot({cmd=1,bot=GetPlayerFromUserID(%i),pos=Vector(%f,%f,%f)})", GetClientUserId(bot), witchPos[0], witchPos[1], witchPos[2]); AutoCrownTarget = witchID; - AutoCrownBot = bot; + AutoCrownBot = GetClientUserId(bot); AutoCrownInPosition = false; + CreateTimer(ACTIVE_INTERVAL, Timer_Active, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); return Plugin_Continue; } } @@ -169,7 +234,7 @@ public Action Timer_StopFiring(Handle hdl) { } 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(AutoCrownInPosition && AutoCrownBot == client && !(buttons & IN_ATTACK)) { + if(AutoCrownInPosition && GetClientOfUserId(AutoCrownBot) == client && !(buttons & IN_ATTACK)) { buttons |= IN_ATTACK; //CreateTimer(0.4, Timer_StopFiring); return Plugin_Changed; @@ -183,5 +248,16 @@ public void ResetAutoCrown() { if(AutoCrownBot > -1) L4D2_RunScript("CommandABot({cmd=3,bot=GetPlayerFromUserID(%i)})", GetClientUserId(AutoCrownBot)); AutoCrownBot = -1; +} +int GetDifficultyInt(const char[] type) { + if(StrEqual(type, "impossible")) { + return 8; + }else if(StrEqual(type, "hard")) { + return 4; + }else if(StrEqual(type, "normal")) { + return 2; + }else{ + return 1; + } } \ No newline at end of file