using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using EyeMonster.AI; using EyeMonster.NetcodePatcher; using EyeMonster.Utils; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using Y4NGZMonsters.Shared; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EyeMonster")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+25ca94fed298fe073d4c739917e3b7f046e875bf")] [assembly: AssemblyProduct("EyeMonster")] [assembly: AssemblyTitle("EyeMonster")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EyeMonster { public sealed class EyeMonsterConfig { public ConfigEntry Enabled { get; } public ConfigEntry SpawnWeightMultiplier { get; } public ConfigEntry MaxCount { get; } public ConfigEntry PowerLevel { get; } public ConfigEntry Health { get; } public ConfigEntry NoticeRange { get; } public ConfigEntry GazeAngle { get; } public ConfigEntry FlashlightRange { get; } public ConfigEntry RoamSpeed { get; } public ConfigEntry ChaseSpeed { get; } public ConfigEntry FleeSpeed { get; } public ConfigEntry AttackDamage { get; } public ConfigEntry AttackCooldown { get; } public ConfigEntry FleeDuration { get; } public ConfigEntry DebugLogs { get; } public EyeMonsterConfig(ConfigFile config) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Expected O, but got Unknown //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Expected O, but got Unknown //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Expected O, but got Unknown //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Expected O, but got Unknown bool saveOnConfigSet = config.SaveOnConfigSet; config.SaveOnConfigSet = false; try { EyeMonsterConfigMigration.TryMigrate(config, Plugin.Log); ConfigSectionNameMigration.TryMigrate(config, Plugin.Log, "Eye Monster"); Enabled = config.Bind("General", "Enabled", true, "Enable the Eye Monster encounter."); SpawnWeightMultiplier = config.Bind("Spawning", "SpawnWeightMultiplier", 1f, new ConfigDescription("Multiplier applied to Eye Monster's contextual moon/interior spawn policy. 0 disables natural spawns.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); MaxCount = config.Bind("Spawning", "MaxCount", 2, new ConfigDescription("Maximum number of living Eye Monsters at once.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 4), Array.Empty())); PowerLevel = config.Bind("Spawning", "PowerLevel", 2f, new ConfigDescription("Indoor enemy power budget cost for each Eye Monster.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 20f), Array.Empty())); Health = config.Bind("Core Stats", "Health", 5, new ConfigDescription("Hits the Eye Monster can take before dying.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100), Array.Empty())); NoticeRange = config.Bind("Detection", "NoticeRange", 12f, new ConfigDescription("Maximum range at which an Eye Monster facing a player can begin investigating.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 80f), Array.Empty())); GazeAngle = config.Bind("Detection", "GazeAngle", 28f, new ConfigDescription("Half-angle within which looking at its eye confirms aggression.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 90f), Array.Empty())); FlashlightRange = config.Bind("Detection", "FlashlightRange", 15f, new ConfigDescription("Maximum range at which a direct flashlight beam makes the Eye Monster flee.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 80f), Array.Empty())); RoamSpeed = config.Bind("Movement", "RoamSpeed", 2f, new ConfigDescription("Movement speed while roaming.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 10f), Array.Empty())); ChaseSpeed = config.Bind("Movement", "ChaseSpeed", 5f, new ConfigDescription("Movement speed after a player confirms aggression through eye contact.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 15f), Array.Empty())); FleeSpeed = config.Bind("Movement", "FleeSpeed", 7f, new ConfigDescription("Movement speed while fleeing a direct flashlight beam.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 20f), Array.Empty())); AttackDamage = config.Bind("Combat", "AttackDamage", 35, new ConfigDescription("Damage dealt by a successful attack.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 200), Array.Empty())); AttackCooldown = config.Bind("Combat", "AttackCooldown", 1.5f, new ConfigDescription("Seconds between attack attempts.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 30f), Array.Empty())); FleeDuration = config.Bind("Abilities", "FleeDuration", 6f, new ConfigDescription("Seconds the Eye Monster flees after being directly lit.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 30f), Array.Empty())); DebugLogs = config.Bind("Diagnostics", "DebugLogs", false, "Log detailed Eye Monster targeting and setup diagnostics."); } finally { config.SaveOnConfigSet = saveOnConfigSet; if (saveOnConfigSet) { config.Save(); } } } } internal static class EyeMonsterConfigMigration { private static readonly ConfigDefinition LegacySpawnWeight = new ConfigDefinition("Spawning", "SpawnWeight"); private static readonly ConfigDefinition[] RetainedLegacyDefinitions = (ConfigDefinition[])(object)new ConfigDefinition[10] { new ConfigDefinition("Combat", "EnemyHP"), new ConfigDefinition("Movement", "RoamSpeed"), new ConfigDefinition("Movement", "ChaseSpeed"), new ConfigDefinition("Movement", "FleeSpeed"), new ConfigDefinition("Combat", "AttackDamage"), new ConfigDefinition("Combat", "AttackCooldown"), new ConfigDefinition("Detection", "AggroRange"), new ConfigDefinition("Detection", "PlayerGazeAngle"), new ConfigDefinition("Detection", "FlashlightDetectionRange"), new ConfigDefinition("Behavior", "FleeDuration") }; private static readonly Dictionary RemovedDefaults = new Dictionary { { new ConfigDefinition("Movement", "InvestigateSpeed"), "2.6" }, { new ConfigDefinition("Combat", "AttackRange"), "2.5" }, { new ConfigDefinition("Detection", "NoticeViewAngle"), "52" }, { new ConfigDefinition("Behavior", "InvestigationStopDistance"), "4.5" }, { new ConfigDefinition("Behavior", "InvestigationDecisionDelay"), "0.8" }, { new ConfigDefinition("Detection", "FlashlightDetectionAngle"), "25" }, { new ConfigDefinition("Behavior", "LoseTargetSeconds"), "3.5" }, { new ConfigDefinition("Behavior", "FailedNoticeCooldown"), "4" } }; internal static bool TryMigrate(ConfigFile config, ManualLogSource log) { string configFilePath = config.ConfigFilePath; if (!File.Exists(configFilePath)) { return false; } Dictionary dictionary = null; string text = null; try { dictionary = ReadValues(configFilePath); if (!ContainsLegacyConfig(dictionary)) { return false; } text = GetBackupPath(configFilePath); File.Copy(configFilePath, text, overwrite: false); File.WriteAllText(configFilePath, BuildMigratedConfig(dictionary), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); config.Reload(); } catch (Exception ex) { string text2 = "The original config was not modified."; if (!string.IsNullOrEmpty(text) && File.Exists(text)) { try { File.Copy(text, configFilePath, overwrite: true); config.Reload(); text2 = "The original config was restored from its backup."; } catch (Exception ex2) { text2 = "Automatic restore also failed: " + ex2.GetBaseException().Message + ". Recover manually from " + text + "."; } } if (log != null) { log.LogWarning((object)("[Eye Monster] Could not migrate legacy config: " + ex.GetBaseException().Message + " " + text2)); } return false; } List list = FindCustomizedDroppedKeys(dictionary); if (log != null) { log.LogInfo((object)("[Eye Monster] Migrated legacy config to the compact DawnLib layout. Backup: " + text)); } if (list.Count > 0 && log != null) { log.LogWarning((object)("[Eye Monster] These customized legacy settings are now authored source tuning and were not carried forward: " + string.Join(", ", list))); } return true; } private static bool ContainsLegacyConfig(Dictionary values) { if (values.ContainsKey(LegacySpawnWeight)) { return true; } for (int i = 0; i < RetainedLegacyDefinitions.Length; i++) { if (values.ContainsKey(RetainedLegacyDefinitions[i])) { return true; } } foreach (ConfigDefinition key in RemovedDefaults.Keys) { if (values.ContainsKey(key)) { return true; } } return false; } private static string BuildMigratedConfig(Dictionary values) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0174: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_01bf: Expected O, but got Unknown //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_01f9: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Expected O, but got Unknown //IL_0233: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_027e: Expected O, but got Unknown //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Expected O, but got Unknown //IL_02b8: Expected O, but got Unknown //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Expected O, but got Unknown //IL_02f2: Expected O, but got Unknown //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Expected O, but got Unknown //IL_033d: Expected O, but got Unknown //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Expected O, but got Unknown //IL_0377: Expected O, but got Unknown //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_03c2: Expected O, but got Unknown //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Expected O, but got Unknown string text = GetValue(values, new ConfigDefinition("10 - Spawning", "SpawnWeightMultiplier"), null, null); if (string.IsNullOrWhiteSpace(text)) { text = ((!float.TryParse(GetValue(values, LegacySpawnWeight, null, "40"), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) ? "1" : Math.Max(0f, Math.Min(5f, result / 40f)).ToString("0.###", CultureInfo.InvariantCulture)); } StringBuilder stringBuilder = new StringBuilder(); AppendSection(stringBuilder, "00 - General", ("Enabled", GetValue(values, new ConfigDefinition("00 - General", "Enabled"), null, "true"))); AppendSection(stringBuilder, "10 - Spawning", ("SpawnWeightMultiplier", text), ("MaxCount", GetValue(values, new ConfigDefinition("10 - Spawning", "MaxCount"), null, "2")), ("PowerLevel", GetValue(values, new ConfigDefinition("10 - Spawning", "PowerLevel"), null, "2"))); AppendSection(stringBuilder, "20 - Core Stats", ("Health", GetValue(values, new ConfigDefinition("20 - Core Stats", "Health"), new ConfigDefinition("Combat", "EnemyHP"), "5"))); AppendSection(stringBuilder, "30 - Detection", ("NoticeRange", GetValue(values, new ConfigDefinition("30 - Detection", "NoticeRange"), new ConfigDefinition("Detection", "AggroRange"), "12")), ("GazeAngle", GetValue(values, new ConfigDefinition("30 - Detection", "GazeAngle"), new ConfigDefinition("Detection", "PlayerGazeAngle"), "28")), ("FlashlightRange", GetValue(values, new ConfigDefinition("30 - Detection", "FlashlightRange"), new ConfigDefinition("Detection", "FlashlightDetectionRange"), "15"))); AppendSection(stringBuilder, "40 - Movement", ("RoamSpeed", GetValue(values, new ConfigDefinition("40 - Movement", "RoamSpeed"), new ConfigDefinition("Movement", "RoamSpeed"), "2")), ("ChaseSpeed", GetValue(values, new ConfigDefinition("40 - Movement", "ChaseSpeed"), new ConfigDefinition("Movement", "ChaseSpeed"), "5")), ("FleeSpeed", GetValue(values, new ConfigDefinition("40 - Movement", "FleeSpeed"), new ConfigDefinition("Movement", "FleeSpeed"), "7"))); AppendSection(stringBuilder, "50 - Combat", ("AttackDamage", GetValue(values, new ConfigDefinition("50 - Combat", "AttackDamage"), new ConfigDefinition("Combat", "AttackDamage"), "35")), ("AttackCooldown", GetValue(values, new ConfigDefinition("50 - Combat", "AttackCooldown"), new ConfigDefinition("Combat", "AttackCooldown"), "1.5"))); AppendSection(stringBuilder, "60 - Abilities", ("FleeDuration", GetValue(values, new ConfigDefinition("60 - Abilities", "FleeDuration"), new ConfigDefinition("Behavior", "FleeDuration"), "6"))); AppendSection(stringBuilder, "99 - Diagnostics", ("DebugLogs", GetValue(values, new ConfigDefinition("99 - Diagnostics", "DebugLogs"), null, "false"))); return stringBuilder.ToString(); } private static void AppendSection(StringBuilder output, string section, params (string Key, string Value)[] entries) { output.Append('[').Append(section).AppendLine("]"); for (int i = 0; i < entries.Length; i++) { output.Append(entries[i].Key).Append(" = ").AppendLine(entries[i].Value); } output.AppendLine(); } private static string GetValue(Dictionary values, ConfigDefinition preferred, ConfigDefinition legacy, string fallback) { if (preferred != (ConfigDefinition)null && values.TryGetValue(preferred, out var value)) { return value; } if (legacy != (ConfigDefinition)null && values.TryGetValue(legacy, out value)) { return value; } return fallback; } private static Dictionary ReadValues(string path) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown Dictionary dictionary = new Dictionary(); string text = string.Empty; string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0 || text2.StartsWith("#", StringComparison.Ordinal)) { continue; } if (text2.StartsWith("[", StringComparison.Ordinal) && text2.EndsWith("]", StringComparison.Ordinal)) { text = text2.Substring(1, text2.Length - 2); continue; } int num = text2.IndexOf('='); if (num > 0) { string text3 = text2.Substring(0, num).Trim(); string value = text2.Substring(num + 1).Trim(); dictionary[new ConfigDefinition(text, text3)] = value; } } return dictionary; } private static List FindCustomizedDroppedKeys(Dictionary values) { List list = new List(); foreach (KeyValuePair removedDefault in RemovedDefaults) { if (values.TryGetValue(removedDefault.Key, out var value) && !ValuesEquivalent(value, removedDefault.Value)) { list.Add(removedDefault.Key.Section + "." + removedDefault.Key.Key); } } list.Sort(StringComparer.OrdinalIgnoreCase); return list; } private static bool ValuesEquivalent(string left, string right) { if (string.Equals(left.Trim(), right.Trim(), StringComparison.OrdinalIgnoreCase)) { return true; } if (float.TryParse(left, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(right, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { return Math.Abs(result - result2) < 0.0001f; } return false; } private static string GetBackupPath(string configPath) { string text = configPath + ".pre-dawn.bak"; if (!File.Exists(text)) { return text; } for (int i = 2; i < 1000; i++) { string text2 = configPath + $".pre-dawn.{i}.bak"; if (!File.Exists(text2)) { return text2; } } throw new IOException("Could not allocate an Eye Monster config backup filename."); } } internal sealed class EyeMonsterSpawnWeights : IWeighted, IContextualWeighted { internal const int DefaultWeight = 5; internal const int MaximumWeight = 100; private readonly Func _multiplier; internal EyeMonsterSpawnWeights(Func multiplier) { _multiplier = multiplier ?? throw new ArgumentNullException("multiplier"); } public int GetWeight() { return Scale(5, 1f); } public int GetWeight(SpawnWeightContext context) { int moonWeight = GetMoonWeight(((SpawnWeightContext)(ref context)).Moon); if (moonWeight <= 0) { return 0; } return Scale(moonWeight, GetDungeonMultiplier(((SpawnWeightContext)(ref context)).Dungeon)); } internal static int GetMoonWeight(DawnMoonInfo moon) { if (moon == null) { return 5; } if (((DawnBaseInfo)(object)moon).HasTag(Tags.Company) || ((DawnBaseInfo)(object)moon).HasTag(Tags.Unimplemented) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Test)) { return 0; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Experimentation)) { return 3; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Assurance) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Vow)) { return 5; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Offense) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.March) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Embrion)) { return 7; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Adamance)) { return 9; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Rend) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Dine)) { return 11; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Titan) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Artifice) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Liquidation)) { return 13; } if (((DawnBaseInfo)(object)moon).HasTag(Tags.Paid)) { return 10; } ((DawnBaseInfo)(object)moon).HasTag(Tags.Free); return 5; } internal static float GetDungeonMultiplier(DawnDungeonInfo dungeon) { if (dungeon == null) { return 1f; } if (KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.FacilityFlow) || KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.FacilityFlowThreeExits) || KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.FacilityFlowExtraLarge) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Industrial) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Mechanical) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Factory) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Bunker)) { return 1f; } if (KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.MansionFlow) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Gothic) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Grand) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Ornate) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Lavish) || ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Eerie)) { return 0.75f; } if (!KeyEquals(((DawnBaseInfo)(object)dungeon).TypedKey, DungeonKeys.MineshaftFlow) && !((DawnBaseInfo)(object)dungeon).HasTag(Tags.Cavern) && !((DawnBaseInfo)(object)dungeon).HasTag(Tags.Quarry)) { ((DawnBaseInfo)(object)dungeon).HasTag(Tags.Flooded); } return 0.75f; } private int Scale(int moonWeight, float dungeonMultiplier) { float num = Mathf.Clamp(_multiplier(), 0f, 5f); return Mathf.Clamp(Mathf.RoundToInt((float)moonWeight * dungeonMultiplier * num), 0, 100); } private static bool KeyEquals(NamespacedKey left, NamespacedKey right) where T : INamespaced { if (left != null && right != null) { return ((object)left).Equals((object?)right); } return false; } } internal static class EyeMonsterTuning { internal const float InvestigateSpeed = 2.6f; internal const float AttackRange = 2.5f; internal const float NoticeViewAngle = 52f; internal const float InvestigationStopDistance = 4.5f; internal const float InvestigationDecisionDelay = 0.8f; internal const float FlashlightDetectionAngle = 25f; internal const float LoseTargetSeconds = 3.5f; internal const float FailedNoticeCooldown = 4f; internal const float AgentAngularSpeed = 180f; internal const float AgentAcceleration = 12f; internal const float AgentRadius = 0.42f; internal const float AgentHeight = 2.45f; } [BepInPlugin("y4ngz.lethalcompany.eyemonster", "Y4NGZ Eye Monster", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal const string DawnNamespace = "y4ngz_monsters"; internal const string DawnEnemyKey = "eye_monster"; internal const string ScanNodeSubtitle = "Avoid its gaze"; internal const string BestiaryText = "Eye Monster\n\nDanger level: high\n\nA roaming ocular predator that approaches cautiously until a worker meets its gaze. Avoid eye contact to make it lose interest, or drive it away with a direct flashlight beam.\n\n"; internal static ManualLogSource Log; internal static EyeMonsterConfig ModConfig; internal static AssetBundle ModAssets; internal static EnemyType EyeMonsterEnemy; private static bool _netcodeInitialized; private static bool _loggedScanNodeLayer; private Harmony _harmony; private void Awake() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; try { InitializeNetcodeRPCs(); ModConfig = new EyeMonsterConfig(((BaseUnityPlugin)this).Config); if (!ModConfig.Enabled.Value) { Log.LogInfo((object)"Y4NGZ Eye Monster is disabled by config."); return; } string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "eyemonster.bundle"); ModAssets = AssetBundle.LoadFromFile(text); if ((Object)(object)ModAssets == (Object)null) { Log.LogError((object)("Failed to load asset bundle at: " + text)); return; } GameObject val = ModAssets.LoadAsset("EyeMonster"); if ((Object)(object)val == (Object)null) { Log.LogError((object)"Failed to load EyeMonster prefab from bundle."); return; } SetupPrefabComponents(val); EyeMonsterEnemy = CreateEnemyType(val); EyeMonsterAI component = val.GetComponent(); if ((Object)(object)component == (Object)null) { Log.LogError((object)"EyeMonster prefab does not contain EyeMonsterAI."); return; } ((EnemyAI)component).enemyType = EyeMonsterEnemy; RegisterWithDawn(val); _harmony = new Harmony("y4ngz.lethalcompany.eyemonster"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"Y4NGZ Eye Monster v1.0.0 loaded."); } catch (Exception arg) { Log.LogError((object)string.Format("Failed to initialize {0}: {1}", "Y4NGZ Eye Monster", arg)); } } private static void RegisterWithDawn(GameObject prefab) { EyeMonsterSpawnWeights spawnWeights = new EyeMonsterSpawnWeights(() => ModConfig.SpawnWeightMultiplier.Value); DawnLib.RegisterNetworkPrefab(prefab); DawnLib.DefineEnemy(NamespacedKey.From("y4ngz_monsters", "eye_monster"), EyeMonsterEnemy, (Action)delegate(EnemyInfoBuilder builder) { ((BaseInfoBuilder)(object)builder.DefineInside((Action)delegate(EnemyLocationBuilder location) { location.SetWeights((Action>)delegate(WeightTableBuilder table) { table.SetGlobalWeight((IWeighted)(object)spawnWeights); }); }).CreateBestiaryNode("Eye Monster\n\nDanger level: high\n\nA roaming ocular predator that approaches cautiously until a worker meets its gaze. Avoid eye contact to make it lose interest, or drive it away with a direct flashlight beam.\n\n").CreateNameKeyword("eye monster")).AddTags((IEnumerable)(object)new NamespacedKey[4] { Tags.Hostile, Tags.Organic, Tags.Killable, Tags.Medium }); }); } private static void InitializeNetcodeRPCs() { if (_netcodeInitialized) { return; } _netcodeInitialized = true; Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { MethodInfo[] methods; try { methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } catch { continue; } foreach (MethodInfo methodInfo in methods) { if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length == 0) { continue; } try { methodInfo.Invoke(null, null); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[NetcodeInit] " + type.Name + "." + methodInfo.Name + " failed: " + ex.Message)); } } } } } private static void SetupPrefabComponents(GameObject prefab) { TrySetTag(prefab, "Enemy"); TrySetLayer(prefab, "Enemies"); EyeMonsterAI component = prefab.GetComponent(); if ((Object)(object)component == (Object)null) { Log.LogError((object)"[EyeMon] EyeMonsterAI is missing from the bundled prefab."); return; } NavMeshAgent val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent(); } ConfigureAgent(val); ((EnemyAI)component).agent = val; Animator animator = ResolveAnimator(prefab, component); EnsureAnimationRelay(prefab, component, animator); EnsureEyeAnchor(prefab, component); EnsureScanNode(prefab); EnsureMapDot(prefab); EnsureCollision(prefab, component); EnsureExclusiveAudio(prefab, component); EnsureSlimeTrail(prefab, component); EnsureBehaviourStates(component); WireAudioClips(component); } private static void ConfigureAgent(NavMeshAgent agent) { agent.speed = ModConfig.RoamSpeed.Value; agent.angularSpeed = 180f; agent.acceleration = 12f; agent.stoppingDistance = 0f; agent.radius = 0.42f; agent.height = 2.45f; agent.baseOffset = 0f; agent.autoRepath = true; agent.autoTraverseOffMeshLink = true; } private static Animator ResolveAnimator(GameObject prefab, EyeMonsterAI ai) { Transform val = prefab.transform.Find("VisualRoot"); Animator val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : prefab.GetComponent()); if ((Object)(object)val2 == (Object)null) { val2 = prefab.GetComponentInChildren(true); } ((EnemyAI)ai).creatureAnimator = val2; return val2; } private static void EnsureAnimationRelay(GameObject prefab, EyeMonsterAI ai, Animator animator) { if (!((Object)(object)animator == (Object)null) && !((Object)(object)((Component)animator).gameObject == (Object)(object)prefab)) { EyeMonsterAnimationRelay eyeMonsterAnimationRelay = ((Component)animator).GetComponent(); if ((Object)(object)eyeMonsterAnimationRelay == (Object)null) { eyeMonsterAnimationRelay = ((Component)animator).gameObject.AddComponent(); } eyeMonsterAnimationRelay.owner = ai; } } private static void EnsureEyeAnchor(GameObject prefab, EyeMonsterAI ai) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Transform val = FindOrCreateChild(prefab.transform, "Eye", new Vector3(0f, 1.45f, 0.45f)); TrySetLayer(((Component)val).gameObject, "Enemies"); ((EnemyAI)ai).eye = val; } internal static void EnsureScanNode(GameObject prefab) { //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) ScanNodeProperties val = null; ScanNodeProperties[] componentsInChildren = prefab.GetComponentsInChildren(true); foreach (ScanNodeProperties val2 in componentsInChildren) { bool flag = val2.creatureScanID >= 0; bool flag2 = (Object)(object)val != (Object)null && val.creatureScanID >= 0; bool flag3 = string.Equals(((Object)((Component)val2).gameObject).name, "ScanNode", StringComparison.Ordinal); bool flag4 = (Object)(object)val != (Object)null && string.Equals(((Object)((Component)val).gameObject).name, "ScanNode", StringComparison.Ordinal); if ((Object)(object)val == (Object)null || (flag && !flag2) || (flag == flag2 && flag3 && !flag4)) { val = val2; } } if (componentsInChildren.Length > 1) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[EyeMon] Found {componentsInChildren.Length} scan nodes; retiring every duplicate."); } } for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)(object)val) { RetireExtraScanNode(componentsInChildren[j], val, prefab); } } Transform val3 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : FindOrCreateChild(prefab.transform, "ScanNode", new Vector3(0f, 1.45f, 0f))); ((Object)((Component)val3).gameObject).name = "ScanNode"; TrySetTag(((Component)val3).gameObject, "DoNotSet"); TrySetLayer(((Component)val3).gameObject, "ScanNode"); EnsureHierarchyActive(val3, prefab.transform); ((Component)val3).gameObject.SetActive(true); if (!_loggedScanNodeLayer) { _loggedScanNodeLayer = true; Log.LogInfo((object)($"[EyeMon] Scan node layer resolved to {((Component)val3).gameObject.layer} " + string.Format("(NameToLayer(\"ScanNode\")={0}, fallback 22); ", LayerMask.NameToLayer("ScanNode")) + $"active={((Component)val3).gameObject.activeInHierarchy}.")); } BoxCollider val4 = ((Component)val3).GetComponent(); if ((Object)(object)val4 == (Object)null) { val4 = ((Component)val3).gameObject.AddComponent(); } ((Collider)val4).enabled = true; ((Collider)val4).isTrigger = true; val4.center = Vector3.zero; val4.size = new Vector3(1.8f, 2.2f, 1.8f); val = val ?? ((Component)val3).gameObject.AddComponent(); val.headerText = "Eye Monster"; val.subText = "Avoid its gaze"; val.maxRange = 25; val.minRange = 1; val.nodeType = 1; val.requiresLineOfSight = true; } private static void RetireExtraScanNode(ScanNodeProperties extra, ScanNodeProperties preferred, GameObject root) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) if ((Object)(object)extra == (Object)null) { return; } Scene scene; if ((Object)(object)((Component)extra).gameObject == (Object)(object)root || ((Object)(object)preferred != (Object)null && (Object)(object)((Component)extra).gameObject == (Object)(object)((Component)preferred).gameObject)) { scene = root.scene; if (((Scene)(ref scene)).IsValid()) { Object.Destroy((Object)(object)extra); } else { Object.DestroyImmediate((Object)(object)extra, true); } return; } GameObject gameObject = ((Component)extra).gameObject; gameObject.SetActive(false); Collider[] components = gameObject.GetComponents(); for (int i = 0; i < components.Length; i++) { components[i].enabled = false; } scene = root.scene; if (((Scene)(ref scene)).IsValid()) { Object.Destroy((Object)(object)gameObject); } else { Object.DestroyImmediate((Object)(object)gameObject, true); } } private static void EnsureMapDot(GameObject prefab) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Transform obj = FindOrCreateChild(prefab.transform, "MapDot", new Vector3(0f, 1.2f, 0f)); TrySetTag(((Component)obj).gameObject, "DoNotSet"); TrySetLayer(((Component)obj).gameObject, "MapRadar"); } private static void EnsureCollision(GameObject prefab, EyeMonsterAI ai) { //IL_0035: 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_0064: 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_00e3: Unknown result type (might be due to invalid IL or missing references) BoxCollider val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent(); } ((Collider)val).enabled = true; ((Collider)val).isTrigger = false; val.center = new Vector3(0f, 1.4f, 0f); val.size = new Vector3(2.05f, 2.8f, 2.05f); Transform val2 = FindOrCreateChild(prefab.transform, "Collision", Vector3.zero); TrySetTag(((Component)val2).gameObject, "Enemy"); TrySetLayer(((Component)val2).gameObject, "Enemies"); BoxCollider val3 = ((Component)val2).GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)val2).gameObject.AddComponent(); } ((Collider)val3).enabled = true; ((Collider)val3).isTrigger = true; val3.center = new Vector3(0f, 1.45f, 0f); val3.size = new Vector3(2.3f, 2.9f, 2.3f); Rigidbody val4 = ((Component)val2).GetComponent(); if ((Object)(object)val4 == (Object)null) { val4 = ((Component)val2).gameObject.AddComponent(); } val4.isKinematic = true; val4.useGravity = false; val4.detectCollisions = true; WireHitDetector(((Component)val2).gameObject, ai); } private static void WireHitDetector(GameObject host, EyeMonsterAI ai) { EnemyAICollisionDetect val = host.GetComponent(); if ((Object)(object)val == (Object)null) { val = host.AddComponent(); } val.mainScript = (EnemyAI)(object)ai; val.alwaysAllowHitting = true; val.canCollideWithEnemies = false; val.onlyCollideWhenGrounded = false; } private static void EnsureExclusiveAudio(GameObject prefab, EyeMonsterAI ai) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Transform val = FindOrCreateChild(prefab.transform, "CreatureAudio", new Vector3(0f, 1.35f, 0f)); TrySetLayer(((Component)val).gameObject, "Enemies"); AudioSource val2 = ((Component)val).GetComponent(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).gameObject.AddComponent(); } ConfigureSpatialAudio(val2); ai.exclusiveAudioSource = val2; ((EnemyAI)ai).creatureSFX = val2; ((EnemyAI)ai).creatureVoice = val2; DisableLegacyAudio(prefab.transform.Find("CreatureSFX"), val2); DisableLegacyAudio(prefab.transform.Find("CreatureVoice"), val2); DisableLegacyAudio(prefab.transform.Find("LoopSource"), val2); } private static void DisableLegacyAudio(Transform legacyTransform, AudioSource retainedSource) { if (!((Object)(object)legacyTransform == (Object)null)) { AudioSource component = ((Component)legacyTransform).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component == (Object)(object)retainedSource)) { component.Stop(); component.playOnAwake = false; component.loop = false; component.clip = null; ((Behaviour)component).enabled = false; } } } private static void ConfigureSpatialAudio(AudioSource source) { source.playOnAwake = false; source.loop = false; source.spatialBlend = 1f; source.rolloffMode = (AudioRolloffMode)1; source.minDistance = 1f; source.maxDistance = 25f; } private static void EnsureSlimeTrail(GameObject prefab, EyeMonsterAI ai) { EyeMonsterSlimeTrail eyeMonsterSlimeTrail = prefab.GetComponent(); if ((Object)(object)eyeMonsterSlimeTrail == (Object)null) { eyeMonsterSlimeTrail = prefab.AddComponent(); } eyeMonsterSlimeTrail.slimeMaterial = LoadMaterial("EyeMonsterSlime"); ai.slimeTrail = eyeMonsterSlimeTrail; if ((Object)(object)eyeMonsterSlimeTrail.slimeMaterial == (Object)null) { Log.LogWarning((object)"[EyeMon] EyeMonsterSlime material is missing from the bundle."); } } private static void EnsureBehaviourStates(EyeMonsterAI ai) { ((EnemyAI)ai).enemyBehaviourStates = (EnemyBehaviourState[])(object)new EnemyBehaviourState[5] { WalkingState("Roaming", walking: false), WalkingState("Investigating", walking: true), WalkingState("Chasing", walking: true), WalkingState("Attacking", walking: false), WalkingState("Fleeing", walking: true) }; ((EnemyAI)ai).currentBehaviourStateIndex = 0; ((EnemyAI)ai).previousBehaviourStateIndex = 0; ((EnemyAI)ai).currentBehaviourState = ((EnemyAI)ai).enemyBehaviourStates[0]; } private static EnemyBehaviourState WalkingState(string name, bool walking) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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) //IL_0026: Expected O, but got Unknown return new EnemyBehaviourState { name = name, IsAnimTrigger = false, parameterString = "isWalking", boolValue = walking }; } private static void WireAudioClips(EyeMonsterAI ai) { ai.idleClips = LoadAudioClips("eyemonster_idle_01", "eyemonster_idle_02"); ai.vocalClips = LoadAudioClips("eyemonster_vocal_01", "eyemonster_vocal_02"); ai.playerHitClips = LoadAudioClips("eyemonster_player_hit_01"); ai.runStepClips = LoadAudioClips("eyemonster_step_01", "eyemonster_step_02", "eyemonster_step_03"); } private static AudioClip[] LoadAudioClips(params string[] names) { AudioClip[] array = (AudioClip[])(object)new AudioClip[names.Length]; int num = 0; for (int i = 0; i < names.Length; i++) { AudioClip val = LoadAudioClip(names[i]); if ((Object)(object)val != (Object)null) { array[num++] = val; } } if (num == array.Length) { return array; } AudioClip[] array2 = (AudioClip[])(object)new AudioClip[num]; Array.Copy(array, array2, num); return array2; } private static AudioClip LoadAudioClip(string shortName) { AudioClip val = ModAssets.LoadAsset(shortName) ?? ModAssets.LoadAsset(shortName + ".wav"); if ((Object)(object)val != (Object)null) { return val; } string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { if (text.EndsWith("/" + shortName + ".wav", StringComparison.OrdinalIgnoreCase)) { return ModAssets.LoadAsset(text); } } Log.LogWarning((object)("[EyeMon] Audio clip missing from bundle: " + shortName)); return null; } private static Material LoadMaterial(string shortName) { Material val = ModAssets.LoadAsset(shortName) ?? ModAssets.LoadAsset(shortName + ".mat"); if ((Object)(object)val != (Object)null) { return val; } string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { if (text.EndsWith("/" + shortName + ".mat", StringComparison.OrdinalIgnoreCase)) { return ModAssets.LoadAsset(text); } } return null; } private static Transform FindOrCreateChild(Transform parent, string name, Vector3 localPosition) { //IL_0026: 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) Transform val = parent.Find(name); if ((Object)(object)val == (Object)null) { val = new GameObject(name).transform; val.SetParent(parent, false); } val.localPosition = localPosition; return val; } private static void TrySetTag(GameObject target, string tagName) { try { target.tag = tagName; } catch (UnityException) { Log.LogWarning((object)("[EyeMon] Tag '" + tagName + "' is unavailable for '" + ((Object)target).name + "'.")); } } internal static void TrySetLayer(GameObject target, string layerName) { if (!((Object)(object)target == (Object)null)) { int num = LayerMask.NameToLayer(layerName); if (num < 0) { num = ResolveLayerFallback(layerName); } if (num < 0 || num > 31) { Log.LogWarning((object)("[EyeMon] Layer '" + layerName + "' is unavailable for '" + ((Object)target).name + "'.")); } else { target.layer = num; } } } private static int ResolveLayerFallback(string layerName) { if (string.Equals(layerName, "ScanNode", StringComparison.OrdinalIgnoreCase)) { return 22; } if (string.Equals(layerName, "Enemies", StringComparison.OrdinalIgnoreCase)) { return 19; } return -1; } private static void EnsureHierarchyActive(Transform child, Transform stopAt) { Transform val = child; while ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(true); if (!((Object)(object)val == (Object)(object)stopAt)) { val = val.parent; continue; } break; } } private static EnemyType CreateEnemyType(GameObject prefab) { EnemyType obj = ScriptableObject.CreateInstance(); obj.enemyName = "Eye Monster"; obj.enemyPrefab = prefab; obj.PowerLevel = ModConfig.PowerLevel.Value; obj.DiversityPowerLevel = 1; obj.MaxCount = ModConfig.MaxCount.Value; obj.canDie = true; obj.canBeStunned = true; obj.stunTimeMultiplier = 1f; obj.doorSpeedMultiplier = 1f; obj.stunGameDifficultyMultiplier = 1f; obj.destroyOnDeath = false; obj.isOutsideEnemy = false; obj.isDaytimeEnemy = false; obj.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f); obj.numberSpawnedFalloff = AnimationCurve.Linear(0f, 1f, 1f, 0.65f); obj.useNumberSpawnedFalloff = true; return obj; } } public static class PluginInfo { public const string PLUGIN_GUID = "y4ngz.lethalcompany.eyemonster"; public const string PLUGIN_NAME = "Y4NGZ Eye Monster"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace EyeMonster.Utils { public static class CreatureAudio { public static bool PlayExclusive(AudioSource source, AudioClip clip, bool interrupt) { if ((Object)(object)source == (Object)null || (Object)(object)clip == (Object)null) { return false; } if (source.isPlaying && !interrupt) { return false; } source.Stop(); source.loop = false; source.clip = clip; source.Play(); return true; } public static void Stop(AudioSource source) { if (!((Object)(object)source == (Object)null)) { source.Stop(); source.loop = false; source.clip = null; } } } } namespace EyeMonster.AI { public class EyeMonsterAI : EnemyAI { private enum AudioCue { Idle, Vocal, PlayerHit, Step } public const int StateRoaming = 0; public const int StateInvestigating = 1; public const int StateChasing = 2; public const int StateAttacking = 3; public const int StateFleeing = 4; [Header("Exclusive audio")] public AudioClip[] idleClips; public AudioClip[] vocalClips; public AudioClip[] playerHitClips; public AudioClip[] runStepClips; public AudioSource exclusiveAudioSource; [Header("Cosmetics")] public EyeMonsterSlimeTrail slimeTrail; private const float LightCheckInterval = 0.2f; private const float PassiveEyelidClosure = 0.24f; private const float FlashlightEyelidClosure = 0.72f; private const float PassiveEyelidSmoothTime = 0.42f; private const float RevealEyelidSmoothTime = 0.24f; private const float FlashlightEyelidSmoothTime = 0.16f; private const float DeathEyelidSmoothTime = 0.13f; private const float IdleAudioMinSeconds = 7.5f; private const float IdleAudioMaxSeconds = 14f; private const float ChaseRangeMultiplier = 1.75f; private const float RootBodyHeight = 2.8f; private const float RootBodyWidth = 2.05f; private const float TriggerHeight = 2.9f; private const float TriggerWidth = 2.3f; private static readonly Vector3 UpperLidOpenPosition = new Vector3(0f, 0.53408f, 0.668f); private static readonly Vector3 LowerLidOpenPosition = new Vector3(0f, 0.53408f, 0.668f); private static readonly Vector3 UpperLidClosedPosition = new Vector3(0f, 0.53408f, 0.668f); private static readonly Vector3 LowerLidClosedPosition = new Vector3(0.44242f, 0.53408f, 0.668f); private static readonly Quaternion UpperLidOpenRotation = Quaternion.identity; private static readonly Quaternion LowerLidOpenRotation = Quaternion.identity; private static readonly Quaternion UpperLidClosedRotation = Quaternion.Euler(35.10085f, 0.00239f, 0.00126f); private static readonly Quaternion LowerLidClosedRotation = Quaternion.Euler(-37.8065f, 0.00281f, -0.00115f); private readonly Dictionary _noticeCooldownUntil = new Dictionary(); private readonly int[] _lastAudioIndices = new int[4] { -1, -1, -1, -1 }; private float _loseTargetTimer; private float _attackCooldownTimer; private float _lightCheckTimer; private float _fleeTimer; private float _investigationStartedAt; private float _nextIdleAudioTime; private float _eyelidClosure = 0.24f; private float _eyelidClosureVelocity; private float _remoteMovingUntil; private Vector3 _lastAnimationPosition; private bool _hasLastAnimationPosition; private bool _eyelidsInitialized; private Vector3 _fleeDestination; private Vector3 _lastLightThreatPosition; private Coroutine _attackCoroutine; private bool _gazeConfirmedForTarget; private Transform _visualRoot; private Transform _eyeBone; private Transform _upperLid; private Transform _lowerLid; private float RoamSpeed => Mathf.Max(0.1f, Plugin.ModConfig.RoamSpeed.Value); private float InvestigateSpeed => 2.6f; private float ChaseSpeed => Mathf.Max(0.1f, Plugin.ModConfig.ChaseSpeed.Value); private float FleeSpeed => Mathf.Max(0.1f, Plugin.ModConfig.FleeSpeed.Value); private int AttackDamage => Mathf.Max(0, Plugin.ModConfig.AttackDamage.Value); private float AttackCooldown => Mathf.Max(0.1f, Plugin.ModConfig.AttackCooldown.Value); private float AttackRange => 2.5f; private float NoticeRange => Mathf.Max(2f, Plugin.ModConfig.NoticeRange.Value); private float NoticeViewAngle => 52f; private float PlayerGazeAngle => Mathf.Clamp(Plugin.ModConfig.GazeAngle.Value, 5f, 90f); private float InvestigationStopDistance => 4.5f; private float InvestigationDecisionDelay => 0.8f; private float FlashlightDetectionRange => Mathf.Max(2f, Plugin.ModConfig.FlashlightRange.Value); private float FlashlightDetectionAngle => 25f; private float FleeDuration => Mathf.Max(0.5f, Plugin.ModConfig.FleeDuration.Value); private float LoseTargetSeconds => 3.5f; private float FailedNoticeCooldown => 4f; internal bool ShouldEmitSlimeTrail { get { if (!base.isEnemyDead && base.ventAnimationFinished) { return base.currentBehaviourStateIndex != 3; } return false; } } private bool AgentCanNavigate { get { if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled) { return base.agent.isOnNavMesh; } return false; } } private void LogError(string message) { Plugin.Log.LogError((object)message); } private void LogDebug(string message) { EyeMonsterConfig modConfig = Plugin.ModConfig; if (modConfig != null && modConfig.DebugLogs.Value) { Plugin.Log.LogInfo((object)("[EyeMon] " + message)); } } public override void Awake() { try { ((EnemyAI)this).Awake(); RepairRuntimeLayersAndTags(); EnsureRuntimeGeometryAndHitDetection(); CacheVisualRig(); ConsolidateAudioSources(); } catch (Exception arg) { LogError($"EyeMonsterAI.Awake: {arg}"); } } public override void Start() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) try { ((EnemyAI)this).Start(); RepairRuntimeLayersAndTags(); EnsureRuntimeGeometryAndHitDetection(); CacheVisualRig(); ConsolidateAudioSources(); base.enemyHP = Mathf.Max(1, Plugin.ModConfig.Health.Value); ConfigureSearchDefaults(); if (((NetworkBehaviour)this).IsOwner) { RepairAgentPlacementIfNeeded(); } ConfigureAgent(RoamSpeed, 0f); slimeTrail?.Bind(this); if (((NetworkBehaviour)this).IsServer) { ResetIdleAudioTimer(); } LogDebug($"Spawned at {((Component)this).transform.position}, HP={base.enemyHP}"); } catch (Exception arg) { LogError($"EyeMonsterAI.Start: {arg}"); } } private void RepairRuntimeLayersAndTags() { int num = LayerMask.NameToLayer("Enemies"); if (num >= 0) { ((Component)this).gameObject.layer = num; } TrySetTag(((Component)this).gameObject, "Enemy"); Plugin.EnsureScanNode(((Component)this).gameObject); FixNamedChildLayer("MapDot", "MapRadar"); Transform val = ((Component)this).transform.Find("Collision"); if ((Object)(object)val != (Object)null) { if (num >= 0) { ((Component)val).gameObject.layer = num; } TrySetTag(((Component)val).gameObject, "Enemy"); } } private void FixNamedChildLayer(string childName, string layerName) { Transform val = ((Component)this).transform.Find(childName); if (!((Object)(object)val == (Object)null)) { int num = LayerMask.NameToLayer(layerName); if (num < 0) { Plugin.Log.LogWarning((object)$"[EyeMon] Layer '{layerName}' is unavailable; '{childName}' remains on layer {((Component)val).gameObject.layer}."); } else { ((Component)val).gameObject.layer = num; } } } private static void TrySetTag(GameObject target, string tagName) { if ((Object)(object)target == (Object)null) { return; } try { target.tag = tagName; } catch (UnityException) { Plugin.Log.LogWarning((object)("[EyeMon] Tag '" + tagName + "' is unavailable for '" + ((Object)target).name + "'.")); } } private void EnsureRuntimeGeometryAndHitDetection() { //IL_00b0: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.agent != (Object)null) { base.agent.baseOffset = 0f; base.agent.radius = 0.42f; base.agent.height = 2.45f; base.agent.acceleration = 12f; base.agent.angularSpeed = 180f; base.agent.autoRepath = true; base.agent.autoTraverseOffMeshLink = true; } BoxCollider val = ((Component)this).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)this).gameObject.AddComponent(); } ((Collider)val).enabled = true; ((Collider)val).isTrigger = false; val.center = new Vector3(0f, 1.4f, 0f); val.size = new Vector3(2.05f, 2.8f, 2.05f); Transform val2 = ((Component)this).transform.Find("Collision"); if ((Object)(object)val2 == (Object)null) { val2 = new GameObject("Collision").transform; val2.SetParent(((Component)this).transform, false); } val2.localPosition = Vector3.zero; TrySetTag(((Component)val2).gameObject, "Enemy"); int num = LayerMask.NameToLayer("Enemies"); if (num >= 0) { ((Component)val2).gameObject.layer = num; } BoxCollider val3 = ((Component)val2).GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)val2).gameObject.AddComponent(); } ((Collider)val3).enabled = true; ((Collider)val3).isTrigger = true; val3.center = new Vector3(0f, 1.45f, 0f); val3.size = new Vector3(2.3f, 2.9f, 2.3f); Rigidbody val4 = ((Component)val2).GetComponent(); if ((Object)(object)val4 == (Object)null) { val4 = ((Component)val2).gameObject.AddComponent(); } val4.isKinematic = true; val4.useGravity = false; val4.detectCollisions = true; WireHitDetector(((Component)val2).gameObject); } private void WireHitDetector(GameObject host) { if (!((Object)(object)host == (Object)null)) { EnemyAICollisionDetect val = host.GetComponent(); if ((Object)(object)val == (Object)null) { val = host.AddComponent(); } val.mainScript = (EnemyAI)(object)this; val.alwaysAllowHitting = true; val.canCollideWithEnemies = false; val.onlyCollideWhenGrounded = false; } } private void CacheVisualRig() { if ((Object)(object)_visualRoot == (Object)null) { _visualRoot = ((Component)this).transform.Find("VisualRoot"); } if ((Object)(object)_eyeBone == (Object)null) { _eyeBone = FindDescendantByExactName(((Component)this).transform, "eye"); } if ((Object)(object)_upperLid == (Object)null) { _upperLid = FindDescendantByExactName(((Component)this).transform, "lid_up"); } if ((Object)(object)_lowerLid == (Object)null) { _lowerLid = FindDescendantByExactName(((Component)this).transform, "lid_down"); } } private static Transform FindDescendantByExactName(Transform root, string childName) { if ((Object)(object)root == (Object)null) { return null; } for (int i = 0; i < root.childCount; i++) { Transform child = root.GetChild(i); if (string.Equals(((Object)child).name, childName, StringComparison.OrdinalIgnoreCase)) { return child; } Transform val = FindDescendantByExactName(child, childName); if ((Object)(object)val != (Object)null) { return val; } } return null; } private void LateUpdate() { try { CacheVisualRig(); SyncEyeAnchorToBone(); UpdateEyelidExpression(); } catch (Exception arg) { LogError($"EyeMonsterAI.LateUpdate: {arg}"); } } private void SyncEyeAnchorToBone() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.eye == (Object)null) { base.eye = ((Component)this).transform.Find("Eye"); } if (!((Object)(object)base.eye == (Object)null) && !((Object)(object)_eyeBone == (Object)null)) { base.eye.position = _eyeBone.position; base.eye.rotation = ((Component)this).transform.rotation; } } private void UpdateEyelidExpression() { //IL_00c0: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_upperLid == (Object)null) && !((Object)(object)_lowerLid == (Object)null)) { if (!_eyelidsInitialized) { _eyelidClosure = (base.isEnemyDead ? 1f : GetDesiredEyelidClosure()); _eyelidClosureVelocity = 0f; _eyelidsInitialized = true; } float num = (base.isEnemyDead ? 1f : GetDesiredEyelidClosure()); float eyelidSmoothTime = GetEyelidSmoothTime(num); _eyelidClosure = Mathf.SmoothDamp(_eyelidClosure, num, ref _eyelidClosureVelocity, eyelidSmoothTime, 4f, Time.deltaTime); if (Mathf.Abs(_eyelidClosure - num) < 0.0005f) { _eyelidClosure = num; } float num2 = Mathf.Clamp01(_eyelidClosure); _upperLid.localPosition = Vector3.Lerp(UpperLidOpenPosition, UpperLidClosedPosition, num2); _lowerLid.localPosition = Vector3.Lerp(LowerLidOpenPosition, LowerLidClosedPosition, num2); _upperLid.localRotation = Quaternion.Slerp(UpperLidOpenRotation, UpperLidClosedRotation, num2); _lowerLid.localRotation = Quaternion.Slerp(LowerLidOpenRotation, LowerLidClosedRotation, num2); } } private float GetDesiredEyelidClosure() { switch (base.currentBehaviourStateIndex) { case 1: case 2: case 3: return 0f; case 4: return 0.72f; default: return 0.24f; } } private float GetEyelidSmoothTime(float desiredClosure) { if (base.isEnemyDead) { return 0.13f; } if (base.currentBehaviourStateIndex == 4) { return 0.16f; } if (desiredClosure <= 0.001f) { return 0.24f; } return 0.42f; } private void ConsolidateAudioSources() { AudioSource val = (((Object)(object)exclusiveAudioSource != (Object)null) ? exclusiveAudioSource : (((Object)(object)base.creatureVoice != (Object)null) ? base.creatureVoice : base.creatureSFX)); if ((Object)(object)base.creatureVoice != (Object)null && (Object)(object)base.creatureVoice != (Object)(object)val) { CreatureAudio.Stop(base.creatureVoice); } if ((Object)(object)base.creatureSFX != (Object)null && (Object)(object)base.creatureSFX != (Object)(object)val) { CreatureAudio.Stop(base.creatureSFX); } exclusiveAudioSource = val; if ((Object)(object)val != (Object)null) { val.playOnAwake = false; val.loop = false; base.creatureVoice = val; base.creatureSFX = val; } } private void RepairAgentPlacementIfNeeded() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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) if (!((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled && !base.agent.isOnNavMesh) { int num = ((base.agent.areaMask == 0) ? (-1) : base.agent.areaMask); NavMeshHit val = default(NavMeshHit); if (!NavMesh.SamplePosition(((Component)this).transform.position, ref val, 4f, num)) { Plugin.Log.LogWarning((object)$"[EyeMon] Could not place NavMeshAgent near spawn position {((Component)this).transform.position}."); return; } ((Behaviour)base.agent).enabled = false; ((Component)this).transform.position = ((NavMeshHit)(ref val)).position; ((Behaviour)base.agent).enabled = true; LogDebug($"Repaired NavMeshAgent placement to {((NavMeshHit)(ref val)).position}."); } } public override void Update() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) try { ((EnemyAI)this).Update(); if (base.isEnemyDead || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayersDead) { return; } if (_attackCooldownTimer > 0f) { _attackCooldownTimer -= Time.deltaTime; } UpdateWalkingAnimation(); if (((NetworkBehaviour)this).IsOwner) { switch (base.currentBehaviourStateIndex) { case 1: UpdateTargetDestination(InvestigateSpeed, InvestigationStopDistance); break; case 2: UpdateTargetDestination(ChaseSpeed, Mathf.Max(0.25f, AttackRange * 0.65f)); break; case 4: ConfigureAgent(FleeSpeed, 0f); if (AgentCanNavigate) { ((EnemyAI)this).SetDestinationToPosition(_fleeDestination, false); } break; } } if (((NetworkBehaviour)this).IsServer) { TickIdleAudio(); } } catch (Exception arg) { LogError($"EyeMonsterAI.Update: {arg}"); } } private void UpdateWalkingAnimation() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) //IL_0042: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0087: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; Vector3 val; if (_hasLastAnimationPosition) { val = position - _lastAnimationPosition; if (((Vector3)(ref val)).sqrMagnitude > 1E-06f) { _remoteMovingUntil = Time.time + 0.15f; } } _lastAnimationPosition = position; _hasLastAnimationPosition = true; if (!((Object)(object)base.creatureAnimator == (Object)null)) { int num; if (!((NetworkBehaviour)this).IsOwner) { num = ((Time.time < _remoteMovingUntil) ? 1 : 0); } else if (AgentCanNavigate) { val = base.agent.velocity; num = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? 1 : 0); } else { num = 0; } bool flag = (byte)num != 0; if (!base.ventAnimationFinished || base.currentBehaviourStateIndex == 3) { flag = false; } base.creatureAnimator.SetBool("isWalking", flag); } } private void UpdateTargetDestination(float speed, float stoppingDistance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (IsValidTarget(base.targetPlayer) && AgentCanNavigate) { ConfigureAgent(speed, stoppingDistance); ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); ((EnemyAI)this).SetDestinationToPosition(((Component)base.targetPlayer).transform.position, false); } } public override void DoAIInterval() { try { ((EnemyAI)this).DoAIInterval(); if (!base.isEnemyDead && !((Object)(object)StartOfRound.Instance == (Object)null) && !StartOfRound.Instance.allPlayersDead && ((NetworkBehaviour)this).IsOwner && (base.currentBehaviourStateIndex == 4 || !TryBeginFlashlightFlee())) { switch (base.currentBehaviourStateIndex) { case 0: DoRoaming(); break; case 1: DoInvestigating(); break; case 2: DoChasing(); break; case 4: DoFleeing(); break; case 3: break; } } } catch (Exception arg) { LogError($"EyeMonsterAI.DoAIInterval: {arg}"); } } private void DoRoaming() { ConfigureAgent(RoamSpeed, 0f); StartFacilitySearchIfNeeded(); PlayerControllerB val = FindNoticeTarget(); if (!((Object)(object)val == (Object)null)) { StopFacilitySearch(); base.targetPlayer = val; _gazeConfirmedForTarget = false; _loseTargetTimer = 0f; _investigationStartedAt = Time.time; ((EnemyAI)this).SetMovingTowardsTargetPlayer(val); PlayNetworkedCue(AudioCue.Vocal, interrupt: true); ((EnemyAI)this).SwitchToBehaviourState(1); LogDebug("Noticed " + val.playerUsername + "; beginning cautious approach."); } } private void DoInvestigating() { //IL_001b: 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) if (!IsValidTarget(base.targetPlayer)) { DropTarget(addNoticeCooldown: false); return; } float num = Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position); if (!(num <= NoticeRange * 1.75f) || !HasClearSightToPlayer(base.targetPlayer)) { _loseTargetTimer += base.AIIntervalTime; if (_loseTargetTimer >= LoseTargetSeconds) { DropTarget(addNoticeCooldown: true); } return; } _loseTargetTimer = 0f; ConfigureAgent(InvestigateSpeed, InvestigationStopDistance); ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); if (!(num > InvestigationStopDistance) && !(Time.time - _investigationStartedAt < InvestigationDecisionDelay)) { StopAgentPath(); FaceTarget(base.targetPlayer); if (IsMutualGaze(base.targetPlayer)) { _gazeConfirmedForTarget = true; PlayNetworkedCue(AudioCue.Vocal, interrupt: true); ConfigureAgent(ChaseSpeed, Mathf.Max(0.25f, AttackRange * 0.65f)); ((EnemyAI)this).SwitchToBehaviourState(2); LogDebug(base.targetPlayer.playerUsername + " looked at the eye; aggro confirmed."); } else { LogDebug(base.targetPlayer.playerUsername + " refused eye contact; forgetting target."); DropTarget(addNoticeCooldown: true); } } } private void DoChasing() { //IL_0023: 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) if (!IsValidTarget(base.targetPlayer) || !_gazeConfirmedForTarget) { DropTarget(addNoticeCooldown: false); return; } float num = Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position); if (!(num <= NoticeRange * 1.75f) || !HasClearSightToPlayer(base.targetPlayer)) { _loseTargetTimer += base.AIIntervalTime; if (_loseTargetTimer >= LoseTargetSeconds) { LogDebug($"Lost {base.targetPlayer.playerUsername} after {_loseTargetTimer:F1}s."); DropTarget(addNoticeCooldown: false); return; } } else { _loseTargetTimer = 0f; } ConfigureAgent(ChaseSpeed, Mathf.Max(0.25f, AttackRange * 0.65f)); ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); if (num <= AttackRange && _attackCooldownTimer <= 0f) { EnterAttacking(); } } private void EnterAttacking() { if (_gazeConfirmedForTarget && IsValidTarget(base.targetPlayer)) { StopAgentPath(); ((EnemyAI)this).SwitchToBehaviourState(3); TriggerAttackAnimationNetworked(); if (_attackCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_attackCoroutine); } _attackCoroutine = ((MonoBehaviour)this).StartCoroutine(AttackRoutine()); } } private IEnumerator AttackRoutine() { try { _attackCooldownTimer = AttackCooldown; } catch (Exception arg) { LogError($"AttackRoutine begin: {arg}"); _attackCoroutine = null; yield break; } yield return (object)new WaitForSeconds(AttackCooldown); try { if (base.isEnemyDead || base.currentBehaviourStateIndex == 4) { _attackCoroutine = null; yield break; } if (!IsValidTarget(base.targetPlayer) || !_gazeConfirmedForTarget) { DropTarget(addNoticeCooldown: false); } else if (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) <= NoticeRange * 1.75f) { ((EnemyAI)this).SwitchToBehaviourState(2); } else { DropTarget(addNoticeCooldown: false); } } catch (Exception arg2) { LogError($"AttackRoutine end: {arg2}"); } _attackCoroutine = null; } private void TriggerAttackAnimationNetworked() { if (((NetworkBehaviour)this).IsServer) { PlayAttackAnimationClientRpc(); } else { RequestAttackAnimationServerRpc(); } } [ServerRpc(RequireOwnership = false)] public void RequestAttackAnimationServerRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(4159574820u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 4159574820u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!base.isEnemyDead) { PlayAttackAnimationClientRpc(); } } } [ClientRpc] public void PlayAttackAnimationClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1996458905u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1996458905u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!base.isEnemyDead && (Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.SetTrigger("doAttack"); } } } private PlayerControllerB FindNoticeTarget() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00c0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return null; } PlayerControllerB result = null; float num = float.PositiveInfinity; float num2 = NoticeRange * NoticeRange; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (IsValidTarget(val) && !IsNoticeCoolingDown(val)) { Vector3 val2 = (((Object)(object)val.gameplayCamera != (Object)null) ? ((Component)val.gameplayCamera).transform.position : (((Component)val).transform.position + Vector3.up)); Vector3 val3 = val2 - GetEyeFocusPosition(); float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (!(sqrMagnitude > num2) && !(sqrMagnitude >= num) && ((EnemyAI)this).CheckLineOfSightForPosition(val2, NoticeViewAngle, Mathf.CeilToInt(NoticeRange), -1f, base.eye)) { result = val; num = sqrMagnitude; } } } return result; } private bool IsMutualGaze(PlayerControllerB player) { //IL_003a: 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) //IL_0023: 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_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_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_0082: Unknown result type (might be due to invalid IL or missing references) if (!IsValidTarget(player)) { return false; } Vector3 val = (((Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform.position : (((Component)player).transform.position + Vector3.up)) - GetEyeFocusPosition(); if (!(((Vector3)(ref val)).sqrMagnitude > 0.001f) || !(Vector3.Angle(((Component)this).transform.forward, val) <= NoticeViewAngle) || !HasClearSightToPlayer(player)) { return false; } return player.HasLineOfSightToPosition(GetEyeFocusPosition(), PlayerGazeAngle, Mathf.CeilToInt(NoticeRange + 6f), -1f, -1); } private bool HasClearSightToPlayer(PlayerControllerB player) { //IL_003a: 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) //IL_0023: 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_003f: 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) if (!IsValidTarget(player)) { return false; } Vector3 val = (((Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform.position : (((Component)player).transform.position + Vector3.up)); return ((EnemyAI)this).CheckLineOfSightForPosition(val, 180f, Mathf.CeilToInt(NoticeRange * 1.75f), -1f, base.eye); } private Vector3 GetEyeFocusPosition() { //IL_0034: 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_0023: 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) if (!((Object)(object)base.eye != (Object)null)) { return ((Component)this).transform.position + Vector3.up * 1.45f; } return base.eye.position; } private static bool IsValidTarget(PlayerControllerB player) { if ((Object)(object)player != (Object)null && player.isPlayerControlled) { return !player.isPlayerDead; } return false; } private bool IsNoticeCoolingDown(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } if (_noticeCooldownUntil.TryGetValue(player.actualClientId, out var value)) { return Time.time < value; } return false; } private void DropTarget(bool addNoticeCooldown) { PlayerControllerB targetPlayer = base.targetPlayer; if (addNoticeCooldown && (Object)(object)targetPlayer != (Object)null) { _noticeCooldownUntil[targetPlayer.actualClientId] = Time.time + FailedNoticeCooldown; } base.targetPlayer = null; base.movingTowardsTargetPlayer = false; _gazeConfirmedForTarget = false; _loseTargetTimer = 0f; if (_attackCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_attackCoroutine); _attackCoroutine = null; } ConfigureAgent(RoamSpeed, 0f); if (base.currentBehaviourStateIndex != 0) { ((EnemyAI)this).SwitchToBehaviourState(0); } } private void FaceTarget(PlayerControllerB player) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; val.y = 0f; if (!(((Vector3)(ref val)).sqrMagnitude < 0.001f)) { Quaternion rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); ((Component)this).transform.rotation = rotation; } } } private void ConfigureSearchDefaults() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown if (base.currentSearch == null) { base.currentSearch = new AISearchRoutine(); } base.currentSearch.loopSearch = true; base.currentSearch.randomized = true; base.currentSearch.searchWidth = 200f; base.currentSearch.searchPrecision = 5f; } private void StartFacilitySearchIfNeeded() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsOwner && AgentCanNavigate) { ConfigureSearchDefaults(); if (!base.currentSearch.inProgress) { ((EnemyAI)this).StartSearch(((Component)this).transform.position, base.currentSearch); } } } private void StopFacilitySearch() { if (base.currentSearch != null && base.currentSearch.inProgress) { ((EnemyAI)this).StopSearch(base.currentSearch, false); } } private void ConfigureAgent(float speed, float stoppingDistance) { if (AgentCanNavigate) { base.agent.speed = speed; base.agent.stoppingDistance = stoppingDistance; } } private void StopAgentPath() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) base.movingTowardsTargetPlayer = false; if (AgentCanNavigate) { base.agent.ResetPath(); base.agent.velocity = Vector3.zero; base.agent.speed = 0f; } } private bool TryBeginFlashlightFlee() { //IL_0056: 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) _lightCheckTimer += base.AIIntervalTime; if (_lightCheckTimer < 0.2f) { return false; } _lightCheckTimer = 0f; if (!TryGetFlashlightThreat(out var threatPosition, out var threatPlayer)) { return false; } if ((Object)(object)threatPlayer != (Object)null) { _lastLightThreatPosition = ((Component)threatPlayer).transform.position; } StartFleeFrom(threatPosition); return true; } private void DoFleeing() { ConfigureAgent(FleeSpeed, 0f); TryRefreshFlashlightFlee(); _fleeTimer -= base.AIIntervalTime; if (_fleeTimer <= 0f) { LogDebug("Flashlight flee expired; returning to facility search."); DropTarget(addNoticeCooldown: false); } } private void TryRefreshFlashlightFlee() { //IL_0053: 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_004d: Unknown result type (might be due to invalid IL or missing references) _lightCheckTimer += base.AIIntervalTime; if (_lightCheckTimer < 0.2f) { return; } _lightCheckTimer = 0f; if (TryGetFlashlightThreat(out var threatPosition, out var threatPlayer)) { if ((Object)(object)threatPlayer != (Object)null) { _lastLightThreatPosition = ((Component)threatPlayer).transform.position; } StartFleeFrom(threatPosition); } } private void StartFleeFrom(Vector3 threatPosition) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0066: 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_0076: 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_007c: 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_00ba: 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_00c5: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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) bool num = base.currentBehaviourStateIndex != 4; _fleeTimer = FleeDuration; base.targetPlayer = null; base.movingTowardsTargetPlayer = false; _gazeConfirmedForTarget = false; _loseTargetTimer = 0f; if (_attackCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_attackCoroutine); _attackCoroutine = null; } StopFacilitySearch(); Vector3 val = ((threatPosition == Vector3.zero) ? _lastLightThreatPosition : threatPosition); Vector3 val2 = ((Component)this).transform.position - val; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = -((Component)this).transform.forward; } ((Vector3)(ref val2)).Normalize(); NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(((Component)this).transform.position + val2 * 20f, ref val3, 15f, -1)) { _fleeDestination = ((NavMeshHit)(ref val3)).position; } else { _fleeDestination = ((Component)this).transform.position + val2 * 10f; } ConfigureAgent(FleeSpeed, 0f); if (AgentCanNavigate) { ((EnemyAI)this).SetDestinationToPosition(_fleeDestination, false); } if (num) { ((EnemyAI)this).SwitchToBehaviourState(4); } } private bool TryGetFlashlightThreat(out Vector3 threatPosition, out PlayerControllerB threatPlayer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0091: Unknown result type (might be due to invalid IL or missing references) threatPosition = Vector3.zero; threatPlayer = null; if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { return false; } float angleCosine = Mathf.Cos(Mathf.Clamp(FlashlightDetectionAngle, 1f, 89f) * (MathF.PI / 180f)); PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (IsValidTarget(val) && (CheckFlashlightSource(val, FlashlightDetectionRange, angleCosine, out threatPosition) || CheckHelmetLight(val, FlashlightDetectionRange, angleCosine, out threatPosition))) { threatPlayer = val; _lastLightThreatPosition = threatPosition; return true; } } return false; } private bool CheckFlashlightSource(PlayerControllerB player, float range, float angleCosine, out Vector3 sourcePosition) { //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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) sourcePosition = Vector3.zero; GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer; FlashlightItem val = (FlashlightItem)(object)((currentlyHeldObjectServer is FlashlightItem) ? currentlyHeldObjectServer : null); if ((Object)(object)val == (Object)null || !((GrabbableObject)val).isBeingUsed) { return false; } Transform val2 = (((Object)(object)val.flashlightBulb != (Object)null) ? ((Component)val.flashlightBulb).transform : ((Component)val).transform); if (CheckLightBeam(val2.position, val2.forward, GetEyeFocusPosition(), range, angleCosine)) { sourcePosition = val2.position; return true; } if ((Object)(object)val.flashlightBulbGlow != (Object)null && CheckLightBeam(((Component)val.flashlightBulbGlow).transform.position, ((Component)val.flashlightBulbGlow).transform.forward, GetEyeFocusPosition(), range, angleCosine)) { sourcePosition = ((Component)val.flashlightBulbGlow).transform.position; return true; } return false; } private bool CheckHelmetLight(PlayerControllerB player, float range, float angleCosine, out Vector3 sourcePosition) { //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_0057: 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_0063: 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_007b: Unknown result type (might be due to invalid IL or missing references) sourcePosition = Vector3.zero; Light helmetLight = player.helmetLight; if ((Object)(object)helmetLight == (Object)null || !((Behaviour)helmetLight).enabled || helmetLight.intensity <= 0f) { return false; } Transform val = (((Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform : ((Component)helmetLight).transform); if (!CheckLightBeam(val.position, val.forward, GetEyeFocusPosition(), range, angleCosine)) { return false; } sourcePosition = val.position; return true; } private bool CheckLightBeam(Vector3 sourcePosition, Vector3 sourceForward, Vector3 detectionPoint, float range, float angleCosine) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_001f: 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_0026: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = detectionPoint - sourcePosition; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.01f || magnitude > range) { return false; } Vector3 val2 = val / magnitude; if (Vector3.Dot(((Vector3)(ref sourceForward)).normalized, val2) > angleCosine) { return HasClearLightPath(sourcePosition, detectionPoint); } return false; } private bool HasClearLightPath(Vector3 sourcePosition, Vector3 detectionPoint) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance == (Object)null) { return true; } Vector3 val = detectionPoint - sourcePosition; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.01f) { return true; } RaycastHit[] array = Physics.RaycastAll(sourcePosition, val / magnitude, magnitude, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { Collider collider = ((RaycastHit)(ref array[i])).collider; if (!((Object)(object)collider == (Object)null) && !((Component)collider).transform.IsChildOf(((Component)this).transform)) { return false; } } return true; } private void TickIdleAudio() { if (!(Time.time < _nextIdleAudioTime)) { ResetIdleAudioTimer(); if (base.currentBehaviourStateIndex == 0 || base.currentBehaviourStateIndex == 1) { BroadcastAudioCue(AudioCue.Idle, interrupt: false); } } } private void ResetIdleAudioTimer() { _nextIdleAudioTime = Time.time + Random.Range(7.5f, 14f); } private void PlayNetworkedCue(AudioCue cue, bool interrupt) { if (((NetworkBehaviour)this).IsServer) { BroadcastAudioCue(cue, interrupt); } else { RequestAudioCueServerRpc((int)cue, interrupt); } } [ServerRpc(RequireOwnership = false)] public void RequestAudioCueServerRpc(int cueValue, bool interrupt) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(398615819u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, cueValue); ((FastBufferWriter)(ref val)).WriteValueSafe(ref interrupt, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 398615819u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (Enum.IsDefined(typeof(AudioCue), cueValue)) { BroadcastAudioCue((AudioCue)cueValue, interrupt); } } } private void BroadcastAudioCue(AudioCue cue, bool interrupt) { AudioClip[] audioPool = GetAudioPool(cue); if (audioPool != null && audioPool.Length != 0) { int num = ChooseAudioIndex(audioPool, _lastAudioIndices[(int)cue]); _lastAudioIndices[(int)cue] = num; PlayAudioCueClientRpc((int)cue, num, interrupt); } } [ClientRpc] public void PlayAudioCueClientRpc(int cueValue, int clipIndex, bool interrupt) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3333831235u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, cueValue); BytePacker.WriteValueBitPacked(val, clipIndex); ((FastBufferWriter)(ref val)).WriteValueSafe(ref interrupt, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 3333831235u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (Enum.IsDefined(typeof(AudioCue), cueValue)) { AudioClip[] audioPool = GetAudioPool((AudioCue)cueValue); if (audioPool != null && clipIndex >= 0 && clipIndex < audioPool.Length) { CreatureAudio.PlayExclusive(exclusiveAudioSource, audioPool[clipIndex], interrupt); } } } private AudioClip[] GetAudioPool(AudioCue cue) { return cue switch { AudioCue.Idle => idleClips, AudioCue.Vocal => vocalClips, AudioCue.PlayerHit => playerHitClips, AudioCue.Step => runStepClips, _ => null, }; } private static int ChooseAudioIndex(AudioClip[] pool, int previous) { if (pool == null || pool.Length <= 1) { return 0; } int num = Random.Range(0, pool.Length); if (num == previous) { num = (num + Random.Range(1, pool.Length)) % pool.Length; } return num; } public void Anim_RunStep() { try { if (!base.isEnemyDead && base.currentBehaviourStateIndex != 3 && runStepClips != null && runStepClips.Length != 0) { int num = ChooseAudioIndex(runStepClips, _lastAudioIndices[3]); if (CreatureAudio.PlayExclusive(exclusiveAudioSource, runStepClips[num], interrupt: false)) { _lastAudioIndices[3] = num; } } } catch (Exception arg) { LogError($"Anim_RunStep: {arg}"); } } public void Anim_AttackDamage() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) try { if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead && _gazeConfirmedForTarget && IsValidTarget(base.targetPlayer) && base.currentBehaviourStateIndex != 4) { if (TryGetFlashlightThreat(out var threatPosition, out var _)) { StartFleeFrom(threatPosition); } else if (!(Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > AttackRange * 1.5f)) { ApplyAttackDamageClientRpc(base.targetPlayer.actualClientId, AttackDamage); BroadcastAudioCue(AudioCue.PlayerHit, interrupt: true); } } } catch (Exception arg) { LogError($"Anim_AttackDamage: {arg}"); } } [ClientRpc] public void ApplyAttackDamageClientRpc(ulong targetClientId, int damage) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_00db: 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_012f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2600942751u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, targetClientId); BytePacker.WriteValueBitPacked(val, damage); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2600942751u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; PlayerControllerB val3 = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val3 == (Object)null) && !val3.isPlayerDead && (val3.actualClientId == targetClientId || val3.playerClientId == targetClientId)) { val3.DamagePlayer(damage, true, true, (CauseOfDeath)0, 0, false, default(Vector3)); } } } public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1) { try { ((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID); if (!base.isEnemyDead) { base.enemyHP -= force; if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.SetTrigger("doHit"); } if (base.enemyHP <= 0 && (((NetworkBehaviour)this).IsOwner || ((NetworkBehaviour)this).IsServer)) { ((EnemyAI)this).KillEnemyOnOwnerClient(false); } } } catch (Exception arg) { LogError($"EyeMonsterAI.HitEnemy: {arg}"); } } public override void KillEnemy(bool destroy = false) { try { ((EnemyAI)this).KillEnemy(destroy); base.isEnemyDead = true; StopFacilitySearch(); StopAgentPath(); CreatureAudio.Stop(exclusiveAudioSource); if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.SetBool("isWalking", false); base.creatureAnimator.SetTrigger("doDeath"); } if (_attackCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_attackCoroutine); _attackCoroutine = null; } } catch (Exception arg) { LogError($"EyeMonsterAI.KillEnemy: {arg}"); } } public override void OnDestroy() { CreatureAudio.Stop(exclusiveAudioSource); ((EnemyAI)this).OnDestroy(); } protected override void __initializeVariables() { ((EnemyAI)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(4159574820u, new RpcReceiveHandler(__rpc_handler_4159574820), "RequestAttackAnimationServerRpc"); ((NetworkBehaviour)this).__registerRpc(1996458905u, new RpcReceiveHandler(__rpc_handler_1996458905), "PlayAttackAnimationClientRpc"); ((NetworkBehaviour)this).__registerRpc(398615819u, new RpcReceiveHandler(__rpc_handler_398615819), "RequestAudioCueServerRpc"); ((NetworkBehaviour)this).__registerRpc(3333831235u, new RpcReceiveHandler(__rpc_handler_3333831235), "PlayAudioCueClientRpc"); ((NetworkBehaviour)this).__registerRpc(2600942751u, new RpcReceiveHandler(__rpc_handler_2600942751), "ApplyAttackDamageClientRpc"); ((EnemyAI)this).__initializeRpcs(); } private static void __rpc_handler_4159574820(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((EyeMonsterAI)(object)target).RequestAttackAnimationServerRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1996458905(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((EyeMonsterAI)(object)target).PlayAttackAnimationClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_398615819(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_006f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int cueValue = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref cueValue); bool interrupt = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref interrupt, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((EyeMonsterAI)(object)target).RequestAudioCueServerRpc(cueValue, interrupt); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3333831235(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0049: 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_005e: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int cueValue = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref cueValue); int clipIndex = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref clipIndex); bool interrupt = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref interrupt, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((EyeMonsterAI)(object)target).PlayAudioCueClientRpc(cueValue, clipIndex, interrupt); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2600942751(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong targetClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref targetClientId); int damage = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref damage); target.__rpc_exec_stage = (__RpcExecStage)1; ((EyeMonsterAI)(object)target).ApplyAttackDamageClientRpc(targetClientId, damage); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "EyeMonsterAI"; } } public sealed class EyeMonsterAnimationRelay : MonoBehaviour { public EyeMonsterAI owner; private EyeMonsterAI Owner { get { if ((Object)(object)owner == (Object)null) { owner = ((Component)this).GetComponentInParent(); } return owner; } } public void Anim_RunStep() { Owner?.Anim_RunStep(); } public void Anim_AttackDamage() { Owner?.Anim_AttackDamage(); } } public sealed class EyeMonsterSlimeTrail : MonoBehaviour { private sealed class SlimeMark { public Transform transform; public MeshRenderer renderer; public MaterialPropertyBlock properties; public float spawnedAt; public Vector4 textureTransform; public bool active; } private const int PoolSize = 128; private const float MarkLifetime = 12f; private const float EmitDistance = 0.78f; private const float GroundProbeHeight = 0.65f; private const float GroundProbeDistance = 2.2f; private const float SurfaceOffset = 0.018f; public Material slimeMaterial; private EyeMonsterAI _owner; private Transform _container; private Mesh _markMesh; private readonly SlimeMark[] _marks = new SlimeMark[128]; private Vector3 _lastPosition; private Vector3 _lastEmitPosition; private bool _hasLastPosition; private bool _hasLastEmitPosition; private int _nextMark; private Color _baseColor = new Color(0.07f, 0.32f, 0.1f, 0.78f); private Color _baseEmission = new Color(0.012f, 0.065f, 0.018f, 1f); private bool _warnedMissingMaterial; public void Bind(EyeMonsterAI owner) { _owner = owner; EnsurePool(); } private void Awake() { if ((Object)(object)_owner == (Object)null) { _owner = ((Component)this).GetComponent(); } } private void Start() { EnsurePool(); } private void Update() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_007d: 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_0089: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00c6: Unknown result type (might be due to invalid IL or missing references) FadeMarks(); if ((Object)(object)_owner == (Object)null) { _owner = ((Component)this).GetComponent(); } if ((Object)(object)_owner == (Object)null || !_owner.ShouldEmitSlimeTrail) { _hasLastPosition = false; _hasLastEmitPosition = false; return; } Vector3 position = ((Component)this).transform.position; if (!_hasLastPosition) { _lastPosition = position; _lastEmitPosition = position; _hasLastPosition = true; _hasLastEmitPosition = true; return; } float num = Vector3.Distance(position, _lastPosition); _lastPosition = position; if (!(num < 0.002f) && (!_hasLastEmitPosition || !(Vector3.Distance(position, _lastEmitPosition) < 0.78f)) && TryFindFloor(position, out var hit)) { EmitMark(hit); _lastEmitPosition = position; _hasLastEmitPosition = true; } } private bool TryFindFloor(Vector3 position, out RaycastHit hit) { //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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5)); return Physics.Raycast(position + Vector3.up * 0.65f, Vector3.down, ref hit, 2.2f, num, (QueryTriggerInteraction)1); } private void EmitMark(RaycastHit hit) { //IL_009f: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00ed: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0167: 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) EnsurePool(); if ((Object)(object)_container == (Object)null || (Object)(object)_markMesh == (Object)null) { return; } if ((Object)(object)slimeMaterial == (Object)null) { if (!_warnedMissingMaterial) { _warnedMissingMaterial = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[EyeMon] Slime material is missing; trail emission is disabled."); } } return; } SlimeMark slimeMark = _marks[_nextMark]; _nextMark = (_nextMark + 1) % 128; float num = Random.Range(0f, 360f); float num2 = Random.Range(0.55f, 0.92f); int num3 = Random.Range(0, 4); Quaternion val = Quaternion.FromToRotation(Vector3.up, ((RaycastHit)(ref hit)).normal); slimeMark.transform.position = ((RaycastHit)(ref hit)).point + ((RaycastHit)(ref hit)).normal * 0.018f; slimeMark.transform.rotation = Quaternion.AngleAxis(num, ((RaycastHit)(ref hit)).normal) * val; slimeMark.transform.localScale = new Vector3(num2, 1f, num2 * Random.Range(0.58f, 1.28f)); ((Renderer)slimeMark.renderer).sharedMaterial = slimeMaterial; ((Renderer)slimeMark.renderer).enabled = true; slimeMark.spawnedAt = Time.time; slimeMark.textureTransform = new Vector4(0.5f, 0.5f, (float)(num3 % 2) * 0.5f, (float)(num3 / 2) * 0.5f); slimeMark.active = true; SetMarkAlpha(slimeMark, _baseColor.a); } private void FadeMarks() { float time = Time.time; for (int i = 0; i < _marks.Length; i++) { SlimeMark slimeMark = _marks[i]; if (slimeMark != null && slimeMark.active) { float num = Mathf.Clamp01((time - slimeMark.spawnedAt) / 12f); if (num >= 1f) { slimeMark.active = false; ((Renderer)slimeMark.renderer).enabled = false; } else { float num2 = 1f - Mathf.SmoothStep(0f, 1f, num); SetMarkAlpha(slimeMark, _baseColor.a * num2); } } } } private void SetMarkAlpha(SlimeMark mark, float alpha) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //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_0070: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00e1: Unknown result type (might be due to invalid IL or missing references) Color baseColor = _baseColor; baseColor.a = alpha; float num = ((_baseColor.a > 0.001f) ? Mathf.Clamp01(alpha / _baseColor.a) : 0f); Color val = _baseEmission * num; val.a = 1f; ((Renderer)mark.renderer).GetPropertyBlock(mark.properties); mark.properties.SetColor("_BaseColor", baseColor); mark.properties.SetColor("_Color", baseColor); mark.properties.SetColor("_EmissiveColor", val); mark.properties.SetColor("_EmissiveColorLDR", val); mark.properties.SetVector("_BaseColorMap_ST", mark.textureTransform); mark.properties.SetVector("_EmissiveColorMap_ST", mark.textureTransform); mark.properties.SetVector("_MainTex_ST", mark.textureTransform); ((Renderer)mark.renderer).SetPropertyBlock(mark.properties); } private void EnsurePool() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) if ((Object)(object)_container != (Object)null) { return; } GameObject val = new GameObject(((Object)this).name + "_SlimeTrailPool"); _container = val.transform; _markMesh = BuildOrganicMarkMesh(); if ((Object)(object)slimeMaterial != (Object)null) { if (slimeMaterial.HasProperty("_BaseColor")) { _baseColor = slimeMaterial.GetColor("_BaseColor"); } else if (slimeMaterial.HasProperty("_Color")) { _baseColor = slimeMaterial.GetColor("_Color"); } if (slimeMaterial.HasProperty("_EmissiveColor")) { _baseEmission = slimeMaterial.GetColor("_EmissiveColor"); } } for (int i = 0; i < 128; i++) { GameObject val2 = new GameObject($"SlimeMark_{i:00}"); val2.transform.SetParent(_container, false); val2.AddComponent().sharedMesh = _markMesh; MeshRenderer val3 = val2.AddComponent(); ((Renderer)val3).sharedMaterial = slimeMaterial; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; ((Renderer)val3).lightProbeUsage = (LightProbeUsage)1; ((Renderer)val3).reflectionProbeUsage = (ReflectionProbeUsage)2; ((Renderer)val3).enabled = false; _marks[i] = new SlimeMark { transform = val2.transform, renderer = val3, properties = new MaterialPropertyBlock(), active = false }; } } private static Mesh BuildOrganicMarkMesh() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //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_004a: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "EyeMonsterSlimeOrganicMark" }; Vector3[] array = (Vector3[])(object)new Vector3[25]; Vector2[] array2 = (Vector2[])(object)new Vector2[25]; Vector3[] array3 = (Vector3[])(object)new Vector3[25]; int[] array4 = new int[72]; array[0] = Vector3.zero; array2[0] = new Vector2(0.5f, 0.5f); array3[0] = Vector3.up; for (int i = 0; i < 24; i++) { float num = (float)i * MathF.PI * 2f / 24f; float num2 = 0.46f * (0.88f + Mathf.Sin(num * 3f + 0.7f) * 0.08f + Mathf.Sin(num * 7f + 1.9f) * 0.045f + Mathf.Sin(num * 11f + 0.2f) * 0.025f); float num3 = Mathf.Cos(num) * num2; float num4 = Mathf.Sin(num) * num2; int num5 = i + 1; array[num5] = new Vector3(num3, 0f, num4); array2[num5] = new Vector2(num3 + 0.5f, num4 + 0.5f); array3[num5] = Vector3.up; int num6 = (i + 1) % 24 + 1; int num7 = i * 3; array4[num7] = 0; array4[num7 + 1] = num6; array4[num7 + 2] = num5; } val.vertices = array; val.uv = array2; val.normals = array3; val.triangles = array4; val.RecalculateBounds(); return val; } private void OnDestroy() { if ((Object)(object)_container != (Object)null) { Object.Destroy((Object)(object)((Component)_container).gameObject); } if ((Object)(object)_markMesh != (Object)null) { Object.Destroy((Object)(object)_markMesh); } } } } namespace Y4NGZMonsters.Shared { internal static class ConfigSectionNameMigration { private static readonly IReadOnlyDictionary SectionNames = new Dictionary(StringComparer.Ordinal) { { "00 - General", "General" }, { "10 - Spawning", "Spawning" }, { "20 - Core Stats", "Core Stats" }, { "20 - Video", "Video" }, { "30 - Detection", "Detection" }, { "30 - Encounter Pacing", "Encounter Pacing" }, { "30 - Encounter Rules", "Encounter Rules" }, { "40 - Movement", "Movement" }, { "50 - Combat", "Combat" }, { "60 - Abilities", "Abilities" }, { "60 - Presentation", "Presentation" }, { "60 - Audio", "Audio" }, { "70 - Audio and Presentation", "Audio and Presentation" }, { "99 - Diagnostics", "Diagnostics" } }; private static readonly Regex NumberedSectionHeader = new Regex("^(?[ \\t]*)\\[(?
00 - General|10 - Spawning|20 - Core Stats|20 - Video|30 - Detection|30 - Encounter Pacing|30 - Encounter Rules|40 - Movement|50 - Combat|60 - Abilities|60 - Presentation|60 - Audio|70 - Audio and Presentation|99 - Diagnostics)\\](?[ \\t]*)(?\\r?)$", RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.CultureInvariant); internal static bool TryMigrate(ConfigFile config, ManualLogSource log, string creatureName) { string configFilePath = config.ConfigFilePath; if (!File.Exists(configFilePath)) { return false; } string text = null; try { int replacementCount; string contents = RenameSectionHeaders(File.ReadAllText(configFilePath), out replacementCount); if (replacementCount == 0) { return false; } text = GetBackupPath(configFilePath); File.Copy(configFilePath, text, overwrite: false); File.WriteAllText(configFilePath, contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); config.Reload(); if (log != null) { log.LogInfo((object)($"[{creatureName}] Removed numeric prefixes from {replacementCount} config section header(s). " + "The previous config is backed up at '" + text + "'.")); } return true; } catch (Exception ex) { string text2 = "The original config was not modified."; if (!string.IsNullOrEmpty(text) && File.Exists(text)) { try { File.Copy(text, configFilePath, overwrite: true); config.Reload(); text2 = "The original config was restored from its backup."; } catch (Exception ex2) { text2 = "Automatic restore also failed (" + ex2.Message + "). Restore '" + text + "' manually before editing the config."; } } if (log != null) { log.LogWarning((object)("[" + creatureName + "] Could not remove numeric config section prefixes: " + ex.Message + " " + text2)); } return false; } } internal static string RenameSectionHeaders(string text, out int replacementCount) { int count = 0; string result = NumberedSectionHeader.Replace(text, delegate(Match match) { string value = match.Groups["section"].Value; if (!SectionNames.TryGetValue(value, out var value2)) { return match.Value; } count++; return match.Groups["leading"].Value + "[" + value2 + "]" + match.Groups["trailing"].Value + match.Groups["carriage"].Value; }); replacementCount = count; return result; } private static string GetBackupPath(string configPath) { string text = configPath + ".pre-section-names.bak"; int num = 1; while (File.Exists(text)) { text = configPath + $".pre-section-names.{num}.bak"; num++; } return text; } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace EyeMonster.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }