Skip to content

Commit

Permalink
Merge pull request #146 from stayintarkov/fix-ai-targeting-clients
Browse files Browse the repository at this point in the history
Fix AI Targeting clients
  • Loading branch information
paulov-t authored Feb 19, 2024
2 parents 0c69ef3 + 29bec81 commit 8d03788
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 10 deletions.
131 changes: 131 additions & 0 deletions Source/AkiSupport/Custom/IsEnemyPatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using EFT;
using System.Linq;
using System.Reflection;
using HarmonyLib;
using StayInTarkov;

namespace Aki.Custom.Patches
{
public class IsEnemyPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(BotsGroup), nameof(BotsGroup.IsEnemy));
}

/// <summary>
/// IsEnemy()
/// Goal: Make bots take Side into account when deciding if another player/bot is an enemy
/// Check enemy cache list first, if not found, check side, if they differ, add to enemy list and return true
/// Needed to ensure bot checks the enemy side, not just its botType
/// </summary>
[PatchPrefix]
private static bool PatchPrefix(ref bool __result, BotsGroup __instance, IPlayer requester)
{
if (__instance.InitialBotType == WildSpawnType.peacefullZryachiyEvent
|| __instance.InitialBotType == WildSpawnType.shooterBTR
|| __instance.InitialBotType == WildSpawnType.gifter
|| __instance.InitialBotType == WildSpawnType.sectantWarrior
|| __instance.InitialBotType == WildSpawnType.sectantPriest)
{
return true; // Do original code
}

var isEnemy = false; // default not an enemy
if (requester == null)
{
__result = isEnemy;

return false; // Skip original
}

// Check existing enemies list
// Could also check x.Value.Player?.Id - BSG do it this way
if (!__instance.Enemies.IsNullOrEmpty() && __instance.Enemies.Any(x => x.Key.Id == requester.Id))
{
__result = true;
return false; // Skip original
}
else
{
// Weird edge case - without this you get spammed with key already in enemy list error when you move around on lighthouse
// Make zryachiy use existing isEnemy() code
if (__instance.InitialBotType == WildSpawnType.bossZryachiy)
{
return false; // Skip original
}

if (__instance.Side == EPlayerSide.Usec)
{
if (requester.Side == EPlayerSide.Bear || requester.Side == EPlayerSide.Savage ||
ShouldAttackUsec(requester))
{
isEnemy = true;
__instance.AddEnemy(requester, EBotEnemyCause.checkAddTODO);
}
}
else if (__instance.Side == EPlayerSide.Bear)
{
if (requester.Side == EPlayerSide.Usec || requester.Side == EPlayerSide.Savage ||
ShouldAttackBear(requester))
{
isEnemy = true;
__instance.AddEnemy(requester, EBotEnemyCause.checkAddTODO);
}
}
else if (__instance.Side == EPlayerSide.Savage)
{
if (requester.Side != EPlayerSide.Savage)
{
//Lets exUsec warn Usecs and fire at will at Bears
if (__instance.InitialBotType == WildSpawnType.exUsec)
{
return true; // Let BSG handle things
}
// everyone else is an enemy to savage (scavs)
isEnemy = true;
__instance.AddEnemy(requester, EBotEnemyCause.checkAddTODO);
}
}
}

__result = isEnemy;

return false; // Skip original
}

/// <summary>
/// Return True when usec default behavior is attack + bot is usec
/// </summary>
/// <param name="requester"></param>
/// <returns>bool</returns>
private static bool ShouldAttackUsec(IPlayer requester)
{
var requesterMind = requester?.AIData?.BotOwner?.Settings?.FileSettings?.Mind;

if (requesterMind == null)
{
return false;
}

return requester.IsAI && requesterMind.DEFAULT_USEC_BEHAVIOUR == EWarnBehaviour.Attack && requester.Side == EPlayerSide.Usec;
}

/// <summary>
/// Return True when bear default behavior is attack + bot is bear
/// </summary>
/// <param name="requester"></param>
/// <returns></returns>
private static bool ShouldAttackBear(IPlayer requester)
{
var requesterMind = requester.AIData?.BotOwner?.Settings?.FileSettings?.Mind;

if (requesterMind == null)
{
return false;
}

return requester.IsAI && requesterMind.DEFAULT_BEAR_BEHAVIOUR == EWarnBehaviour.Attack && requester.Side == EPlayerSide.Bear;
}
}
}
47 changes: 37 additions & 10 deletions Source/Coop/Components/CoopGameComponents/CoopGameComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ private IEnumerator SendPlayerStatePacket()

