mirror of
https://github.com/sp-tarkov/modules.git
synced 2025-02-13 01:10:45 -05:00
IsEnemyPatch Improvements (!156)
Revised `IsEnemyPatch` with the following changes: * Added a check to see if the player is in the group's `Allies` collection (needed for mod support) * Added a check to see if the player is in the group (possibly needed for future mod support) * Fixed Zryachiy check (and added his followers) by allowing the EFT method to run for them * Refactoring for clarity and to reorder the checks based on priority: 1) Null check(s) 2) Check if the player is in the group or in its `Allies` or `Enemies` collections 3) Allow the EFT method to run for certain bot roles 4) Finally, add the player to the group's `Enemies` collection if needed **This is a big change, so please double-check my work!** I tested this in multiple raids, in several maps, with and without SAIN, and I didn't find any issues. Reviewed-on: SPT/Modules#156 Co-authored-by: DanW <danw@noreply.dev.sp-tarkov.com> Co-committed-by: DanW <danw@noreply.dev.sp-tarkov.com>
This commit is contained in:
parent
471c191bbb
commit
af96c37815
@ -1,4 +1,5 @@
|
||||
using EFT;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SPT.Custom.CustomAI
|
||||
{
|
||||
@ -42,5 +43,20 @@ namespace SPT.Custom.CustomAI
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<BotOwner> GetAllMembers(this BotsGroup group)
|
||||
{
|
||||
List<BotOwner> members = new List<BotOwner>();
|
||||
|
||||
if (group != null)
|
||||
{
|
||||
for (int m = 0; m < group.MembersCount; m++)
|
||||
{
|
||||
members.Add(group.Member(m));
|
||||
}
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
using SPT.Reflection.Patching;
|
||||
using EFT;
|
||||
using EFT;
|
||||
using HarmonyLib;
|
||||
using SPT.Custom.CustomAI;
|
||||
using SPT.Reflection.Patching;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace SPT.Custom.Patches
|
||||
{
|
||||
@ -25,7 +27,28 @@ namespace SPT.Custom.Patches
|
||||
if (requester == null)
|
||||
{
|
||||
__result = false;
|
||||
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
|
||||
}
|
||||
|
||||
// Do not force bots to be enemies if they are allies
|
||||
if (!__instance.Allies.IsNullOrEmpty() && __instance.Allies.Any(x => x?.Id == requester.Id))
|
||||
{
|
||||
__result = false;
|
||||
return false; // Skip original
|
||||
}
|
||||
|
||||
// Bots should not become hostile with their group members here. This is needed in case mods add mixed groups (i.e. BEAR's and USEC's).
|
||||
if (__instance.GetAllMembers().Any(i => i?.Id == requester.Id))
|
||||
{
|
||||
__result = false;
|
||||
return false; // Skip original
|
||||
}
|
||||
|
||||
@ -35,73 +58,59 @@ namespace SPT.Custom.Patches
|
||||
|| __instance.InitialBotType == WildSpawnType.sectantWarrior
|
||||
|| __instance.InitialBotType == WildSpawnType.sectantPriest
|
||||
|| __instance.InitialBotType == WildSpawnType.sectactPriestEvent
|
||||
|| __instance.InitialBotType == WildSpawnType.ravangeZryachiyEvent)
|
||||
|| __instance.InitialBotType == WildSpawnType.ravangeZryachiyEvent
|
||||
|| __instance.InitialBotType == WildSpawnType.bossZryachiy
|
||||
|| __instance.InitialBotType == WildSpawnType.followerZryachiy)
|
||||
{
|
||||
return true; // Do original code
|
||||
}
|
||||
|
||||
var isEnemy = false; // default not an enemy
|
||||
|
||||
// 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))
|
||||
// Let EFT manage Rogue behavior toward PMC's
|
||||
if (__instance.InitialBotType == WildSpawnType.exUsec
|
||||
&& __instance.Side == EPlayerSide.Savage
|
||||
&& requester.Side != EPlayerSide.Savage)
|
||||
{
|
||||
__result = true;
|
||||
return false; // Skip original
|
||||
return true; // Do original code
|
||||
}
|
||||
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)
|
||||
|
||||
// In all other cases, requester needs to be added to the enemies collection of the bot group if it should be treated as hostile
|
||||
// NOTE: Manually adding enemies is needed as a result of EFT's implementation of PMC's because they are not hostile toward
|
||||
// Scavs (any probably other bot types too)
|
||||
__result = CheckIfPlayerShouldBeEnemy(__instance, requester);
|
||||
if (__result)
|
||||
{
|
||||
__instance.AddEnemy(requester, EBotEnemyCause.checkAddTODO);
|
||||
}
|
||||
|
||||
return false; // Skip original
|
||||
}
|
||||
|
||||
if (__instance.Side == EPlayerSide.Usec)
|
||||
/// <summary>
|
||||
/// Returns true if requester should be an enemy of the bot group
|
||||
/// </summary>
|
||||
/// <param name="__instance"></param>
|
||||
/// <param name="requester"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckIfPlayerShouldBeEnemy(BotsGroup __instance, IPlayer requester)
|
||||
{
|
||||
if (requester.Side == EPlayerSide.Bear || requester.Side == EPlayerSide.Savage ||
|
||||
ShouldAttackUsec(requester))
|
||||
switch (__instance.Side)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
case EPlayerSide.Usec:
|
||||
return requester.Side != EPlayerSide.Usec || ShouldAttackUsec(requester);
|
||||
case EPlayerSide.Bear:
|
||||
return requester.Side != EPlayerSide.Bear || ShouldAttackBear(requester);
|
||||
case EPlayerSide.Savage:
|
||||
return requester.Side != EPlayerSide.Savage;
|
||||
}
|
||||
|
||||
__result = isEnemy;
|
||||
|
||||
return false; // Skip original
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return True when usec default behavior is attack + bot is usec
|
||||
/// </summary>
|
||||
/// <param name="requester"></param>
|
||||
/// <returns>bool</returns>
|
||||
/// <returns></returns>
|
||||
private static bool ShouldAttackUsec(IPlayer requester)
|
||||
{
|
||||
var requesterMind = requester?.AIData?.BotOwner?.Settings?.FileSettings?.Mind;
|
||||
|
Loading…
x
Reference in New Issue
Block a user