//TODO To choose spawn based on IFF, we need to basically generate spawn points on our own in this method!
        public static TNH_Manager.SosigPatrolSquad GeneratePatrol(TNH_Manager instance, Patrol patrol, List <Vector3> SpawnPoints, List <Vector3> ForwardVectors, List <Vector3> PatrolPoints, int patrolIndex)
        {
            TNH_Manager.SosigPatrolSquad squad = new TNH_Manager.SosigPatrolSquad();
            squad.PatrolPoints = new List <Vector3>(PatrolPoints);

            for (int i = 0; i < patrol.PatrolSize && i < SpawnPoints.Count; i++)
            {
                SosigEnemyTemplate template;

                bool allowAllWeapons;

                //If this is a boss, then we can only spawn it once, so add it to the list of spawned bosses
                if (patrol.IsBoss)
                {
                    TNHTweaker.SpawnedBossIndexes.Add(patrolIndex);
                }

                //Select a sosig template from the custom character patrol
                if (i == 0)
                {
                    template        = IM.Instance.odicSosigObjsByID[(SosigEnemyID)LoadedTemplateManager.SosigIDDict[patrol.LeaderType]];
                    allowAllWeapons = true;
                }

                else
                {
                    template        = IM.Instance.odicSosigObjsByID[(SosigEnemyID)LoadedTemplateManager.SosigIDDict[patrol.EnemyType.GetRandom()]];
                    allowAllWeapons = false;
                }

                CustomCharacter character      = LoadedTemplateManager.LoadedCharactersDict[instance.C];
                SosigTemplate   customTemplate = LoadedTemplateManager.LoadedSosigsDict[template];
                FVRObject       droppedObject  = instance.Prefab_HealthPickupMinor;

                //If squad is set to swarm, the first point they path to should be the players current position
                Sosig sosig;
                if (patrol.SwarmPlayer)
                {
                    squad.PatrolPoints[0] = GM.CurrentPlayerBody.transform.position;
                    sosig = SpawnEnemy(customTemplate, character, SpawnPoints[i], Quaternion.LookRotation(ForwardVectors[i], Vector3.up), instance.AI_Difficulty, patrol.IFFUsed, true, squad.PatrolPoints[0], allowAllWeapons);
                    sosig.SetAssaultSpeed(patrol.AssualtSpeed);
                }
                else
                {
                    sosig = SpawnEnemy(customTemplate, character, SpawnPoints[i], Quaternion.LookRotation(ForwardVectors[i], Vector3.up), instance.AI_Difficulty, patrol.IFFUsed, true, squad.PatrolPoints[0], allowAllWeapons);
                    sosig.SetAssaultSpeed(patrol.AssualtSpeed);
                }

                //Handle patrols dropping health
                if (i == 0 && UnityEngine.Random.value < patrol.DropChance)
                {
                    sosig.Links[1].RegisterSpawnOnDestroy(droppedObject);
                }

                squad.Squad.Add(sosig);
            }

            return(squad);
        }
        public static bool GenerateSentryPatrolPatch(
            List <Vector3> SpawnPoints,
            List <Vector3> ForwardVectors,
            List <Vector3> PatrolPoints,
            TNH_Manager __instance,
            List <TNH_Manager.SosigPatrolSquad> ___m_patrolSquads,
            ref float ___m_timeTilPatrolCanSpawn,
            ref TNH_Manager.SosigPatrolSquad __result
            )
        {
            TNHTweakerLogger.Log("TNHTWEAKER -- Generating a sentry patrol -- There are currently " + ___m_patrolSquads.Count + " patrols active", TNHTweakerLogger.LogType.TNH);

            CustomCharacter character = LoadedTemplateManager.LoadedCharactersDict[__instance.C];
            Level           currLevel = character.GetCurrentLevel(__instance.m_curLevel);

            if (currLevel.Patrols.Count < 1)
            {
                return(false);
            }

            //Get a valid patrol index, and exit if there are no valid patrols
            int patrolIndex = GetValidPatrolIndex(currLevel.Patrols);

            if (patrolIndex == -1)
            {
                TNHTweakerLogger.Log("TNHTWEAKER -- No valid patrols can spawn", TNHTweakerLogger.LogType.TNH);
                ___m_timeTilPatrolCanSpawn = 999;

                //Returning an empty squad is the easiest way to not generate a patrol when no valid ones are found
                //This could cause strange and unpredictable behaviour
                //Good luck!
                __result = new TNH_Manager.SosigPatrolSquad();
                __result.PatrolPoints = new List <Vector3>();
                __result.Squad        = new List <Sosig>();

                return(false);
            }

            TNHTweakerLogger.Log("TNHTWEAKER -- Valid patrol found", TNHTweakerLogger.LogType.TNH);

            Patrol patrol = currLevel.Patrols[patrolIndex];

            TNH_Manager.SosigPatrolSquad squad = GeneratePatrol(__instance, patrol, SpawnPoints, ForwardVectors, PatrolPoints, patrolIndex);

            //We don't add this patrol because it's tracked outside of this method
            //___m_patrolSquads.Add(squad);

            if (__instance.EquipmentMode == TNHSetting_EquipmentMode.Spawnlocking)
            {
                ___m_timeTilPatrolCanSpawn = patrol.PatrolCadence;
            }
            else
            {
                ___m_timeTilPatrolCanSpawn = patrol.PatrolCadenceLimited;
            }

            __result = squad;
            return(false);
        }
        public static bool GenerateValidPatrolReplacement(TNH_PatrolChallenge P, int curStandardIndex, int excludeHoldIndex, bool isStart, TNH_Manager __instance, TNH_Progression.Level ___m_curLevel, List <TNH_Manager.SosigPatrolSquad> ___m_patrolSquads, ref float ___m_timeTilPatrolCanSpawn)
        {
            TNHTweakerLogger.Log("TNHTWEAKER -- Generating a patrol -- There are currently " + ___m_patrolSquads.Count + " patrols active", TNHTweakerLogger.LogType.TNH);

            if (P.Patrols.Count < 1)
            {
                return(false);
            }

            CustomCharacter character = LoadedTemplateManager.LoadedCharactersDict[__instance.C];
            Level           currLevel = character.GetCurrentLevel(__instance.m_curLevel);

            //Get a valid patrol index, and exit if there are no valid patrols
            int patrolIndex = GetValidPatrolIndex(currLevel.Patrols);

            if (patrolIndex == -1)
            {
                TNHTweakerLogger.Log("TNHTWEAKER -- No valid patrols can spawn", TNHTweakerLogger.LogType.TNH);
                ___m_timeTilPatrolCanSpawn = 999;
                return(false);
            }

            TNHTweakerLogger.Log("TNHTWEAKER -- Valid patrol found", TNHTweakerLogger.LogType.TNH);

            Patrol patrol = currLevel.Patrols[patrolIndex];

            List <int> validLocations = new List <int>();
            float      minDist        = __instance.TAHReticle.Range * 1.2f;

            //Get a safe starting point for the patrol to spawn
            TNH_SafePositionMatrix.PositionEntry startingEntry;
            if (isStart)
            {
                startingEntry = __instance.SafePosMatrix.Entries_SupplyPoints[curStandardIndex];
            }
            else
            {
                startingEntry = __instance.SafePosMatrix.Entries_HoldPoints[curStandardIndex];
            }


            for (int i = 0; i < startingEntry.SafePositions_HoldPoints.Count; i++)
            {
                if (i != excludeHoldIndex && startingEntry.SafePositions_HoldPoints[i])
                {
                    float playerDist = Vector3.Distance(GM.CurrentPlayerBody.transform.position, __instance.HoldPoints[i].transform.position);
                    if (playerDist > minDist)
                    {
                        validLocations.Add(i);
                    }
                }
            }


            if (validLocations.Count < 1)
            {
                return(false);
            }
            validLocations.Shuffle();

            TNH_Manager.SosigPatrolSquad squad = GeneratePatrol(validLocations[0], __instance, patrol, patrolIndex);
            ___m_patrolSquads.Add(squad);

            if (__instance.EquipmentMode == TNHSetting_EquipmentMode.Spawnlocking)
            {
                ___m_timeTilPatrolCanSpawn = patrol.PatrolCadence;
            }
            else
            {
                ___m_timeTilPatrolCanSpawn = patrol.PatrolCadenceLimited;
            }

            return(false);
        }