private void GameWorld_AfterGameStarted()
{
GameWorldGameStarted = true;
Logger.LogDebug(nameof(GameWorld_AfterGameStarted));
if (Singleton<GameWorld>.Instance.RegisteredPlayers.Any())
{
Expand Down Expand Up @@ -397,6 +398,14 @@ private IEnumerator EverySecondCoroutine()
if (!Singleton<ISITGame>.Instantiated)
continue;

if (!Singleton<GameWorld>.Instantiated)
continue;

if (!GameWorldGameStarted)
continue;

//Logger.LogDebug($"DEBUG: {nameof(EverySecondCoroutine)}");

var coopGame = Singleton<ISITGame>.Instance;

var playersToExtract = new HashSet<string>();
Expand Down Expand Up @@ -459,6 +468,20 @@ private IEnumerator EverySecondCoroutine()
}
}
}


// Add players who have joined to the AI Enemy Lists
var botController = (BotsController)ReflectionHelpers.GetFieldFromTypeByFieldType(typeof(BaseLocalGame<GamePlayerOwner>), typeof(BotsController)).GetValue(Singleton<ISITGame>.Instance);
if (botController != null)
{
while (PlayersForAIToTarget.TryDequeue(out var otherPlayer))
{
Logger.LogDebug($"Adding {otherPlayer.Profile.Nickname} to Enemy list");
botController.AddActivePLayer(otherPlayer);
botController.AddEnemyToAllGroups(otherPlayer, otherPlayer, otherPlayer);
}
}

}
}

Expand Down Expand Up @@ -1141,17 +1164,19 @@ private LocalPlayer CreateLocalPlayer(Profile profile, Vector3 position, int pla

if (!SITMatchmaking.IsClient)
{
if (otherPlayer.ProfileId.StartsWith("pmc"))
if (ProfileIdsUser.Contains(otherPlayer.ProfileId))
{
if (LocalGameInstance != null)
{
var botController = (BotsController)ReflectionHelpers.GetFieldFromTypeByFieldType(typeof(BaseLocalGame<GamePlayerOwner>), typeof(BotsController)).GetValue(LocalGameInstance);
if (botController != null)
{
Logger.LogDebug("Adding Client Player to Enemy list");
botController.AddActivePLayer(otherPlayer);
}
}
PlayersForAIToTarget.Enqueue(otherPlayer);
//if (Singleton<ISITGame>.Instantiated)
//{
// var botController = (BotsController)ReflectionHelpers.GetFieldFromTypeByFieldType(typeof(BaseLocalGame<GamePlayerOwner>), typeof(BotsController)).GetValue(Singleton<ISITGame>.Instance);
// if (botController != null)
// {
// Logger.LogDebug($"Adding {otherPlayer.Profile.Nickname} to Enemy list");
// botController.AddActivePLayer(otherPlayer);
// botController.AddEnemyToAllGroups(otherPlayer, otherPlayer, otherPlayer);
// }
//}
}
}

Expand Down Expand Up @@ -1339,6 +1364,8 @@ private void CreatePlayerStatePacketFromPRC(ref List<PlayerStatePacket> playerSt
//public bool HighPingMode { get; set; } = false;
public bool ServerHasStopped { get; set; }
private bool ServerHasStoppedActioned { get; set; }
public ConcurrentQueue<EFT.Player> PlayersForAIToTarget { get; } = new();
public bool GameWorldGameStarted { get; private set; }

GUIStyle middleLabelStyle;
GUIStyle middleLargeLabelStyle;
Expand Down
1 change: 1 addition & 0 deletions Source/StayInTarkovPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ private static void EnableSPPatches_Bots(BepInEx.Configuration.ConfigFile config
new SpawnProcessNegativeValuePatch().Enable();
new LocationLootCacheBustingPatch().Enable();
new FixBrokenSpawnOnSandboxPatch().Enable();
new IsEnemyPatch().Enable();
}

private void EnableCoopPatches()
Expand Down

0 comments on commit 8d03788

Please sign in to comment.