From 208ee49a1f29f1cd7c7e01d84df3f2b998472e38 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sun, 19 May 2024 20:41:41 +0200 Subject: [PATCH 1/2] Fix return scope on CheckForPlayers --- Fika.Core/Coop/Custom/FikaDynamicAI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fika.Core/Coop/Custom/FikaDynamicAI.cs b/Fika.Core/Coop/Custom/FikaDynamicAI.cs index ecb6a02c..e8b8ec6f 100644 --- a/Fika.Core/Coop/Custom/FikaDynamicAI.cs +++ b/Fika.Core/Coop/Custom/FikaDynamicAI.cs @@ -121,8 +121,8 @@ private void CheckForPlayers(CoopBot bot) if (!bot.gameObject.activeSelf) { ActivateBot(bot); - return; } + return; } if (!bot.HealthController.IsAlive) From 69d2b7072789f683f87fcb43a8bc64b0f9ae9cbe Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Mon, 20 May 2024 10:11:56 +0200 Subject: [PATCH 2/2] Fixes - Reworked dynamic AI to be more efficient - Bots will no longer spawn without a brain due to a hidden exception --- Fika.Core/Coop/Custom/FikaDynamicAI.cs | 53 +++++++++++++++++++++----- Fika.Core/Coop/GameMode/CoopGame.cs | 38 ++++++++++-------- Fika.Core/FikaPlugin.cs | 5 +++ Fika.Core/Utils/FikaModHandler.cs | 6 +++ 4 files changed, 78 insertions(+), 24 deletions(-) diff --git a/Fika.Core/Coop/Custom/FikaDynamicAI.cs b/Fika.Core/Coop/Custom/FikaDynamicAI.cs index e8b8ec6f..4728bdb1 100644 --- a/Fika.Core/Coop/Custom/FikaDynamicAI.cs +++ b/Fika.Core/Coop/Custom/FikaDynamicAI.cs @@ -5,6 +5,7 @@ using EFT; using Fika.Core.Coop.Components; using Fika.Core.Coop.Players; +using System; using System.Collections.Generic; using UnityEngine; @@ -16,8 +17,9 @@ public class FikaDynamicAI : MonoBehaviour private CoopHandler coopHandler; private int frameCounter; private int resetCounter; - private List humanPlayers = []; - private List bots = []; + private readonly List humanPlayers = []; + private readonly List bots = []; + private readonly HashSet disabledBots = []; private BotSpawner spawner; protected void Awake() @@ -65,11 +67,21 @@ private void Spawner_OnBotRemoved(BotOwner botOwner) private void Spawner_OnBotCreated(BotOwner botOwner) { + if (botOwner.IsYourPlayer || !botOwner.IsAI) + { + return; + } + bots.Add((CoopBot)botOwner.GetPlayer); } protected void Update() { + if (!FikaPlugin.DynamicAI.Value) + { + return; + } + frameCounter++; if (frameCounter % resetCounter == 0) @@ -93,7 +105,7 @@ public void AddHumans() } } - private void DeactivateBot(CoopPlayer bot) + private void DeactivateBot(CoopBot bot) { #if DEBUG logger.LogWarning($"Disabling {bot.gameObject.name}"); @@ -102,9 +114,18 @@ private void DeactivateBot(CoopPlayer bot) bot.AIData.BotOwner.Memory.GoalEnemy = null; bot.AIData.BotOwner.PatrollingData.Pause(); bot.gameObject.SetActive(false); + + if (!disabledBots.Contains(bot)) + { + disabledBots.Add(bot); + } + else + { + logger.LogError($"{bot.gameObject.name} was already in the disabled bots list when adding!"); + } } - private void ActivateBot(CoopPlayer bot) + private void ActivateBot(CoopBot bot) { #if DEBUG logger.LogWarning($"Enabling {bot.gameObject.name}"); @@ -112,16 +133,14 @@ private void ActivateBot(CoopPlayer bot) bot.gameObject.SetActive(true); bot.AIData.BotOwner.PatrollingData.Unpause(); bot.AIData.BotOwner.PostActivate(); + disabledBots.Remove(bot); } private void CheckForPlayers(CoopBot bot) { - if (!FikaPlugin.DynamicAI.Value) + // Do not run on bots that have no initialized yet + if (bot.AIData.BotOwner.BotState is EBotState.NonActive or EBotState.PreActive) { - if (!bot.gameObject.activeSelf) - { - ActivateBot(bot); - } return; } @@ -139,13 +158,16 @@ private void CheckForPlayers(CoopBot bot) notInRange++; continue; } + if (!humanPlayer.HealthController.IsAlive) { notInRange++; continue; } + float distance = Vector3.SqrMagnitude(bot.Position - humanPlayer.Position); float range = FikaPlugin.DynamicAIRange.Value; + if (distance > range * range) { notInRange++; @@ -161,5 +183,18 @@ private void CheckForPlayers(CoopBot bot) ActivateBot(bot); } } + + public void SettingChanged(bool value) + { + if (!value) + { + foreach (CoopBot bot in disabledBots) + { + bot.gameObject.SetActive(true); + } + + disabledBots.Clear(); + } + } } } diff --git a/Fika.Core/Coop/GameMode/CoopGame.cs b/Fika.Core/Coop/GameMode/CoopGame.cs index b1eddfcc..f177d7ba 100644 --- a/Fika.Core/Coop/GameMode/CoopGame.cs +++ b/Fika.Core/Coop/GameMode/CoopGame.cs @@ -1,5 +1,6 @@ using Aki.Custom.Airdrops; using Aki.Reflection.Utils; +using BepInEx.Configuration; using BepInEx.Logging; using Comfort.Common; using CommonAssets.Scripts.Game; @@ -58,7 +59,8 @@ internal sealed class CoopGame : BaseLocalGame, IBotGame, IFika public bool forceStart = false; private CoopExfilManager exfilManager; private GameObject fikaStartButton; - private Dictionary botQueue = []; + private readonly Dictionary botQueue = []; + private FikaDynamicAI dynamicAI; public RaidSettings RaidSettings { get; private set; } @@ -114,10 +116,10 @@ internal static CoopGame Create(InputTree inputTree, Profile profile, GameDateTi coopGame.nonWavesSpawnScenario_0.ImplementWaveSettings(wavesSettings); // Waves Scenario setup - WildSpawnWave[] waves = EFT.LocalGame.smethod_7(wavesSettings, location.waves); + WildSpawnWave[] waves = LocalGame.smethod_7(wavesSettings, location.waves); coopGame.wavesSpawnScenario_0 = WavesSpawnScenario.smethod_0(coopGame.gameObject, waves, new Action(coopGame.botsController_0.ActivateBotsByWave), location); - BossLocationSpawn[] bossSpawns = EFT.LocalGame.smethod_8(wavesSettings, location.BossLocationSpawn); + BossLocationSpawn[] bossSpawns = LocalGame.smethod_8(wavesSettings, location.BossLocationSpawn); coopGame.GClass579 = GClass579.smethod_0(bossSpawns, new Action(coopGame.botsController_0.ActivateBotsByWave)); if (useCustomWeather && MatchmakerAcceptPatches.IsServer) @@ -361,7 +363,7 @@ private async Task CreateBot(Profile profile, Vector3 position) } else { - int num = 999 + Bots.Count; + int num = method_12(); profile.SetSpawnedInSession(profile.Info.Side == EPlayerSide.Savage); FikaServer server = Singleton.Instance; @@ -390,7 +392,7 @@ private async Task CreateBot(Profile profile, Vector3 position) else { #if DEBUG - Logger.LogInfo($"Bot {profile.Info.Settings.Role.ToString()} created at {position} SUCCESSFULLY!"); + Logger.LogInfo($"Bot {profile.Info.Settings.Role} created at {position} SUCCESSFULLY!"); #endif Bots.Add(localPlayer.ProfileId, localPlayer); } @@ -546,8 +548,7 @@ private async void DeployScreen(float timeBeforeDeploy) Destroy(fikaStartButton); } - FikaDynamicAI newDynamicAI = gameObject.GetComponent(); - newDynamicAI?.AddHumans(); + dynamicAI?.AddHumans(); SetStatusModel status = new(coopHandler.MyPlayer.ProfileId, LobbyEntry.ELobbyStatus.IN_GAME); await FikaRequestHandler.UpdateSetStatus(status); @@ -597,8 +598,7 @@ private async void DeployScreen(float timeBeforeDeploy) Singleton.Instance.SendDataToAll(writer, ref syncPacket, LiteNetLib.DeliveryMethod.ReliableUnordered); } - FikaDynamicAI newDynamicAI = gameObject.GetComponent(); - newDynamicAI?.AddHumans(); + dynamicAI?.AddHumans(); } else if (MatchmakerAcceptPatches.IsClient) { @@ -919,8 +919,7 @@ public void FinishLoading() private async Task CreateLocalPlayer() { - int num = Traverse.Create(this).Field("int_0").GetValue(); - num++; + int num = method_12(); Player.EUpdateMode eupdateMode = Player.EUpdateMode.Auto; if (GClass549.Config.UseHandsFastAnimator) @@ -978,7 +977,6 @@ private async Task WaitForPlayers() FikaServer server = Singleton.Instance; - numbersOfPlayersToWaitFor = MatchmakerAcceptPatches.HostExpectedNumberOfPlayers - (server.NetServer.ConnectedPeersCount + 1); do { numbersOfPlayersToWaitFor = MatchmakerAcceptPatches.HostExpectedNumberOfPlayers - (server.NetServer.ConnectedPeersCount + 1); @@ -1038,7 +1036,6 @@ private async Task WaitForPlayers() NetDataWriter writer = new(); writer.Reset(); client.SendData(writer, ref packet, LiteNetLib.DeliveryMethod.ReliableOrdered); - numbersOfPlayersToWaitFor = MatchmakerAcceptPatches.HostExpectedNumberOfPlayers - (client.ConnectedClients + 1); do { numbersOfPlayersToWaitFor = MatchmakerAcceptPatches.HostExpectedNumberOfPlayers - (client.ConnectedClients + 1); @@ -1142,7 +1139,7 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co botsController_0.BotSpawner.SetMaxBots(limits); } - gameObject.AddComponent(); + dynamicAI = gameObject.AddComponent(); } else if (MatchmakerAcceptPatches.IsClient) { @@ -1209,6 +1206,8 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co } GClass579.Run(EBotsSpawnMode.Anyway); + + FikaPlugin.DynamicAI.SettingChanged += DynamicAI_SettingChanged; } else { @@ -1238,6 +1237,14 @@ public override IEnumerator vmethod_4(float startDelay, BotControllerSettings co yield break; } + private void DynamicAI_SettingChanged(object sender, EventArgs e) + { + if (dynamicAI != null) + { + dynamicAI.SettingChanged(FikaPlugin.DynamicAI.Value); + } + } + private void SetupBorderzones() { GameWorld gameWorld = Singleton.Instance; @@ -1730,7 +1737,6 @@ public override void Dispose() Singleton.Instance.MineManager.OnExplosion -= OnMineExplode; } - // Add these to coopgame directly? if (MatchmakerAcceptPatches.IsServer) { CoopPlayer coopPlayer = (CoopPlayer)Singleton.Instance.MainPlayer; @@ -1744,6 +1750,8 @@ public override void Dispose() { Destroy(newDynamicAI); } + + FikaPlugin.DynamicAI.SettingChanged -= DynamicAI_SettingChanged; } else if (MatchmakerAcceptPatches.IsClient) { diff --git a/Fika.Core/FikaPlugin.cs b/Fika.Core/FikaPlugin.cs index b60beb1b..daf2a0ce 100644 --- a/Fika.Core/FikaPlugin.cs +++ b/Fika.Core/FikaPlugin.cs @@ -234,6 +234,11 @@ protected void Awake() StartCoroutine(RunModHandler()); } + private void Config_SettingChanged(object sender, SettingChangedEventArgs e) + { + throw new NotImplementedException(); + } + /// /// Coroutine to ensure all mods are loaded by waiting 5 seconds /// diff --git a/Fika.Core/Utils/FikaModHandler.cs b/Fika.Core/Utils/FikaModHandler.cs index 0463a50b..d364eeb7 100644 --- a/Fika.Core/Utils/FikaModHandler.cs +++ b/Fika.Core/Utils/FikaModHandler.cs @@ -10,6 +10,7 @@ public class FikaModHandler private readonly ManualLogSource logger = Logger.CreateLogSource("FikaModHandler"); public bool QuestingBotsLoaded = false; + public bool SAINLoaded = false; public void Run() { @@ -34,6 +35,11 @@ private void CheckSpecialMods(string key) { QuestingBotsLoaded = true; } + + if (key == "me.sol.sain") + { + SAINLoaded = true; + } } } }