Decompiled source of H3TVR v1.1.8
H3TVR.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FistVR; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks; using UnityEngine; using UnityEngine.UI; using Valve.VR; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace H3TVR { public enum SpawnPriority { Low, Normal, High, Immediate } public class AdvancedChatSosigSpawner : MonoBehaviour { public struct ChatSosigStats { public int ActiveAllies; public int ActiveEnemies; public int QueueLength; public int TotalSpawned; } public struct SosigStats { public int Allies; public int Enemies; public int Queued; public int TotalActive; public bool ChatWatcherActive; } [CompilerGenerated] private sealed class <CleanupCoroutine>d__73 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AdvancedChatSosigSpawner <>4__this; private WaitForSeconds <wait>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CleanupCoroutine>d__73(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <wait>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <wait>5__1 = new WaitForSeconds(10f); break; case 1: <>1__state = -1; <>4__this.CleanupDeadSosigs(); break; } <>2__current = <wait>5__1; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <DelayedInitialization>d__50 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AdvancedChatSosigSpawner <>4__this; private float <timeout>5__1; private float <elapsed>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedInitialization>d__50(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <timeout>5__1 = 10f; <elapsed>5__2 = 0f; goto IL_007a; case 1: <>1__state = -1; <elapsed>5__2 += 0.5f; goto IL_007a; case 2: { <>1__state = -1; <>4__this.BuildTemplateCache(); ManualLogSource logger = <>4__this.logger; if (logger != null) { logger.LogInfo((object)"Delayed initialization complete - Template cache ready"); } return false; } IL_007a: if ((Object)(object)ManagerSingleton<IM>.Instance == (Object)null && <elapsed>5__2 < <timeout>5__1) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } if ((Object)(object)ManagerSingleton<IM>.Instance == (Object)null) { ManualLogSource logger2 = <>4__this.logger; if (logger2 != null) { logger2.LogError((object)"IM.Instance failed to initialize within timeout"); } return false; } <>2__current = null; <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <InitializeChatWatcher>d__48 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AdvancedChatSosigSpawner <>4__this; private GameObject <chatWatcherGO>5__1; private Exception <ex>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitializeChatWatcher>d__48(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <chatWatcherGO>5__1 = null; <ex>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; try { <>4__this.chatWatcher = Object.FindObjectOfType<ChatWatcher>(); if ((Object)(object)<>4__this.chatWatcher == (Object)null) { <chatWatcherGO>5__1 = new GameObject("H3TVR_ChatWatcher"); <>4__this.chatWatcher = <chatWatcherGO>5__1.AddComponent<ChatWatcher>(); <>4__this.chatWatcher.Initialize(<>4__this.plugin, <>4__this.logger, <>4__this); Object.DontDestroyOnLoad((Object)(object)<chatWatcherGO>5__1); <>4__this.chatWatcherEnabled = true; ManualLogSource logger = <>4__this.logger; if (logger != null) { logger.LogInfo((object)"ChatWatcher integration enabled - file-based chat spawning active"); } <chatWatcherGO>5__1 = null; } else { <>4__this.chatWatcherEnabled = true; ManualLogSource logger2 = <>4__this.logger; if (logger2 != null) { logger2.LogInfo((object)"ChatWatcher already exists - using existing instance"); } } } catch (Exception ex) { <ex>5__2 = ex; ManualLogSource logger3 = <>4__this.logger; if (logger3 != null) { logger3.LogError((object)("Failed to initialize ChatWatcher: " + <ex>5__2.Message)); } <>4__this.chatWatcherEnabled = false; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LinkSteamFriendsIntegration>d__49 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AdvancedChatSosigSpawner <>4__this; private SteamFriendsIntegration <steamIntegration>5__1; private Exception <ex>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LinkSteamFriendsIntegration>d__49(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <steamIntegration>5__1 = null; <ex>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; try { <steamIntegration>5__1 = <>4__this.plugin?.GetSteamFriendsIntegration(); if ((Object)(object)<steamIntegration>5__1 != (Object)null && <steamIntegration>5__1.IsAvailable()) { <>4__this.steamFriends = <steamIntegration>5__1; ManualLogSource logger = <>4__this.logger; if (logger != null) { logger.LogInfo((object)"Steam Friends integration linked successfully"); } } else { ManualLogSource logger2 = <>4__this.logger; if (logger2 != null) { logger2.LogInfo((object)"Steam Friends integration not available"); } } <steamIntegration>5__1 = null; } catch (Exception ex) { <ex>5__2 = ex; ManualLogSource logger3 = <>4__this.logger; if (logger3 != null) { logger3.LogWarning((object)("Failed to link Steam Friends integration: " + <ex>5__2.Message)); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadTemplatesDelayed>d__54 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AdvancedChatSosigSpawner <>4__this; private SosigEnemyTemplate[] <sosigObjects>5__1; private SosigEnemyTemplate[] <>s__2; private int <>s__3; private SosigEnemyTemplate <template>5__4; private Exception <ex>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadTemplatesDelayed>d__54(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <sosigObjects>5__1 = null; <>s__2 = null; <template>5__4 = null; <ex>5__5 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; try { <sosigObjects>5__1 = Resources.FindObjectsOfTypeAll<SosigEnemyTemplate>(); if (<sosigObjects>5__1 != null && <sosigObjects>5__1.Length != 0) { <>4__this.cachedSosigTemplates = <sosigObjects>5__1; <>s__2 = <>4__this.cachedSosigTemplates; for (<>s__3 = 0; <>s__3 < <>s__2.Length; <>s__3++) { <template>5__4 = <>s__2[<>s__3]; if ((Object)(object)<template>5__4 != (Object)null) { <>4__this.allyTemplates.Add(<template>5__4); <>4__this.enemyTemplates.Add(<template>5__4); } <template>5__4 = null; } <>s__2 = null; ManualLogSource logger = <>4__this.logger; if (logger != null) { logger.LogInfo((object)$"Loaded {<>4__this.allyTemplates.Count} legacy sosig templates (fallback)"); } } else { ManualLogSource logger2 = <>4__this.logger; if (logger2 != null) { logger2.LogWarning((object)"No legacy sosig templates found - using modern spawn system only"); } } <sosigObjects>5__1 = null; } catch (Exception ex) { <ex>5__5 = ex; ManualLogSource logger3 = <>4__this.logger; if (logger3 != null) { logger3.LogError((object)("Template loading failed: " + <ex>5__5.Message)); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <UpdateSosigsCoroutine>d__70 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AdvancedChatSosigSpawner <>4__this; private WaitForSeconds <wait>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <UpdateSosigsCoroutine>d__70(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <wait>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <wait>5__1 = new WaitForSeconds(1f); break; case 1: <>1__state = -1; <>4__this.UpdateAllySosigs(); <>4__this.UpdateEnemySosigs(); break; } <>2__current = <wait>5__1; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static List<Sosig> spawnedChatters = new List<Sosig>(); public static List<Sosig> spawnedEnemyChatters = new List<Sosig>(); private H3TVRImproved plugin; private ManualLogSource logger; private SteamFriendsIntegration steamFriends; private ChatWatcher chatWatcher; private bool chatWatcherEnabled = false; [Header("Sosig Templates")] public SosigEnemyID defaultAllyID = (SosigEnemyID)100; public SosigEnemyID defaultEnemyID = (SosigEnemyID)108; public List<SosigEnemyTemplate> allyTemplates = new List<SosigEnemyTemplate>(); public List<SosigEnemyTemplate> enemyTemplates = new List<SosigEnemyTemplate>(); private SosigEnemyTemplate[] cachedSosigTemplates; private List<SosigEnemyID> allyPoolIDs = new List<SosigEnemyID>(); private List<SosigEnemyID> enemyPoolIDs = new List<SosigEnemyID>(); public GameObject nameplateAlly; public GameObject nameplateEnemy; public string SpawnerName = "ChatUser"; private List<string> allyNames = new List<string>(); private List<string> enemyNames = new List<string>(); private ConfigEntry<int> maxAllySosigs; private ConfigEntry<int> maxEnemySosigs; private ConfigEntry<float> spawnCooldown; private ConfigEntry<bool> enableNameplates; private ConfigEntry<float> sosigLifetime; private ConfigEntry<bool> enableAutoCleanup; private ConfigEntry<float> enemyIFF; private ConfigEntry<float> followDistance; private ConfigEntry<float> enemyAggressionDistance; private ConfigEntry<bool> useModernSpawnSystem; private ConfigEntry<string> allySosigPool; private ConfigEntry<string> enemySosigPool; private ConfigEntry<bool> enableArmorCustomization; private ConfigEntry<string> allyNamesFilePath; private ConfigEntry<string> enemyNamesFilePath; private ConfigEntry<bool> useRandomNames; private ConfigEntry<int> maxSosigsPerUser; private ConfigEntry<bool> enableCoverAI; private ConfigEntry<float> sosigUpdateInterval; private ConfigEntry<bool> enableChatWatcherIntegration; private float lastSpawnTime; private static readonly LayerMask EnvironmentMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { "Environment" })); private Dictionary<string, int> userSosigCounts = new Dictionary<string, int>(); private Dictionary<string, float> userLastSpawnTime = new Dictionary<string, float>(); private Dictionary<SosigEnemyID, SosigEnemyTemplate> templateCache = new Dictionary<SosigEnemyID, SosigEnemyTemplate>(); public static AdvancedChatSosigSpawner Instance { get; private set; } public void Initialize(H3TVRImproved pluginInstance, ManualLogSource logSource) { if ((Object)(object)Instance != (Object)null) { Object.Destroy((Object)(object)this); return; } Instance = this; plugin = pluginInstance; logger = logSource; InitializeConfiguration(); InitializeSosigTemplates(); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)"Advanced Chat Sosig Spawner initialized (Update 120 TNH System, ChatWatcher compatible)"); } ((MonoBehaviour)this).StartCoroutine(DelayedInitialization()); ((MonoBehaviour)this).StartCoroutine(UpdateSosigsCoroutine()); ((MonoBehaviour)this).StartCoroutine(CleanupCoroutine()); ((MonoBehaviour)this).StartCoroutine(LinkSteamFriendsIntegration()); if (enableChatWatcherIntegration.Value) { ((MonoBehaviour)this).StartCoroutine(InitializeChatWatcher()); } } private IEnumerator InitializeChatWatcher() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeChatWatcher>d__48(0) { <>4__this = this }; } private IEnumerator LinkSteamFriendsIntegration() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LinkSteamFriendsIntegration>d__49(0) { <>4__this = this }; } private IEnumerator DelayedInitialization() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedInitialization>d__50(0) { <>4__this = this }; } private void InitializeConfiguration() { H3TVRImproved h3TVRImproved = plugin; if (((h3TVRImproved != null) ? ((BaseUnityPlugin)h3TVRImproved).Config : null) == null) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)"Plugin config is null"); } return; } try { maxAllySosigs = ((BaseUnityPlugin)plugin).Config.Bind<int>("Chat Spawner", "MaxAllySosigs", 8, "Maximum ally sosigs"); maxEnemySosigs = ((BaseUnityPlugin)plugin).Config.Bind<int>("Chat Spawner", "MaxEnemySosigs", 8, "Maximum enemy sosigs"); spawnCooldown = ((BaseUnityPlugin)plugin).Config.Bind<float>("Chat Spawner", "SpawnCooldown", 2f, "Cooldown between spawns"); enableNameplates = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Chat Spawner", "EnableNameplates", true, "Show nameplates above sosigs"); sosigLifetime = ((BaseUnityPlugin)plugin).Config.Bind<float>("Chat Spawner", "SosigLifetime", 300f, "Sosig lifetime in seconds (0 = infinite)"); enableAutoCleanup = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Chat Spawner", "EnableAutoCleanup", true, "Auto cleanup dead sosigs"); enemyIFF = ((BaseUnityPlugin)plugin).Config.Bind<float>("Chat Spawner", "EnemyIFF", 1f, "Enemy IFF code"); followDistance = ((BaseUnityPlugin)plugin).Config.Bind<float>("Chat Spawner", "FollowDistance", 6f, "Distance for allies to follow player"); enemyAggressionDistance = ((BaseUnityPlugin)plugin).Config.Bind<float>("Chat Spawner", "EnemyAggressionDistance", 20f, "Distance at which enemies become aggressive"); useModernSpawnSystem = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Chat Spawner", "UseModernSpawnSystem", true, "Use Update 120's modern TNH sosig spawn system (recommended)"); allySosigPool = ((BaseUnityPlugin)plugin).Config.Bind<string>("Chat Spawner", "AllySosigPool", "M_Swat_Scout,M_Swat_Sniper,M_Swat_Breacher", "Comma-separated list of SosigEnemyID names for allies\nValid IDs include: M_Swat_Scout, M_Swat_Sniper, M_Swat_Breacher, M_Swat_Heavy, M_Swat_Riot, M_Merc_Scout, M_Merc_Sniper, M_Merc_Heavy, M_Zombies_Melee, M_Zombies_Ranged, M_Soldier_Scout, M_Soldier_Sniper, M_Soldier_Heavy, and many more. Check H3VR's SosigEnemyID enum for complete list."); enemySosigPool = ((BaseUnityPlugin)plugin).Config.Bind<string>("Chat Spawner", "EnemySosigPool", "M_Swat_Heavy,M_Swat_Breacher,M_Swat_Sniper", "Comma-separated list of SosigEnemyID names for enemies\nValid IDs include: M_Swat_Heavy, M_Swat_Riot, M_Swat_Breacher, M_Merc_Heavy, M_Zombies_Ranged, M_Soldier_Heavy, M_PMC_Heavy, and many more. Check H3VR's SosigEnemyID enum for complete list."); enableArmorCustomization = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Chat Spawner Advanced", "EnableArmorCustomization", true, "Enable armor customization system"); allyNamesFilePath = ((BaseUnityPlugin)plugin).Config.Bind<string>("Chat Spawner Advanced", "AllyNamesFilePath", "Plugins/H3TwitchTools/AllyNames.ini", "File path for ally names list (INI file)"); enemyNamesFilePath = ((BaseUnityPlugin)plugin).Config.Bind<string>("Chat Spawner Advanced", "EnemyNamesFilePath", "Plugins/H3TwitchTools/EnemyNames.ini", "File path for enemy names list (INI file)"); useRandomNames = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Chat Spawner Advanced", "UseRandomNames", true, "Use random names from name lists"); maxSosigsPerUser = ((BaseUnityPlugin)plugin).Config.Bind<int>("Chat Spawner Advanced", "MaxSosigsPerUser", 2, "Maximum sosigs per Twitch user"); enableCoverAI = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Chat Spawner Advanced", "EnableCoverAI", true, "Enable advanced cover-taking AI behavior"); sosigUpdateInterval = ((BaseUnityPlugin)plugin).Config.Bind<float>("Chat Spawner Advanced", "UpdateInterval", 1f, "Interval between sosig AI updates (seconds)"); enableChatWatcherIntegration = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Chat Spawner Integration", "EnableChatWatcher", true, "Enable ChatWatcher integration for file-based Twitch chat spawning\nWhen enabled, sosigs will spawn automatically from chat files (H3TwitchTools compatible)"); ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)"Configuration initialized successfully (ChatWatcher integration ready)"); } } catch (Exception ex) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogError((object)("Config init failed: " + ex.Message)); } } } private void InitializeSosigTemplates() { try { InitializeSosigPools(); ((MonoBehaviour)this).StartCoroutine(LoadTemplatesDelayed()); BuildTemplateCache(); } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Template initialization failed: " + ex.Message)); } } } private void InitializeSosigPools() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) try { string[] array = allySosigPool.Value.Split(new char[1] { ',' }); string[] array2 = array; foreach (string text in array2) { try { SosigEnemyID item = (SosigEnemyID)Enum.Parse(typeof(SosigEnemyID), text.Trim()); allyPoolIDs.Add(item); } catch { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)("Invalid ally sosig ID: " + text)); } } } string[] array3 = enemySosigPool.Value.Split(new char[1] { ',' }); string[] array4 = array3; foreach (string text2 in array4) { try { SosigEnemyID item2 = (SosigEnemyID)Enum.Parse(typeof(SosigEnemyID), text2.Trim()); enemyPoolIDs.Add(item2); } catch { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogWarning((object)("Invalid enemy sosig ID: " + text2)); } } } if (allyPoolIDs.Count == 0) { allyPoolIDs.Add((SosigEnemyID)100); allyPoolIDs.Add((SosigEnemyID)102); } if (enemyPoolIDs.Count == 0) { enemyPoolIDs.Add((SosigEnemyID)108); enemyPoolIDs.Add((SosigEnemyID)109); } ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogInfo((object)$"Loaded {allyPoolIDs.Count} ally sosig types, {enemyPoolIDs.Count} enemy sosig types"); } } catch (Exception ex) { ManualLogSource obj6 = logger; if (obj6 != null) { obj6.LogError((object)("Failed to initialize sosig pools: " + ex.Message)); } allyPoolIDs.Add((SosigEnemyID)100); enemyPoolIDs.Add((SosigEnemyID)108); } } private IEnumerator LoadTemplatesDelayed() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadTemplatesDelayed>d__54(0) { <>4__this = this }; } private void LoadNameLists() { try { if (File.Exists(allyNamesFilePath.Value)) { string[] array = File.ReadAllLines(allyNamesFilePath.Value); string[] array2 = array; foreach (string text in array2) { string text2 = text.Trim(); if (!string.IsNullOrEmpty(text2) && !text2.StartsWith("#") && !text2.StartsWith(";")) { allyNames.Add(text2); } } ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)$"Loaded {allyNames.Count} ally names"); } } else { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("Ally names file not found: " + allyNamesFilePath.Value)); } CreateDefaultNameFile(allyNamesFilePath.Value, isAlly: true); } if (File.Exists(enemyNamesFilePath.Value)) { string[] array3 = File.ReadAllLines(enemyNamesFilePath.Value); string[] array4 = array3; foreach (string text3 in array4) { string text4 = text3.Trim(); if (!string.IsNullOrEmpty(text4) && !text4.StartsWith("#") && !text4.StartsWith(";")) { enemyNames.Add(text4); } } ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)$"Loaded {enemyNames.Count} enemy names"); } } else { ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogWarning((object)("Enemy names file not found: " + enemyNamesFilePath.Value)); } CreateDefaultNameFile(enemyNamesFilePath.Value, isAlly: false); } } catch (Exception ex) { ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogError((object)("Failed to load name lists: " + ex.Message)); } } } private void CreateDefaultNameFile(string path, bool isAlly) { try { string directoryName = Path.GetDirectoryName(path); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } string[] array = ((!isAlly) ? new string[6] { "# Enemy Sosig Names", "Hostile Bot", "Attacker", "Enemy", "Threat", "Opponent" } : new string[6] { "# Ally Sosig Names", "Friendly Bot", "Guardian", "Protector", "Ally", "Helper" }); File.WriteAllLines(path, array); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("Created default name file: " + path)); } if (isAlly) { allyNames.AddRange(array.Skip(1)); } else { enemyNames.AddRange(array.Skip(1)); } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("Failed to create default name file: " + ex.Message)); } } } public void SpawningSequence(string username) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) try { if (spawnedChatters.Count >= maxAllySosigs.Value) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)$"Max ally sosigs reached ({maxAllySosigs.Value}) - cannot spawn for {username}"); } return; } if (Time.time - lastSpawnTime < spawnCooldown.Value) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)$"Spawn cooldown active ({spawnCooldown.Value}s) - skipping {username}"); } return; } if (userSosigCounts.ContainsKey(username) && userSosigCounts[username] >= maxSosigsPerUser.Value) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogWarning((object)$"User {username} has reached max sosigs limit ({maxSosigsPerUser.Value})"); } return; } Vector3 pos = CalculateAllySpawnPoint(); Quaternion identity = Quaternion.identity; Sosig val = null; if (useModernSpawnSystem.Value) { SosigEnemyID randomAllyID = GetRandomAllyID(); val = SpawnSosigModern(randomAllyID, pos, identity, 0); } if ((Object)(object)val == (Object)null) { SosigEnemyTemplate randomTemplate = GetRandomTemplate(isAlly: true); if ((Object)(object)randomTemplate != (Object)null) { val = SpawnSosigLegacy(randomTemplate, pos, identity, 0); } } if ((Object)(object)val != (Object)null) { SetupAllyBehavior(val); string text = username; if (useRandomNames.Value) { text = GetRandomName(isAlly: true); ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogInfo((object)("Using random ally name from INI: " + text + " (spawned by " + username + ")")); } } if (enableNameplates.Value && (Object)(object)nameplateAlly != (Object)null) { AttachNameplate(val, text, nameplateAlly, isEnemy: false); } spawnedChatters.Add(val); lastSpawnTime = Time.time; if (userSosigCounts.ContainsKey(username)) { userSosigCounts[username]++; } else { userSosigCounts.Add(username, 1); } ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogInfo((object)$"✓ Spawned ally sosig '{text}' for {username} ({spawnedChatters.Count}/{maxAllySosigs.Value})"); } } else { ManualLogSource obj6 = logger; if (obj6 != null) { obj6.LogError((object)("Failed to spawn ally sosig for " + username)); } } } catch (Exception ex) { ManualLogSource obj7 = logger; if (obj7 != null) { obj7.LogError((object)("Ally spawn failed for " + username + ": " + ex.Message)); } } } public void SpawningSequenceEnemy(int IFF, string username) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) try { if (spawnedEnemyChatters.Count >= maxEnemySosigs.Value) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)$"Max enemy sosigs reached ({maxEnemySosigs.Value}) - cannot spawn for {username}"); } return; } if (Time.time - lastSpawnTime < spawnCooldown.Value) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)$"Spawn cooldown active ({spawnCooldown.Value}s) - skipping {username}"); } return; } Vector3 pos = CalculateEnemySpawnPoint(); Quaternion identity = Quaternion.identity; int iFF = ((IFF > 0) ? IFF : Mathf.Max(1, (int)enemyIFF.Value)); Sosig val = null; if (useModernSpawnSystem.Value) { SosigEnemyID randomEnemyID = GetRandomEnemyID(); val = SpawnSosigModern(randomEnemyID, pos, identity, iFF); } if ((Object)(object)val == (Object)null) { SosigEnemyTemplate randomTemplate = GetRandomTemplate(isAlly: false); if ((Object)(object)randomTemplate != (Object)null) { val = SpawnSosigLegacy(randomTemplate, pos, identity, iFF); } } if ((Object)(object)val != (Object)null) { SetupEnemyBehavior(val); string text = username; if (useRandomNames.Value) { text = GetRandomName(isAlly: false); ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("Using random enemy name from INI: " + text + " (spawned by " + username + ")")); } } if (enableNameplates.Value && (Object)(object)nameplateEnemy != (Object)null) { AttachNameplate(val, text, nameplateEnemy, isEnemy: true); } spawnedEnemyChatters.Add(val); lastSpawnTime = Time.time; ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogInfo((object)$"✓ Spawned enemy sosig '{text}' for {username} ({spawnedEnemyChatters.Count}/{maxEnemySosigs.Value})"); } } else { ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogError((object)("Failed to spawn enemy sosig for " + username)); } } } catch (Exception ex) { ManualLogSource obj6 = logger; if (obj6 != null) { obj6.LogError((object)("Enemy spawn failed for " + username + ": " + ex.Message)); } } } private Sosig SpawnSosigModern(SosigEnemyID enemyID, Vector3 pos, Quaternion rot, int IFF) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) try { if (templateCache == null || templateCache.Count == 0) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)"Template cache not ready, attempting to rebuild..."); } BuildTemplateCache(); if (templateCache.Count == 0) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)"Template cache rebuild failed - falling back to legacy spawn"); } return null; } } SosigEnemyTemplate val = null; if (templateCache.ContainsKey(enemyID)) { val = templateCache[enemyID]; } if ((Object)(object)val == (Object)null && (Object)(object)ManagerSingleton<IM>.Instance != (Object)null && ManagerSingleton<IM>.Instance.odicSosigObjsByID != null && ManagerSingleton<IM>.Instance.odicSosigObjsByID.ContainsKey(enemyID)) { val = ManagerSingleton<IM>.Instance.odicSosigObjsByID[enemyID]; templateCache[enemyID] = val; ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)$"Cached template for {enemyID} from IM.Instance"); } } if ((Object)(object)val == (Object)null) { ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogWarning((object)$"Template not in cache for {enemyID}, searching Resources..."); } SosigEnemyTemplate[] array = Resources.FindObjectsOfTypeAll<SosigEnemyTemplate>(); SosigEnemyTemplate[] array2 = array; foreach (SosigEnemyTemplate val2 in array2) { if ((Object)(object)val2 != (Object)null && val2.SosigEnemyID == enemyID) { val = val2; templateCache[enemyID] = val; ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogInfo((object)$"Found and cached template for {enemyID}"); } break; } } } if ((Object)(object)val == (Object)null) { ManualLogSource obj6 = logger; if (obj6 != null) { obj6.LogError((object)$"Could not find template for SosigEnemyID: {enemyID}"); } return null; } Sosig val3 = SpawnSosigLegacy(val, pos, rot, IFF); if ((Object)(object)val3 == (Object)null) { ManualLogSource obj7 = logger; if (obj7 != null) { obj7.LogError((object)"Modern sosig spawn returned null"); } return null; } try { if (val.ConfigTemplates != null && val.ConfigTemplates.Count > 0) { SosigConfigTemplate val4 = val.ConfigTemplates[Random.Range(0, val.ConfigTemplates.Count)]; val3.Configure(val4); } } catch (Exception ex) { ManualLogSource obj8 = logger; if (obj8 != null) { obj8.LogWarning((object)("Failed to apply config template: " + ex.Message)); } } val3.E.IFFCode = IFF; val3.SetIFF(IFF); try { val3.Inventory.FillAllAmmo(); } catch (Exception ex2) { ManualLogSource obj9 = logger; if (obj9 != null) { obj9.LogWarning((object)("Failed to fill ammo: " + ex2.Message)); } } try { if (val.OutfitConfig != null && val.OutfitConfig.Count > 0) { ApplyOutfit(val3, val.OutfitConfig[Random.Range(0, val.OutfitConfig.Count)]); } } catch (Exception ex3) { ManualLogSource obj10 = logger; if (obj10 != null) { obj10.LogWarning((object)("Failed to apply outfit: " + ex3.Message)); } } return val3; } catch (Exception ex4) { ManualLogSource obj11 = logger; if (obj11 != null) { obj11.LogError((object)("Modern sosig spawn failed: " + ex4.Message + "\n" + ex4.StackTrace)); } return null; } } private Sosig SpawnSosigLegacy(SosigEnemyTemplate template, Vector3 pos, Quaternion rot, int IFF) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)template == (Object)null || template.SosigPrefabs == null || template.SosigPrefabs.Count == 0) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)"Invalid template"); } return null; } FVRObject val = template.SosigPrefabs[Random.Range(0, template.SosigPrefabs.Count)]; if ((Object)(object)((val != null) ? ((AnvilAsset)val).GetGameObject() : null) == (Object)null) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)"Invalid prefab"); } return null; } GameObject val2 = Object.Instantiate<GameObject>(((AnvilAsset)val).GetGameObject(), pos, rot); Sosig componentInChildren = val2.GetComponentInChildren<Sosig>(); if ((Object)(object)componentInChildren == (Object)null) { Object.Destroy((Object)(object)val2); return null; } if (template.ConfigTemplates != null && template.ConfigTemplates.Count > 0) { SosigConfigTemplate val3 = template.ConfigTemplates[Random.Range(0, template.ConfigTemplates.Count)]; if ((Object)(object)val3 != (Object)null) { componentInChildren.Configure(val3); } } componentInChildren.E.IFFCode = IFF; if (IFF < componentInChildren.Priority.IFFChart.Length) { componentInChildren.Priority.IFFChart[IFF] = true; } EquipWeapons(componentInChildren, template, pos, rot); if (template.OutfitConfig != null && template.OutfitConfig.Count > 0) { ApplyOutfit(componentInChildren, template.OutfitConfig[Random.Range(0, template.OutfitConfig.Count)]); } return componentInChildren; } catch (Exception ex) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogError((object)("Legacy sosig spawn failed: " + ex.Message)); } return null; } } private void EquipWeapons(Sosig sosig, SosigEnemyTemplate template, Vector3 pos, Quaternion rot) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) try { if (template.WeaponOptions != null && template.WeaponOptions.Count > 0) { EquipWeapon(sosig, template.WeaponOptions[Random.Range(0, template.WeaponOptions.Count)], pos, rot); } if (template.WeaponOptions_Secondary != null && template.WeaponOptions_Secondary.Count > 0) { EquipWeapon(sosig, template.WeaponOptions_Secondary[Random.Range(0, template.WeaponOptions_Secondary.Count)], pos, rot); } if (template.WeaponOptions_Tertiary != null && template.WeaponOptions_Tertiary.Count > 0) { EquipWeapon(sosig, template.WeaponOptions_Tertiary[Random.Range(0, template.WeaponOptions_Tertiary.Count)], pos, rot); } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Weapon equip failed: " + ex.Message)); } } } private void EquipWeapon(Sosig sosig, FVRObject weaponObj, Vector3 pos, Quaternion rot) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 //IL_008d: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)((weaponObj != null) ? ((AnvilAsset)weaponObj).GetGameObject() : null) == (Object)null) { return; } GameObject val = Object.Instantiate<GameObject>(((AnvilAsset)weaponObj).GetGameObject(), pos + Vector3.up * 0.1f, rot); SosigWeapon component = val.GetComponent<SosigWeapon>(); if ((Object)(object)component != (Object)null) { component.SetAutoDestroy(true); component.O.SpawnLockable = false; component.SetAmmoClamping(true); component.IsShakeReloadable = false; if ((int)component.Type == 0) { sosig.Inventory.FillAmmoWithType(component.AmmoType); } sosig.Inventory.Init(); sosig.Inventory.FillAllAmmo(); sosig.InitHands(); sosig.ForceEquip(component); } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Weapon equip error: " + ex.Message)); } } } private void ApplyOutfit(Sosig sosig, SosigOutfitConfig outfit) { try { if (!((Object)(object)outfit == (Object)null) && sosig.Links.Count >= 4) { if (Random.value < outfit.Chance_Headwear) { SpawnAccessory(outfit.Headwear, sosig.Links[0]); } if (Random.value < outfit.Chance_Facewear) { SpawnAccessory(outfit.Facewear, sosig.Links[0]); } if (Random.value < outfit.Chance_Eyewear) { SpawnAccessory(outfit.Eyewear, sosig.Links[0]); } if (Random.value < outfit.Chance_Torsowear) { SpawnAccessory(outfit.Torsowear, sosig.Links[1]); } if (Random.value < outfit.Chance_Pantswear) { SpawnAccessory(outfit.Pantswear, sosig.Links[2]); } if (sosig.Links.Count > 3 && Random.value < outfit.Chance_Pantswear_Lower) { SpawnAccessory(outfit.Pantswear_Lower, sosig.Links[3]); } if (Random.value < outfit.Chance_Backpacks) { SpawnAccessory(outfit.Backpacks, sosig.Links[1]); } if (Random.value < outfit.Chance_TorosDecoration) { SpawnAccessory(outfit.TorosDecoration, sosig.Links[1]); } } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Outfit apply failed: " + ex.Message)); } } } private void SpawnAccessory(List<FVRObject> accessories, SosigLink link) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (accessories == null || accessories.Count == 0 || (Object)(object)link == (Object)null) { return; } try { FVRObject val = accessories[Random.Range(0, accessories.Count)]; if (!((Object)(object)((val != null) ? ((AnvilAsset)val).GetGameObject() : null) == (Object)null)) { GameObject val2 = Object.Instantiate<GameObject>(((AnvilAsset)val).GetGameObject(), ((Component)link).transform.position, ((Component)link).transform.rotation); val2.transform.SetParent(((Component)link).transform); SosigWearable component = val2.GetComponent<SosigWearable>(); if ((Object)(object)component != (Object)null) { component.RegisterWearable(link); } } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Accessory spawn failed: " + ex.Message)); } } } private void SetupAllyBehavior(Sosig sosig) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) try { FVRPlayerBody currentPlayerBody = GM.CurrentPlayerBody; object obj; if (currentPlayerBody == null) { obj = null; } else { Transform head = currentPlayerBody.Head; obj = ((head != null) ? ((Component)head).transform : null); } if (!((Object)obj == (Object)null)) { Vector3 position = ((Component)GM.CurrentPlayerBody.Head).transform.position; float num = (float)(Random.Range(0, 2) * 2 - 1) * Random.Range(0.75f, 2.5f); float num2 = (float)(Random.Range(0, 2) * 2 - 1) * Random.Range(0.75f, 2.5f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(position.x + num, position.y, position.z + num2); sosig.CommandAssaultPoint(val); sosig.FallbackOrder = (SosigOrder)4; } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("Ally behavior setup failed: " + ex.Message)); } } } private void SetupEnemyBehavior(Sosig sosig) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) try { FVRPlayerBody currentPlayerBody = GM.CurrentPlayerBody; if (!((Object)(object)((currentPlayerBody != null) ? ((Component)currentPlayerBody).transform : null) == (Object)null)) { sosig.CommandAssaultPoint(((Component)GM.CurrentPlayerBody).transform.position); sosig.FallbackOrder = (SosigOrder)4; } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Enemy behavior setup failed: " + ex.Message)); } } } private void AttachNameplate(Sosig sosig, string name, GameObject nameplatePrefab, bool isEnemy) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) try { if (sosig.Links.Count != 0 && !((Object)(object)nameplatePrefab == (Object)null)) { SpawnerName = name; GameObject val = Object.Instantiate<GameObject>(nameplatePrefab, ((Component)sosig.Links[0]).transform, false); val.transform.localPosition = new Vector3(0f, 0.3f, 0f); val.transform.localRotation = Quaternion.identity; Text[] componentsInChildren = val.GetComponentsInChildren<Text>(); Text[] array = componentsInChildren; foreach (Text val2 in array) { val2.text = name; } } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Nameplate attach failed: " + ex.Message)); } } } private Vector3 CalculateAllySpawnPoint() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) FVRPlayerBody currentPlayerBody = GM.CurrentPlayerBody; object obj; if (currentPlayerBody == null) { obj = null; } else { Transform head = currentPlayerBody.Head; obj = ((head != null) ? ((Component)head).transform : null); } if ((Object)obj == (Object)null) { return Vector3.zero; } Vector3 position = ((Component)GM.CurrentPlayerBody.Head).transform.position; float num = Random.Range(0f, 360f) * ((float)Math.PI / 180f); float num2 = Random.Range(2f, 4f); return new Vector3(position.x + Mathf.Cos(num) * num2, position.y, position.z + Mathf.Sin(num) * num2); } private Vector3 CalculateEnemySpawnPoint() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) FVRPlayerBody currentPlayerBody = GM.CurrentPlayerBody; object obj; if (currentPlayerBody == null) { obj = null; } else { Transform head = currentPlayerBody.Head; obj = ((head != null) ? ((Component)head).transform : null); } if ((Object)obj == (Object)null) { return Vector3.zero; } Vector3 position = ((Component)GM.CurrentPlayerBody.Head).transform.position; float num = Random.Range(0f, 360f) * ((float)Math.PI / 180f); float num2 = Random.Range(8f, 15f); return new Vector3(position.x + Mathf.Cos(num) * num2, position.y, position.z + Mathf.Sin(num) * num2); } private IEnumerator UpdateSosigsCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <UpdateSosigsCoroutine>d__70(0) { <>4__this = this }; } private void UpdateAllySosigs() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Invalid comparison between Unknown and I4 //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GM.CurrentPlayerBody?.Head == (Object)null) { return; } Vector3 val2 = default(Vector3); for (int num = spawnedChatters.Count - 1; num >= 0; num--) { if ((Object)(object)spawnedChatters[num] == (Object)null || (int)spawnedChatters[num].BodyState == 3) { if (enableAutoCleanup.Value && (Object)(object)spawnedChatters[num] != (Object)null) { spawnedChatters[num].TickDownToClear(3f); } spawnedChatters.RemoveAt(num); } else { Sosig val = spawnedChatters[num]; if (!val.m_isStunned) { Vector3 position = GM.CurrentPlayerBody.Head.position; float num2 = Vector3.Distance(position, val.m_assaultPoint); if (num2 > followDistance.Value) { float num3 = (float)(Random.Range(0, 2) * 2 - 1) * Random.Range(0.75f, 2.5f); float num4 = (float)(Random.Range(0, 2) * 2 - 1) * Random.Range(0.75f, 2.5f); ((Vector3)(ref val2))..ctor(position.x + num3, position.y, position.z + num4); if (!Physics.Linecast(position, val2, LayerMask.op_Implicit(EnvironmentMask))) { val.CommandAssaultPoint(val2); } } } if (val.Priority.HasFreshTarget() && (int)val.CurrentOrder == 3 && val.m_entityRecognition >= 0.65f) { val.SetCurrentOrder((SosigOrder)2); } } } } private void UpdateEnemySosigs() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Invalid comparison between Unknown and I4 //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Invalid comparison between Unknown and I4 //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Invalid comparison between Unknown and I4 //IL_0195: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GM.CurrentPlayerBody?.Head == (Object)null) { return; } for (int i = spawnedEnemyChatters.Count - 1; i >= 0; i++) { if ((Object)(object)spawnedEnemyChatters[i] == (Object)null || (int)spawnedEnemyChatters[i].BodyState == 3) { if (enableAutoCleanup.Value && (Object)(object)spawnedEnemyChatters[i] != (Object)null) { spawnedEnemyChatters[i].TickDownToClear(3f); } spawnedEnemyChatters.RemoveAt(i); continue; } Sosig val = spawnedEnemyChatters[i]; if (!val.m_isStunned) { Vector3 position = GM.CurrentPlayerBody.Head.position; float num = Vector3.Distance(position, ((Component)val.Links[1]).transform.position); if (num > enemyAggressionDistance.Value) { val.CommandAssaultPoint(((Component)GM.CurrentPlayerBody).transform.position); } } if (val.Priority.HasFreshTarget() && (int)val.CurrentOrder == 3 && val.m_entityRecognition >= 0.55f) { val.SetCurrentOrder((SosigOrder)2); } if ((int)val.CurrentOrder == 0 || (int)val.CurrentOrder == 9 || (int)val.CurrentOrder == 1) { val.CommandAssaultPoint(((Component)GM.CurrentPlayerBody).transform.position); } } } private IEnumerator CleanupCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CleanupCoroutine>d__73(0) { <>4__this = this }; } private void CleanupDeadSosigs() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 if (!enableAutoCleanup.Value) { return; } foreach (Sosig item in spawnedChatters.Concat(spawnedEnemyChatters)) { if ((Object)(object)item != (Object)null && (int)item.BodyState == 3) { item.TickDownToClear(3f); } } } public void ClearSosigs(bool clearAllies = true, bool clearEnemies = true) { try { int num = 0; if (clearAllies) { for (int num2 = spawnedChatters.Count - 1; num2 >= 0; num2--) { if ((Object)(object)spawnedChatters[num2] != (Object)null) { Object.Destroy((Object)(object)((Component)spawnedChatters[num2]).gameObject); num++; } } spawnedChatters.Clear(); } if (clearEnemies) { for (int num3 = spawnedEnemyChatters.Count - 1; num3 >= 0; num3--) { if ((Object)(object)spawnedEnemyChatters[num3] != (Object)null) { Object.Destroy((Object)(object)((Component)spawnedEnemyChatters[num3]).gameObject); num++; } } spawnedEnemyChatters.Clear(); } userSosigCounts.Clear(); userLastSpawnTime.Clear(); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)$"Cleared {num} sosigs (ChatWatcher compatible)"); } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("Clear sosigs failed: " + ex.Message)); } } } public void ClearAllSosigs() { ClearSosigs(); BossSosigSystem.ClearAllBosses(); if (!chatWatcherEnabled || !((Object)(object)chatWatcher != (Object)null)) { return; } try { chatWatcher.ClearCache(); } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)("Failed to clear ChatWatcher cache: " + ex.Message)); } } } public ChatWatcher GetChatWatcher() { return chatWatcher; } public bool IsChatWatcherEnabled() { return chatWatcherEnabled && (Object)(object)chatWatcher != (Object)null; } public Sosig SpawningSequenceBoss(BossSosigSystem.BossType bossType, string username = null) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) try { if (spawnedEnemyChatters.Count >= maxEnemySosigs.Value) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)"Max enemy sosigs reached - cannot spawn boss"); } return null; } if (Time.time - lastSpawnTime < spawnCooldown.Value) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)"Spawn cooldown active"); } return null; } Vector3 pos = CalculateBossSpawnPoint(); Quaternion identity = Quaternion.identity; int num = Mathf.Max(1, (int)enemyIFF.Value); Sosig val = null; if (useModernSpawnSystem.Value) { SosigEnemyID bossTemplate = GetBossTemplate(bossType); val = SpawnSosigModern(bossTemplate, pos, identity, num); } if ((Object)(object)val == (Object)null) { SosigEnemyTemplate randomTemplate = GetRandomTemplate(isAlly: false); if ((Object)(object)randomTemplate != (Object)null) { val = SpawnSosigLegacy(randomTemplate, pos, identity, num); } } if ((Object)(object)val != (Object)null) { SetupEnemyBehavior(val); BossSosig bossSosig = ((Component)val).gameObject.AddComponent<BossSosig>(); bossSosig.Initialize(bossType, logger); string text = username ?? $"BOSS_{bossType}"; if (enableNameplates.Value && (Object)(object)nameplateEnemy != (Object)null) { AttachNameplate(val, "★ " + text + " ★", nameplateEnemy, isEnemy: true); } spawnedEnemyChatters.Add(val); lastSpawnTime = Time.time; ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)$"Spawned {bossType} BOSS '{text}' (IFF: {num})"); } return val; } ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogError((object)"Failed to spawn boss sosig"); } return null; } catch (Exception ex) { ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogError((object)("Boss spawn failed: " + ex.Message)); } return null; } } private Vector3 CalculateBossSpawnPoint() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) FVRPlayerBody currentPlayerBody = GM.CurrentPlayerBody; object obj; if (currentPlayerBody == null) { obj = null; } else { Transform head = currentPlayerBody.Head; obj = ((head != null) ? ((Component)head).transform : null); } if ((Object)obj == (Object)null) { return Vector3.zero; } Vector3 position = ((Component)GM.CurrentPlayerBody.Head).transform.position; float num = Random.Range(0f, 360f) * ((float)Math.PI / 180f); float num2 = Random.Range(20f, 30f); return new Vector3(position.x + Mathf.Cos(num) * num2, position.y, position.z + Mathf.Sin(num) * num2); } private SosigEnemyID GetBossTemplate(BossSosigSystem.BossType bossType) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) switch (bossType) { case BossSosigSystem.BossType.Tank: case BossSosigSystem.BossType.Juggernaut: return (SosigEnemyID)108; case BossSosigSystem.BossType.Sniper: return (SosigEnemyID)102; case BossSosigSystem.BossType.Berserker: case BossSosigSystem.BossType.Assassin: return (SosigEnemyID)109; default: return GetRandomEnemyID(); } } public void QueueSpawn(string username, string displayName, bool isFriendly, string armorPreset = null, SpawnPriority priority = SpawnPriority.Normal, string behavior = null) { try { if (isFriendly) { SpawningSequence(displayName ?? username); } else { SpawningSequenceEnemy((int)enemyIFF.Value, displayName ?? username); } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("QueueSpawn failed for " + username + ": " + ex.Message)); } } } public SosigStats GetStats() { SosigStats result = default(SosigStats); result.Allies = spawnedChatters.Count; result.Enemies = spawnedEnemyChatters.Count; result.Queued = 0; result.TotalActive = spawnedChatters.Count + spawnedEnemyChatters.Count; result.ChatWatcherActive = chatWatcherEnabled && (Object)(object)chatWatcher != (Object)null; return result; } public bool QueueTwitchSpawnRequest(string username, string displayName, bool isFriendly, string armorPreset = null, SpawnPriority priority = SpawnPriority.Normal, string requestedBehavior = null) { try { string arg = (chatWatcherEnabled ? "ChatWatcher" : "Direct"); ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)$"Twitch spawn request from {arg}: {username} (friendly: {isFriendly})"); } if (isFriendly) { SpawningSequence(displayName ?? username); } else { SpawningSequenceEnemy((int)enemyIFF.Value, displayName ?? username); } return true; } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("Twitch spawn request failed for " + username + ": " + ex.Message)); } return false; } } private void ApplyOutfitModern(Sosig sosig, SosigOutfitConfig outfit) { try { if (!((Object)(object)outfit == (Object)null) && sosig.Links.Count >= 4) { ApplyOutfit(sosig, outfit); } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Modern outfit apply failed: " + ex.Message)); } ApplyOutfit(sosig, outfit); } } private string GetRandomName(bool isAlly) { if ((Object)(object)steamFriends != (Object)null && steamFriends.IsAvailable() && plugin.UseSteamFriendsRandomNames()) { try { string randomFriendName = steamFriends.GetRandomFriendName(); if (!string.IsNullOrEmpty(randomFriendName) && randomFriendName != "Steam Friend") { ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)("Using Steam friend name: " + randomFriendName)); } return randomFriendName; } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("Failed to get Steam friend name: " + ex.Message)); } } } List<string> list = (isAlly ? allyNames : enemyNames); if (list.Count == 0) { LoadNameLists(); } if (list.Count == 0) { return isAlly ? "Ally" : "Enemy"; } return list[Random.Range(0, list.Count)]; } private SosigEnemyID GetRandomAllyID() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (allyPoolIDs.Count == 0) { return defaultAllyID; } return allyPoolIDs[Random.Range(0, allyPoolIDs.Count)]; } private SosigEnemyID GetRandomEnemyID() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (enemyPoolIDs.Count == 0) { return defaultEnemyID; } return enemyPoolIDs[Random.Range(0, enemyPoolIDs.Count)]; } private SosigEnemyTemplate GetRandomTemplate(bool isAlly) { List<SosigEnemyTemplate> list = (isAlly ? allyTemplates : enemyTemplates); if (list == null || list.Count == 0) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)("No " + (isAlly ? "ally" : "enemy") + " templates available")); } return null; } return list[Random.Range(0, list.Count)]; } private void BuildTemplateCache() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)ManagerSingleton<IM>.Instance == (Object)null) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)"Cannot build template cache - IM.Instance is null (H3VR not ready)"); } return; } if (ManagerSingleton<IM>.Instance.odicSosigObjsByID == null) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)"Cannot build template cache - odicSosigObjsByID is null (H3VR not ready)"); } return; } int num = 0; ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)"Building template cache from IM.Instance..."); } foreach (SosigEnemyID item in allyPoolIDs.Concat(enemyPoolIDs).Distinct()) { if (ManagerSingleton<IM>.Instance.odicSosigObjsByID.ContainsKey(item)) { SosigEnemyTemplate val = ManagerSingleton<IM>.Instance.odicSosigObjsByID[item]; if ((Object)(object)val != (Object)null) { templateCache[item] = val; num++; ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogDebug((object)$" Cached: {item}"); } } else { ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogWarning((object)$" Template null for {item}"); } } } else { ManualLogSource obj6 = logger; if (obj6 != null) { obj6.LogWarning((object)$" ID not found in IM: {item}"); } } } ManualLogSource obj7 = logger; if (obj7 != null) { obj7.LogInfo((object)$"Template cache built: {num}/{allyPoolIDs.Count + enemyPoolIDs.Count} templates loaded"); } ManualLogSource obj8 = logger; if (obj8 != null) { obj8.LogInfo((object)$"Template cache status: {templateCache.Count} total templates"); } ManualLogSource obj9 = logger; if (obj9 != null) { obj9.LogInfo((object)$" Ally pool: {allyPoolIDs.Count} IDs configured"); } ManualLogSource obj10 = logger; if (obj10 != null) { obj10.LogInfo((object)$" Enemy pool: {enemyPoolIDs.Count} IDs configured"); } } catch (Exception ex) { ManualLogSource obj11 = logger; if (obj11 != null) { obj11.LogWarning((object)("Failed to build template cache: " + ex.Message)); } ManualLogSource obj12 = logger; if (obj12 != null) { obj12.LogDebug((object)("Stack trace: " + ex.StackTrace)); } } } public void OnReceiveNameLists(List<string> allyList, List<string> enemyList) { try { allyNames = allyList; enemyNames = enemyList; ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)$"Received {allyNames.Count} ally names and {enemyNames.Count} enemy names from ChatWatcher"); } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("Failed to process received name lists: " + ex.Message)); } } } public string GetSystemStatus() { try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("=== Advanced Chat Sosig Spawner Status ==="); stringBuilder.AppendLine($"Active Allies: {spawnedChatters.Count}/{maxAllySosigs.Value}"); stringBuilder.AppendLine($"Active Enemies: {spawnedEnemyChatters.Count}/{maxEnemySosigs.Value}"); stringBuilder.AppendLine("ChatWatcher: " + (chatWatcherEnabled ? "ACTIVE" : "INACTIVE")); stringBuilder.AppendLine("Steam Friends: " + (((Object)(object)steamFriends != (Object)null && steamFriends.IsAvailable()) ? "AVAILABLE" : "N/A")); stringBuilder.AppendLine($"Template Cache: {templateCache.Count} templates"); stringBuilder.AppendLine($"Ally Pool: {allyPoolIDs.Count} types"); stringBuilder.AppendLine($"Enemy Pool: {enemyPoolIDs.Count} types"); stringBuilder.AppendLine($"Ally Names: {allyNames.Count} loaded"); stringBuilder.AppendLine($"Enemy Names: {enemyNames.Count} loaded"); stringBuilder.AppendLine("Modern Spawn System: " + (useModernSpawnSystem.Value ? "ENABLED" : "DISABLED")); stringBuilder.AppendLine("Nameplates: " + (enableNameplates.Value ? "ENABLED" : "DISABLED")); stringBuilder.AppendLine($"User Tracking: {userSosigCounts.Count} users"); stringBuilder.AppendLine("=========================================="); return stringBuilder.ToString(); } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogError((object)("Failed to get system status: " + ex.Message)); } return "ERROR: Could not get status"; } } public void ReloadNameLists() { try { allyNames.Clear(); enemyNames.Clear(); LoadNameLists(); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)$"Reloaded name lists: {allyNames.Count} allies, {enemyNames.Count} enemies"); } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("Failed to reload name lists: " + ex.Message)); } } } public void RebuildTemplateCache() { try { templateCache.Clear(); BuildTemplateCache(); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)$"Rebuilt template cache: {templateCache.Count} templates"); } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("Failed to rebuild template cache: " + ex.Message)); } } } } public class AdvancedSosigAI : MonoBehaviour { public enum AIState { Following, Assault, TakingCover, Suppressing, Flanking, Retreating, HoldingPosition } [CompilerGenerated] private sealed class <AIUpdateLoop>d__41 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AdvancedSosigAI <>4__this; private WaitForSeconds <wait>5__1; private Exception <ex>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AIUpdateLoop>d__41(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <wait>5__1 = null; <ex>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Invalid comparison between Unknown and I4 switch (<>1__state) { default: return false; case 0: <>1__state = -1; <wait>5__1 = new WaitForSeconds(2f); break; case 1: <>1__state = -1; try { if (EnableAdvancedAI) { if (<>4__this.isAlly && PreventFriendlyFire) { <>4__this.EnforceFriendlyFirePrevention(); } <>4__this.UpdateAIBehavior(); } } catch (Exception ex) { <ex>5__2 = ex; ManualLogSource logger = <>4__this.logger; if (logger != null) { logger.LogError((object)("Advanced AI update error: " + <ex>5__2.Message)); } } break; } if (<>4__this.isInitialized && (Object)(object)<>4__this.sosig != (Object)null && (int)<>4__this.sosig.BodyState != 3) { <>2__current = <wait>5__1; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private AIState currentState = AIState.Following; private Transform coverPoint; private float lastStateChangeTime; private Vector3 lastKnownEnemyPosition; private bool hasLineOfSight; private int sosigIFF = -1; private bool isAlly = false; private Sosig sosig; private ManualLogSource logger; private bool isInitialized; public static bool EnableAdvancedAI { get; set; } = true; public static bool EnableCoverSystem { get; set; } = true; public static bool EnableSquadCoordination { get; set; } = false; public static bool EnableTacticalMovement { get; set; } = true; public static float CoverSearchRadius { get; set; } = 15f; public static float SuppressionRadius { get; set; } = 10f; public static bool PreventFriendlyFire { get; set; } = true; public void Initialize(Sosig sosigInstance, ManualLogSource logSource) { sosig = sosigInstance; logger = logSource; isInitialized = true; if ((Object)(object)sosig != (Object)null) { sosigIFF = sosig.E.IFFCode; isAlly = sosigIFF == 0; ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)$"[AdvancedAI] Initialized for sosig with IFF {sosigIFF} (Ally: {isAlly})"); } if (isAlly && PreventFriendlyFire) { ConfigureFriendlyFirePrevention(); } } if (EnableAdvancedAI) { ((MonoBehaviour)this).StartCoroutine(AIUpdateLoop()); } } private void ConfigureFriendlyFirePrevention() { try { if (!((Object)(object)sosig == (Object)null) && isAlly) { sosig.E.IFFCode = 0; sosig.SetIFF(0); ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)"[AdvancedAI] Friendly fire prevention configured for ally sosig"); } } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogError((object)("[AdvancedAI] Error configuring friendly fire prevention: " + ex.Message)); } } } private IEnumerator AIUpdateLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AIUpdateLoop>d__41(0) { <>4__this = this }; } private void EnforceFriendlyFirePrevention() { try { if (sosig.E.IFFCode != 0) { sosig.E.IFFCode = 0; sosig.SetIFF(0); ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)"[AdvancedAI] Reset ally IFF to 0"); } } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogDebug((object)("[AdvancedAI] Error enforcing friendly fire prevention: " + ex.Message)); } } } private void UpdateAIBehavior() { if (!((Object)(object)sosig == (Object)null) && !sosig.m_isStunned) { UpdateTargetTracking(); EvaluateState(); ExecuteCurrentState(); } } private void UpdateTargetTracking() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (sosig.Priority.HasFreshTarget()) { Vector3 assaultPoint = sosig.m_assaultPoint; if (!IsTargetingPlayer()) { lastKnownEnemyPosition = assaultPoint; hasLineOfSight = HasLineOfSight(assaultPoint); return; } hasLineOfSight = false; ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)"[AdvancedAI] Prevented ally from targeting player"); } } else { hasLineOfSight = false; } } private bool IsTargetingPlayer() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!isAlly || (Object)(object)GM.CurrentPlayerBody == (Object)null) { return false; } float num = Vector3.Distance(sosig.m_assaultPoint, ((Component)GM.CurrentPlayerBody).transform.position); return num < 2f; } private void EvaluateState() { if (!(Time.time - lastStateChangeTime < 3f)) { if (isAlly) { EvaluateAllyState(); } else { EvaluateEnemyState(); } } } private void EvaluateAllyState() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!sosig.Priority.HasFreshTarget() || IsTargetingPlayer()) { SetState(AIState.Following); return; } float num = Vector3.Distance(((Component)sosig).transform.position, lastKnownEnemyPosition); float healthPercent = GetHealthPercent(); if (healthPercent < 0.3f && EnableCoverSystem) { if (FindNearestCover()) { SetState(AIState.TakingCover); } else { SetState(AIState.Retreating); } } else if (EnableCoverSystem && num > 8f && healthPercent < 0.6f && FindNearestCover()) { SetState(AIState.TakingCover); } else { SetState(AIState.Assault); } } private void EvaluateEnemyState() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!sosig.Priority.HasFreshTarget()) { SetState(AIState.Assault); return; } float num = Vector3.Distance(((Component)sosig).transform.position, lastKnownEnemyPosition); float healthPercent = GetHealthPercent(); if (healthPercent < 0.3f && EnableCoverSystem) { if (FindNearestCover()) { SetState(AIState.TakingCover); } else { SetState(AIState.Retreating); } } else if (num < 8f && healthPercent > 0.5f) { SetState(AIState.Assault); } else if (EnableCoverSystem && num > 8f && num < 25f && (!hasLineOfSight || healthPercent < 0.6f) && FindNearestCover()) { SetState(AIState.TakingCover); } else { SetState(AIState.Assault); } } private void SetState(AIState newState) { if (currentState != newState) { currentState = newState; lastStateChangeTime = Time.time; ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)$"Sosig AI state changed to: {newState}"); } } } private void ExecuteCurrentState() { if (isAlly && currentState == AIState.Assault && IsTargetingPlayer()) { SetState(AIState.Following); return; } switch (currentState) { case AIState.Following: break; case AIState.Assault: ExecuteAssault(); break; case AIState.TakingCover: ExecuteTakeCover(); break; case AIState.Suppressing: ExecuteSuppression(); break; case AIState.Flanking: ExecuteFlank(); break; case AIState.Retreating: ExecuteRetreat(); break; case AIState.HoldingPosition: ExecuteHold(); break; } } private void ExecuteAssault() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (isAlly && IsTargetingPlayer()) { SetState(AIState.Following); } else if (!hasLineOfSight && EnableTacticalMovement) { sosig.CommandAssaultPoint(lastKnownEnemyPosition); } else { sosig.SetCurrentOrder((SosigOrder)7); } } private void ExecuteTakeCover() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)coverPoint != (Object)null) { float num = Vector3.Distance(((Component)sosig).transform.position, coverPoint.position); if (num > 1.5f) { sosig.CommandAssaultPoint(coverPoint.position); } else if (hasLineOfSight && (!isAlly || !IsTargetingPlayer())) { sosig.SetCurrentOrder((SosigOrder)2); } else { sosig.SetCurrentOrder((SosigOrder)1); } } else { SetState(AIState.Assault); } } private void ExecuteSuppression() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (isAlly && IsTargetingPlayer()) { SetState(AIState.Following); } else if (hasLineOfSight) { sosig.SetCurrentOrder((SosigOrder)2); } else { sosig.CommandAssaultPoint(lastKnownEnemyPosition); } } private void ExecuteFlank() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = CalculateFlankPosition(); if (val != Vector3.zero) { sosig.CommandAssaultPoint(val); } else { SetState(AIState.Assault); } } private void ExecuteRetreat() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = CalculateRetreatPosition(); if (val != Vector3.zero) { sosig.CommandAssaultPoint(val); } if (GetHealthPercent() > 0.5f) { SetState(AIState.Assault); } } private void ExecuteHold() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) sosig.SetCurrentOrder((SosigOrder)1); if ((!isAlly || !IsTargetingPlayer()) && Vector3.Distance(((Component)sosig).transform.position, lastKnownEnemyPosition) < 10f) { SetState(AIState.Assault); } } private bool HasLineOfSight(Vector3 targetPosition) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)sosig == (Object)null || sosig.Links.Count == 0) { return false; } Vector3 position = ((Component)sosig.Links[0]).transform.position; Vector3 val = targetPosition - position; return !Physics.Raycast(position, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, LayerMask.GetMask(new string[1] { "Environment" })); } private bool FindNearestCover() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (!EnableCoverSystem) { return false; } Collider[] array = Physics.OverlapSphere(((Component)sosig).transform.position, CoverSearchRadius); float num = float.MaxValue; Transform val = null; Collider[] array2 = array; foreach (Collider val2 in array2) { if (((Component)val2).gameObject.layer == LayerMask.NameToLayer("Environment")) { float num2 = Vector3.Distance(((Component)sosig).transform.position, ((Component)val2).transform.position); if (IsCoverEffective(((Component)val2).transform.position) && num2 < num) { num = num2; val = ((Component)val2).transform; } } } if ((Object)(object)val != (Object)null) { coverPoint = val; return true; } return false; } private bool IsCoverEffective(Vector3 coverPosition) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = lastKnownEnemyPosition - ((Component)sosig).transform.position; Vector3 val2 = coverPosition - ((Component)sosig).transform.position; float num = Vector3.Dot(((Vector3)(ref val)).normalized, ((Vector3)(ref val2)).normalized); return num > 0.5f; } private Vector3 CalculateFlankPosition() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (lastKnownEnemyPosition == Vector3.zero) { return Vector3.zero; } Vector3 val = lastKnownEnemyPosition - ((Component)sosig).transform.position; Vector3 val2 = Vector3.Cross(val, Vector3.up); Vector3 normalized = ((Vector3)(ref val2)).normalized; Vector3 val3 = ((Component)sosig).transform.position + normalized * 10f; Vector3 val4 = ((Component)sosig).transform.position - normalized * 10f; if (!Physics.Linecast(((Component)sosig).transform.position, val3, LayerMask.GetMask(new string[1] { "Environment" }))) { return val3; } if (!Physics.Linecast(((Component)sosig).transform.position, val4, LayerMask.GetMask(new string[1] { "Environment" }))) { return val4; } return Vector3.zero; } private Vector3 CalculateRetreatPosition() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown resul