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.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using GameNetcodeStuff; using Microsoft.CodeAnalysis; using Unity.Netcode; using Unity.Netcode.Components; using UnityEngine; using UnityEngine.AI; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using Y4NGZHarmonic.AI; using Y4NGZHarmonic.NetcodePatcher; 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("Y4NGZHarmonic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+25ca94fed298fe073d4c739917e3b7f046e875bf")] [assembly: AssemblyProduct("Y4NGZHarmonic")] [assembly: AssemblyTitle("Y4NGZHarmonic")] [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 Y4NGZHarmonic { internal static class HarmonicBloodFxBridge { internal const string PluginGuid = "com.y4ngz.bloodfx"; private const string CreatureBloodTypeName = "Y4NGZCompany.Experience.BloodFX.BloodFXCreatureBlood"; private static bool? _pluginPresent; private static bool _bridgeResolved; private static PropertyInfo _isAvailable; private static MethodInfo _playCreatureBleed; internal static void PlayCreatureBleed(int creatureKey, Vector3 point, Vector3 direction, Color tint, int contacts, float scale) { //IL_0054: 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_0066: Unknown result type (might be due to invalid IL or missing references) if (!BloodFxPluginPresent() || !ResolveBridge()) { return; } try { if (_isAvailable != null) { object value = _isAvailable.GetValue(null); if (value is bool && !(bool)value) { return; } } _playCreatureBleed.Invoke(null, new object[6] { creatureKey, point, direction, tint, contacts, scale }); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Harmonic] Optional BloodFX bridge failed: " + ex.GetBaseException().Message)); } } } private static bool BloodFxPluginPresent() { if (!_pluginPresent.HasValue) { _pluginPresent = Chainloader.PluginInfos.ContainsKey("com.y4ngz.bloodfx"); } return _pluginPresent.Value; } private static bool ResolveBridge() { if (_bridgeResolved) { return _playCreatureBleed != null; } _bridgeResolved = true; if (!Chainloader.PluginInfos.TryGetValue("com.y4ngz.bloodfx", out var value) || (Object)(object)value.Instance == (Object)null) { return false; } Type type = ((object)value.Instance).GetType().Assembly.GetType("Y4NGZCompany.Experience.BloodFX.BloodFXCreatureBlood", throwOnError: false); if (type == null) { return false; } _isAvailable = type.GetProperty("IsAvailable", BindingFlags.Static | BindingFlags.Public); _playCreatureBleed = type.GetMethod("PlayCreatureBleed", BindingFlags.Static | BindingFlags.Public, null, new Type[6] { typeof(int), typeof(Vector3), typeof(Vector3), typeof(Color), typeof(int), typeof(float) }, null); return _playCreatureBleed != null; } } internal sealed class HarmonicConfig { public ConfigEntry Enabled { get; } public ConfigEntry SpawnWeightMultiplier { get; } public ConfigEntry MaxCount { get; } public ConfigEntry PowerLevel { get; } public ConfigEntry Health { get; } public ConfigEntry MoveSpeed { get; } public ConfigEntry AlarmChance { get; } public ConfigEntry AlarmAttractionRadius { get; } public ConfigEntry MusicVolume { get; } public ConfigEntry SfxVolume { get; } public ConfigEntry MusicMaxDistance { get; } public ConfigEntry SfxMaxDistance { get; } public ConfigEntry DebugLogs { get; } public HarmonicConfig(ConfigFile config) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Expected O, but got Unknown bool saveOnConfigSet = config.SaveOnConfigSet; config.SaveOnConfigSet = false; try { HarmonicConfigMigration.TryMigrate(config, Plugin.Log); ConfigSectionNameMigration.TryMigrate(config, Plugin.Log, "Harmonic"); Enabled = config.Bind("General", "Enabled", true, "Enable the Harmonic encounter."); SpawnWeightMultiplier = config.Bind("Spawning", "SpawnWeightMultiplier", 1f, new ConfigDescription("Multiplier applied to Harmonic's contextual moon/interior spawn policy. 0 disables natural spawns.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); MaxCount = config.Bind("Spawning", "MaxCount", 1, new ConfigDescription("Maximum number of living Harmonics at once.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 20), Array.Empty())); PowerLevel = config.Bind("Spawning", "PowerLevel", 1.1f, new ConfigDescription("Indoor enemy power budget cost for each Harmonic.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 10f), Array.Empty())); Health = config.Bind("Core Stats", "Health", 4, new ConfigDescription("Hits the Harmonic can take before dying.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100), Array.Empty())); MoveSpeed = config.Bind("Movement", "MoveSpeed", 1.15f, new ConfigDescription("Passive roaming speed.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 10f), Array.Empty())); AlarmChance = config.Bind("Abilities", "AlarmChance", 0.2f, new ConfigDescription("Chance that the next selected track will be the alarm.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); AlarmAttractionRadius = config.Bind("Abilities", "AlarmAttractionRadius", 30f, new ConfigDescription("Maximum distance in metres at which an alarm attracts other indoor enemies.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 200f), Array.Empty())); MusicVolume = config.Bind("Audio and Presentation", "MusicVolume", 0.95f, new ConfigDescription("Volume for idle music.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); SfxVolume = config.Bind("Audio and Presentation", "SfxVolume", 1f, new ConfigDescription("Shared volume for the alarm, hit, and death sounds.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); MusicMaxDistance = config.Bind("Audio and Presentation", "MusicMaxDistance", 65f, new ConfigDescription("Maximum audible distance for Harmonic music.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 65f), Array.Empty())); SfxMaxDistance = config.Bind("Audio and Presentation", "SfxMaxDistance", 42f, new ConfigDescription("Maximum audible distance for alarm, hit, and death sounds.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 42f), Array.Empty())); DebugLogs = config.Bind("Diagnostics", "DebugLogs", false, "Write verbose Harmonic diagnostics to the BepInEx log."); } finally { config.SaveOnConfigSet = saveOnConfigSet; if (saveOnConfigSet) { config.Save(); } } } } internal static class HarmonicConfigMigration { private static readonly ConfigDefinition LegacySpawnWeight = new ConfigDefinition("Spawning", "SpawnWeight"); private static readonly Dictionary RemovedDefaults = new Dictionary { { new ConfigDefinition("Spawning", "LevelMask"), "-1" }, { new ConfigDefinition("Spawning", "SpawnType"), "Default" }, { new ConfigDefinition("Stats", "ModelScale"), "0.72" }, { new ConfigDefinition("Movement", "Acceleration"), "4.5" }, { new ConfigDefinition("Movement", "AngularSpeed"), "70" }, { new ConfigDefinition("Movement", "HoverHeight"), "0.55" }, { new ConfigDefinition("Movement", "RoamSearchWidth"), "120" }, { new ConfigDefinition("Movement", "RoamSearchPrecision"), "8" }, { new ConfigDefinition("Movement", "RoamStuckRecoverySeconds"), "3.5" }, { new ConfigDefinition("Movement", "MovementBobAmount"), "0.06" }, { new ConfigDefinition("Movement", "MovementTiltDegrees"), "4" }, { new ConfigDefinition("Collision", "BodyColliderRadius"), "0.32" }, { new ConfigDefinition("Collision", "BodyColliderHeight"), "1.25" }, { new ConfigDefinition("Alarm", "RefreshSeconds"), "0.35" }, { new ConfigDefinition("Audio", "AlarmVolume"), "1" }, { new ConfigDefinition("Audio", "DeathVolume"), "1" }, { new ConfigDefinition("Death", "HitInflateAmount"), "0.13" }, { new ConfigDefinition("Death", "DeathEffectScale"), "0.75" }, { new ConfigDefinition("Pulse", "IdlePulseRate"), "0.42" }, { new ConfigDefinition("Pulse", "WarningPulseRate"), "1.55" }, { new ConfigDefinition("Pulse", "PitchPulseAmount"), "0.025" }, { new ConfigDefinition("Pulse", "VolumePulseAmount"), "0.08" }, { new ConfigDefinition("Pulse", "WarningPitchMultiplier"), "1.18" }, { new ConfigDefinition("Pulse", "AnimationPulseAmount"), "0" }, { new ConfigDefinition("Pulse", "HornPulseScale"), "0.06" }, { new ConfigDefinition("Light", "BaseIntensity"), "45" }, { new ConfigDefinition("Light", "PulseIntensity"), "35" }, { new ConfigDefinition("Light", "Range"), "8.5" }, { new ConfigDefinition("Light", "EmissionIntensity"), "0.22" } }; 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)("[Harmonic] Could not migrate legacy config: " + ex.GetBaseException().Message + " " + text2)); } return false; } List list = FindCustomizedDroppedKeys(dictionary); if (log != null) { log.LogInfo((object)("[Harmonic] Migrated legacy config to the compact DawnLib layout. Backup: " + text)); } if (list.Count > 0 && log != null) { log.LogWarning((object)("[Harmonic] 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; } 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00a8: Expected O, but got Unknown //IL_00e7: 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_0105: Expected O, but got Unknown //IL_0105: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_013f: Expected O, but got Unknown //IL_016c: 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_018a: Expected O, but got Unknown //IL_018a: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_01d5: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown //IL_0220: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_025a: Expected O, but got Unknown //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Expected O, but got Unknown //IL_02a5: Expected O, but got Unknown //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Expected O, but got Unknown //IL_02df: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Expected O, but got Unknown //IL_0319: Expected O, but got Unknown //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Expected O, but got Unknown //IL_0353: Expected O, but got Unknown //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Expected O, but got Unknown //IL_039e: 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, "18"), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) ? "1" : (result / 18f).ToString("0.###", CultureInfo.InvariantCulture)); } StringBuilder stringBuilder = new StringBuilder(); AppendSection(stringBuilder, "00 - General", ("Enabled", GetValue(values, new ConfigDefinition("00 - General", "Enabled"), new ConfigDefinition("General", "Enabled"), "true"))); AppendSection(stringBuilder, "10 - Spawning", ("SpawnWeightMultiplier", text), ("MaxCount", GetValue(values, new ConfigDefinition("10 - Spawning", "MaxCount"), new ConfigDefinition("Spawning", "MaxCount"), "1")), ("PowerLevel", GetValue(values, new ConfigDefinition("10 - Spawning", "PowerLevel"), new ConfigDefinition("Spawning", "PowerLevel"), "1.1"))); AppendSection(stringBuilder, "20 - Core Stats", ("Health", GetValue(values, new ConfigDefinition("20 - Core Stats", "Health"), new ConfigDefinition("Stats", "Health"), "4"))); AppendSection(stringBuilder, "40 - Movement", ("MoveSpeed", GetValue(values, new ConfigDefinition("40 - Movement", "MoveSpeed"), new ConfigDefinition("Movement", "MoveSpeed"), "1.15"))); AppendSection(stringBuilder, "60 - Abilities", ("AlarmChance", GetValue(values, new ConfigDefinition("60 - Abilities", "AlarmChance"), new ConfigDefinition("Audio", "AlarmChance"), "0.2")), ("AlarmAttractionRadius", GetValue(values, new ConfigDefinition("60 - Abilities", "AlarmAttractionRadius"), new ConfigDefinition("Alarm", "AttractionRadius"), "30"))); AppendSection(stringBuilder, "70 - Audio and Presentation", ("MusicVolume", GetValue(values, new ConfigDefinition("70 - Audio and Presentation", "MusicVolume"), new ConfigDefinition("Audio", "IdleMusicVolume"), "0.95")), ("SfxVolume", GetValue(values, new ConfigDefinition("70 - Audio and Presentation", "SfxVolume"), new ConfigDefinition("Audio", "HitVolume"), "1")), ("MusicMaxDistance", GetValue(values, new ConfigDefinition("70 - Audio and Presentation", "MusicMaxDistance"), new ConfigDefinition("Audio", "MusicMaxDistance"), "65")), ("SfxMaxDistance", GetValue(values, new ConfigDefinition("70 - Audio and Presentation", "SfxMaxDistance"), new ConfigDefinition("Audio", "SfxMaxDistance"), "42"))); AppendSection(stringBuilder, "99 - Diagnostics", ("DebugLogs", GetValue(values, new ConfigDefinition("99 - Diagnostics", "DebugLogs"), new ConfigDefinition("Debug", "DebugLogs"), "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 a Harmonic config backup filename."); } } internal sealed class HarmonicSpawnWeights : IWeighted, IContextualWeighted { internal const int DefaultWeight = 6; internal const int MaximumWeight = 100; private readonly Func _multiplier; internal HarmonicSpawnWeights(Func multiplier) { _multiplier = multiplier ?? throw new ArgumentNullException("multiplier"); } public int GetWeight() { return Scale(6, 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 6; } 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 4; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Assurance) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Vow)) { return 6; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Offense) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.March) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Embrion)) { return 8; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Adamance)) { return 10; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Rend) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Dine)) { return 12; } if (KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Titan) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Artifice) || KeyEquals(((DawnBaseInfo)(object)moon).TypedKey, MoonKeys.Liquidation)) { return 14; } if (((DawnBaseInfo)(object)moon).HasTag(Tags.Paid)) { return 10; } ((DawnBaseInfo)(object)moon).HasTag(Tags.Free); return 6; } 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)) { 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)) { 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.5f; } 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 HarmonicTuning { internal const float ModelScale = 0.72f; internal const float Acceleration = 4.5f; internal const float AngularSpeed = 70f; internal const float HoverHeight = 0.55f; internal const float RoamSearchWidth = 120f; internal const float RoamSearchPrecision = 8f; internal const float RoamStuckRecoverySeconds = 3.5f; internal const float MovementBobAmount = 0.06f; internal const float MovementTiltDegrees = 4f; internal const float BodyColliderRadius = 0.32f; internal const float BodyColliderHeight = 1.25f; internal const float AlarmRefreshSeconds = 0.35f; internal const float HitInflateAmount = 0.13f; internal const float DeathEffectScale = 0.75f; internal const float IdlePulseRate = 0.42f; internal const float WarningPulseRate = 1.55f; internal const float PitchPulseAmount = 0.025f; internal const float VolumePulseAmount = 0.08f; internal const float WarningPitchMultiplier = 1.18f; internal const float AnimationPulseAmount = 0f; internal const float HornPulseScale = 0.06f; internal const float LightBaseIntensity = 45f; internal const float LightPulseIntensity = 35f; internal const float LightRange = 8.5f; internal const float EmissionIntensity = 0.22f; } [BepInPlugin("y4ngz.lethalcompany.harmonic", "Y4NGZ Harmonic", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal const string BundleFilename = "harmonic.bundle"; internal const string PrefabName = "Harmonic"; internal const string DeathEffectName = "DustExplosion"; internal const string AudioFolderName = "Harmonic"; internal const string DawnNamespace = "y4ngz_monsters"; internal const string DawnEnemyKey = "harmonic"; internal const string BestiaryText = "Harmonic\n\nDanger level: ambient\n\nA passive floating organism that wanders facilities while playing warped music. Its alarm call can briefly draw other creatures toward its location.\n\n"; internal static ManualLogSource Log; private static bool _loggedScanNodeLayer; internal static HarmonicConfig ModConfig; internal static AssetBundle ModAssets; internal static EnemyType EnemyType; internal static string AssemblyDirectory; internal static AudioClip[] IdleMusicClips = Array.Empty(); internal static AudioClip AlarmClip; internal static AudioClip DeathClip; internal static AudioClip DeathPopClip; internal static AudioClip[] HitClips = Array.Empty(); internal static GameObject DeathEffectPrefab; private const float MusicMaxAudibleDistance = 65f; private const float SfxMaxAudibleDistance = 42f; private static bool _netcodeInitialized; private static Material _fallbackVisibleMaterial; private static Material _fallbackParticleMaterial; private static Texture2D _runtimeParticleTexture; private static readonly Color RuntimeParticleDustColor = new Color(0.52f, 0.5f, 0.46f, 0.72f); private static readonly Dictionary RuntimeVisualMaterials = new Dictionary(); private static readonly Dictionary RuntimeParticleMaterials = new Dictionary(); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; try { InitializeNetcodeRPCs(); ModConfig = new HarmonicConfig(((BaseUnityPlugin)this).Config); AssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (!ModConfig.Enabled.Value) { Log.LogInfo((object)"Y4NGZ Harmonic is disabled by config."); } else { if (!LoadBundle()) { return; } DeathEffectPrefab = LoadDeathEffectPrefab(); GameObject val = LoadBundlePrefab(); if ((Object)(object)val == (Object)null) { Log.LogError((object)"Prefab 'Harmonic' not found in harmonic.bundle. Refusing to load fallback/legacy visuals."); DumpBundleAssets(); return; } PreparePrefab(val); EnemyType = CreateEnemyType(val); HarmonicAI component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((EnemyAI)component).enemyType = EnemyType; } RegisterWithDawn(val); ((MonoBehaviour)this).StartCoroutine(LoadLooseAudioAsync(val)); Log.LogInfo((object)"Y4NGZ Harmonic v0.1.0 loaded. Registered as 'Harmonic'."); } } catch (Exception arg) { Log.LogError((object)string.Format("[{0}] Initialization failed: {1}", "Y4NGZ Harmonic", arg)); } } private static void RegisterWithDawn(GameObject prefab) { HarmonicSpawnWeights spawnWeights = new HarmonicSpawnWeights(() => ModConfig.SpawnWeightMultiplier.Value); DawnLib.RegisterNetworkPrefab(prefab); DawnLib.DefineEnemy(NamespacedKey.From("y4ngz_monsters", "harmonic"), EnemyType, (Action)delegate(EnemyInfoBuilder builder) { ((BaseInfoBuilder)(object)builder.DefineInside((Action)delegate(EnemyLocationBuilder location) { location.SetWeights((Action>)delegate(WeightTableBuilder table) { table.SetGlobalWeight((IWeighted)(object)spawnWeights); }); }).CreateBestiaryNode("Harmonic\n\nDanger level: ambient\n\nA passive floating organism that wanders facilities while playing warped music. Its alarm call can briefly draw other creatures toward its location.\n\n").CreateNameKeyword("harmonic")).AddTags((IEnumerable)(object)new NamespacedKey[3] { Tags.Passive, Tags.Organic, Tags.Killable }); }); } 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 bool LoadBundle() { if (string.IsNullOrEmpty(AssemblyDirectory)) { Log.LogError((object)"Could not resolve plugin assembly directory."); return false; } string text = Path.Combine(AssemblyDirectory, "harmonic.bundle"); if (!File.Exists(text)) { Log.LogError((object)("Missing asset bundle: " + text)); return false; } ModAssets = AssetBundle.LoadFromFile(text); if ((Object)(object)ModAssets == (Object)null) { Log.LogError((object)("AssetBundle.LoadFromFile returned null for " + text + ".")); return false; } return true; } private static GameObject LoadBundlePrefab() { string[] array = new string[4] { "Harmonic", "Y4NGZHarmonic", "AF_45", "Alien flora 45" }; for (int i = 0; i < array.Length; i++) { GameObject val = ModAssets.LoadAsset(array[i]); if ((Object)(object)val != (Object)null) { return val; } } string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { string text2 = text.Replace('\\', '/'); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text2); if (text2.EndsWith("/harmonic.prefab", StringComparison.OrdinalIgnoreCase) || text2.EndsWith("/y4ngzharmonic.prefab", StringComparison.OrdinalIgnoreCase) || text2.EndsWith("/af_45.prefab", StringComparison.OrdinalIgnoreCase) || string.Equals(fileNameWithoutExtension, "Harmonic", StringComparison.OrdinalIgnoreCase) || string.Equals(fileNameWithoutExtension, "AF_45", StringComparison.OrdinalIgnoreCase)) { GameObject val2 = ModAssets.LoadAsset(text); if ((Object)(object)val2 != (Object)null) { return val2; } } } return null; } private static GameObject LoadDeathEffectPrefab() { string[] array = new string[2] { "DustExplosion", "DustExplosion.prefab" }; for (int i = 0; i < array.Length; i++) { GameObject val = ModAssets.LoadAsset(array[i]); if ((Object)(object)val != (Object)null) { return val; } } string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { string text2 = text.Replace('\\', '/'); if (text2.EndsWith("/dustexplosion.prefab", StringComparison.OrdinalIgnoreCase) || string.Equals(Path.GetFileNameWithoutExtension(text2), "DustExplosion", StringComparison.OrdinalIgnoreCase)) { GameObject val2 = ModAssets.LoadAsset(text); if ((Object)(object)val2 != (Object)null) { return val2; } } } Log.LogWarning((object)"[Harmonic] Death effect 'DustExplosion' not found in harmonic.bundle; death pop will hide the creature without particles."); return null; } private IEnumerator LoadLooseAudioAsync(GameObject prefab) { string audioDir = Path.Combine(AssemblyDirectory ?? string.Empty, "assets", "Harmonic"); if (!Directory.Exists(audioDir)) { Log.LogWarning((object)("[Harmonic] Audio directory not found: " + audioDir)); yield break; } List idle = new List(); string path = Path.Combine(audioDir, "idle music"); if (Directory.Exists(path)) { string[] idleFiles = Directory.GetFiles(path, "*.mp3", SearchOption.TopDirectoryOnly); Array.Sort(idleFiles, (IComparer?)StringComparer.OrdinalIgnoreCase); for (int i = 0; i < idleFiles.Length; i++) { AudioClip loaded = null; yield return LoadAudioClipCoroutine(idleFiles[i], delegate(AudioClip clip) { loaded = clip; }); if ((Object)(object)loaded != (Object)null) { idle.Add(loaded); } } } IdleMusicClips = idle.ToArray(); yield return LoadAudioClipCoroutine(Path.Combine(audioDir, "alarm.mp3"), delegate(AudioClip clip) { AlarmClip = clip; }); yield return LoadAudioClipCoroutine(Path.Combine(audioDir, "death.wav"), delegate(AudioClip clip) { DeathClip = clip; }); yield return LoadAudioClipCoroutine(Path.Combine(audioDir, "pop.mp3"), delegate(AudioClip clip) { DeathPopClip = clip; }); List hits = new List(); string[] hitNames = new string[3] { "hit01.wav", "hit02.wav", "hit03.wav" }; for (int i = 0; i < hitNames.Length; i++) { AudioClip loaded2 = null; yield return LoadAudioClipCoroutine(Path.Combine(audioDir, hitNames[i]), delegate(AudioClip clip) { loaded2 = clip; }); if ((Object)(object)loaded2 != (Object)null) { hits.Add(loaded2); } } HitClips = hits.ToArray(); ApplyAudioToPrefab(prefab); RefreshSpawnedHarmonics(); Log.LogInfo((object)$"[Harmonic] Audio loaded. idle={IdleMusicClips.Length}, alarm={(Object)(object)AlarmClip != (Object)null}, death={(Object)(object)DeathClip != (Object)null}, pop={(Object)(object)DeathPopClip != (Object)null}, hits={HitClips.Length}."); } private IEnumerator LoadAudioClipCoroutine(string path, Action onLoaded) { if (!File.Exists(path)) { Log.LogWarning((object)("[Harmonic] Audio file not found: " + path)); yield break; } AudioType val = ResolveAudioType(path); string text = "file:///" + path.Replace('\\', '/'); UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(text, val); try { yield return request.SendWebRequest(); if ((int)request.result != 1) { Log.LogWarning((object)("[Harmonic] Failed to load audio " + path + ": " + request.error)); yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(request); if ((Object)(object)content != (Object)null) { ((Object)content).name = Path.GetFileNameWithoutExtension(path); } onLoaded?.Invoke(content); } finally { ((IDisposable)request)?.Dispose(); } } private static AudioType ResolveAudioType(string path) { string extension = Path.GetExtension(path); if (!string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase)) { if (!string.Equals(extension, ".wav", StringComparison.OrdinalIgnoreCase)) { return (AudioType)0; } return (AudioType)20; } return (AudioType)13; } private static void ApplyAudioToPrefab(GameObject prefab) { HarmonicAI harmonicAI = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent() : null); if (!((Object)(object)harmonicAI == (Object)null)) { harmonicAI.idleMusicClips = IdleMusicClips; harmonicAI.alarmClip = AlarmClip; harmonicAI.deathClip = DeathClip; harmonicAI.deathPopClip = DeathPopClip; harmonicAI.hitClips = HitClips; harmonicAI.deathEffectPrefab = DeathEffectPrefab; } } private static void RefreshSpawnedHarmonics() { HarmonicAI[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { array[i].RefreshClipsFromPlugin(); } } private static void PreparePrefab(GameObject prefab) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) AssignUniqueNetworkHash(prefab, "Harmonic"); TrySetTag(prefab, "Enemy"); TrySetLayer(prefab, "Enemies"); prefab.transform.localScale = Vector3.one * 0.72f; NetworkObject val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent(); } val.SynchronizeTransform = true; if ((Object)(object)prefab.GetComponent() == (Object)null) { prefab.AddComponent(); } HarmonicAI harmonicAI = prefab.GetComponent(); if ((Object)(object)harmonicAI == (Object)null) { harmonicAI = prefab.AddComponent(); } Animator val2 = prefab.GetComponent() ?? prefab.GetComponentInChildren(true); if ((Object)(object)val2 != (Object)null) { val2.applyRootMotion = false; val2.cullingMode = (AnimatorCullingMode)0; ((EnemyAI)harmonicAI).creatureAnimator = val2; } NavMeshAgent val3 = prefab.GetComponent() ?? prefab.GetComponentInChildren(true); if ((Object)(object)val3 == (Object)null) { val3 = prefab.AddComponent(); } ((EnemyAI)harmonicAI).agent = val3; ConfigureAgent(val3); harmonicAI.visualRoot = FindBestVisualRoot(prefab.transform); ((EnemyAI)harmonicAI).eye = FindOrCreateChild(prefab.transform, "EyeTransform", new Vector3(0f, 0.35f, 0.2f)); harmonicAI.musicSource = FindOrCreateAudioSource(prefab.transform, "HarmonicMusic", ModConfig.MusicMaxDistance.Value); harmonicAI.sfxSource = FindOrCreateAudioSource(prefab.transform, "HarmonicSFX", ModConfig.SfxMaxDistance.Value); harmonicAI.glowLight = FindOrCreateLight(prefab.transform); harmonicAI.deathEffectPrefab = DeathEffectPrefab; EnsureScanNode(prefab); EnsureCollision(prefab, harmonicAI); EnsureBehaviourStates(harmonicAI); RepairRuntimePresentation(prefab, "prefab", logDiagnostics: true); } internal static void ConfigureAgent(NavMeshAgent agent) { if (!((Object)(object)agent == (Object)null)) { agent.speed = Mathf.Max(0.1f, ModConfig.MoveSpeed.Value); agent.acceleration = 4.5f; agent.angularSpeed = 70f; agent.stoppingDistance = 0.55f; agent.radius = 0.32f; agent.height = 1.25f; agent.baseOffset = 0f; agent.autoBraking = true; agent.autoRepath = true; agent.obstacleAvoidanceType = (ObstacleAvoidanceType)4; agent.avoidancePriority = 55; } } private static void EnsureBehaviourStates(HarmonicAI ai) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_005f: Expected O, but got Unknown //IL_0061: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown ((EnemyAI)ai).enemyBehaviourStates = (EnemyBehaviourState[])(object)new EnemyBehaviourState[3] { new EnemyBehaviourState { name = "Roaming", IsAnimTrigger = false, parameterString = "Moving", boolValue = true }, new EnemyBehaviourState { name = "Alarm", IsAnimTrigger = false, parameterString = "Moving", boolValue = true }, new EnemyBehaviourState { name = "Dead", IsAnimTrigger = true, parameterString = "Death" } }; ((EnemyAI)ai).currentBehaviourStateIndex = 0; ((EnemyAI)ai).previousBehaviourStateIndex = 0; ((EnemyAI)ai).currentBehaviourState = ((EnemyAI)ai).enemyBehaviourStates[0]; } internal static int RepairRuntimePresentation(GameObject root, string context, bool logDiagnostics) { if ((Object)(object)root == (Object)null) { return 0; } TrySetTag(root, "Enemy"); TrySetLayer(root, "Enemies"); int num = PrepareRenderers(root); EnsureScanNode(root); EnsureCollision(root, root.GetComponent()); Animator val = root.GetComponent() ?? root.GetComponentInChildren(true); if ((Object)(object)val != (Object)null) { val.cullingMode = (AnimatorCullingMode)0; } if (logDiagnostics) { LogPresentationDiagnostics(root, context, num); } return num; } internal static void EnsureScanNode(GameObject prefab) { //IL_00b7: 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) //IL_01ae: 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) { if ((Object)(object)val == (Object)null || (val2.creatureScanID >= 0 && val.creatureScanID < 0) || (val2.creatureScanID == val.creatureScanID && ((Object)((Component)val2).gameObject).name == "ScanNode" && ((Object)((Component)val).gameObject).name != "ScanNode")) { val = val2; } } if (componentsInChildren.Length > 1) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[Harmonic] Found {componentsInChildren.Length} scan nodes; repairing the preferred existing node without creating another."); } } Transform val3 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : FindOrCreateChild(prefab.transform, "ScanNode", ResolveScanNodeLocalPosition(prefab))); TrySetTag(((Component)val3).gameObject, "DoNotSet"); TrySetLayer(((Component)val3).gameObject, "ScanNode"); EnsureHierarchyActive(val3, prefab.transform); ((Component)val3).gameObject.SetActive(true); if (!_loggedScanNodeLayer) { _loggedScanNodeLayer = true; ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)($"[Harmonic] 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 obj = ((Component)val3).GetComponent() ?? ((Component)val3).gameObject.AddComponent(); ((Collider)obj).enabled = true; ((Collider)obj).isTrigger = true; obj.center = Vector3.zero; obj.size = new Vector3(2.4f, 2.4f, 2.4f); Rigidbody obj2 = ((Component)val3).GetComponent() ?? ((Component)val3).gameObject.AddComponent(); obj2.isKinematic = true; obj2.useGravity = false; obj2.detectCollisions = true; val = val ?? ((Component)val3).gameObject.AddComponent(); val.headerText = "Harmonic"; val.subText = "Creature"; val.maxRange = 18; val.minRange = 1; val.requiresLineOfSight = true; val.nodeType = 1; } private static Vector3 ResolveScanNodeLocalPosition(GameObject prefab) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_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_0051: 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) if ((Object)(object)prefab != (Object)null && TryGetRendererBounds(prefab, out var bounds)) { Vector3 val = ((Bounds)(ref bounds)).center + Vector3.up * Mathf.Clamp(((Bounds)(ref bounds)).extents.y * 0.2f, 0.25f, 0.85f); return prefab.transform.InverseTransformPoint(val); } return new Vector3(0f, 1.15f, 0f); } internal static void EnsureCollision(GameObject prefab, HarmonicAI ai) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) ResolveCollisionShape(prefab, out var center, out var radius, out var height); CapsuleCollider obj = prefab.GetComponent() ?? prefab.AddComponent(); ((Collider)obj).enabled = true; ((Collider)obj).isTrigger = false; obj.direction = 1; obj.center = center; obj.radius = radius; obj.height = height; Rigidbody obj2 = prefab.GetComponent() ?? prefab.AddComponent(); obj2.isKinematic = true; obj2.useGravity = false; obj2.detectCollisions = true; Transform val = FindOrCreateChild(prefab.transform, "Collision", Vector3.zero); ((Component)val).gameObject.SetActive(true); TrySetTag(((Component)val).gameObject, "Enemy"); TrySetLayer(((Component)val).gameObject, "Enemies"); CapsuleCollider obj3 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); ((Collider)obj3).enabled = true; ((Collider)obj3).isTrigger = true; obj3.direction = 1; obj3.center = center; obj3.radius = radius * 1.15f; obj3.height = height * 1.12f; Rigidbody obj4 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); obj4.isKinematic = true; obj4.useGravity = false; obj4.detectCollisions = true; if ((Object)(object)ai != (Object)null) { EnemyAICollisionDetect obj5 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); obj5.mainScript = (EnemyAI)(object)ai; obj5.alwaysAllowHitting = true; obj5.canCollideWithEnemies = true; obj5.onlyCollideWhenGrounded = false; } DisableRenderers(val); } private static void ResolveCollisionShape(GameObject root, out Vector3 center, out float radius, out float height) { //IL_002b: 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_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_0055: 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) //IL_0095: 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) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) radius = 0.32f; height = 1.25f; center = new Vector3(0f, Mathf.Max(0.45f, height * 0.5f), 0f); if (TryGetRendererBounds(root, out var bounds)) { Vector3 val = root.transform.InverseTransformPoint(((Bounds)(ref bounds)).center); float num = Mathf.Max(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z); radius = Mathf.Clamp(Mathf.Max(radius, num * 0.22f), 0.1f, 0.75f); height = Mathf.Clamp(Mathf.Max(height, ((Bounds)(ref bounds)).size.y * 0.55f), 0.65f, 2.4f); center = new Vector3(0f, Mathf.Clamp(val.y, height * 0.45f, height * 1.1f), 0f); } } private static int PrepareRenderers(GameObject prefab) { //IL_009d: 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_00ac: 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) Renderer[] componentsInChildren = prefab.GetComponentsInChildren(true); int num = 0; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsHelperRenderer(val)) { EnsureHierarchyActive(((Component)val).transform, prefab.transform); ((Component)val).gameObject.layer = 0; val.enabled = true; val.forceRenderingOff = false; val.allowOcclusionWhenDynamic = false; val.shadowCastingMode = (ShadowCastingMode)1; val.receiveShadows = true; EnsureVisibleMaterials(val); SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); if ((Object)(object)val2 != (Object)null) { val2.updateWhenOffscreen = true; ((Renderer)val2).localBounds = new Bounds(new Vector3(0f, 1f, 0f), Vector3.one * 12f); } num++; } } return num; } private static EnemyType CreateEnemyType(GameObject prefab) { EnemyType obj = ScriptableObject.CreateInstance(); obj.enemyName = "Harmonic"; obj.enemyPrefab = prefab; obj.PowerLevel = ModConfig.PowerLevel.Value; obj.DiversityPowerLevel = 1; obj.MaxCount = Mathf.Max(1, ModConfig.MaxCount.Value); obj.canDie = true; obj.canBeStunned = true; obj.canBeDestroyed = true; obj.stunTimeMultiplier = 1f; obj.stunGameDifficultyMultiplier = 1f; obj.destroyOnDeath = false; obj.doorSpeedMultiplier = 1f; obj.isOutsideEnemy = false; obj.isDaytimeEnemy = false; obj.pushPlayerDistance = 0f; obj.pushPlayerForce = 0f; obj.normalizedTimeInDayToLeave = 1f; obj.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f); obj.numberSpawnedFalloff = AnimationCurve.Linear(0f, 1f, 1f, 0f); obj.useNumberSpawnedFalloff = true; obj.disableAnimatorWhenFar = false; return obj; } private static AudioSource FindOrCreateAudioSource(Transform parent, string childName, float maxDistance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Transform val = FindOrCreateChild(parent, childName, Vector3.zero); AudioSource val2 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); val2.playOnAwake = false; val2.loop = false; val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)0; val2.minDistance = 4f; float num = (string.Equals(childName, "HarmonicMusic", StringComparison.OrdinalIgnoreCase) ? 65f : 42f); val2.maxDistance = Mathf.Clamp(maxDistance, 8f, num); val2.dopplerLevel = 0f; val2.spread = 55f; if ((Object)(object)((Component)val2).GetComponent() == (Object)null) { ((Component)val2).gameObject.AddComponent(); } return val2; } private static Light FindOrCreateLight(Transform parent) { //IL_0015: 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) Transform val = FindOrCreateChild(parent, "HarmonicLight", new Vector3(0f, 1.1f, 0f)); Light obj = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); obj.type = (LightType)2; obj.color = new Color(0.34f, 0.24f, 1f, 1f); obj.intensity = 45f; obj.range = 8.5f; obj.shadows = (LightShadows)0; obj.renderMode = (LightRenderMode)1; return obj; } private static Transform FindBestVisualRoot(Transform root) { Transform val = FindChildRecursive(root, "VisualRoot") ?? FindChildRecursive(root, "Armature") ?? FindChildRecursive(root, "HarmonicModel_AF_45") ?? FindChildRecursive(root, "AF_45"); if ((Object)(object)val != (Object)null) { return val; } Renderer componentInChildren = ((Component)root).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return root; } Transform val2 = ((Component)componentInChildren).transform; while ((Object)(object)val2.parent != (Object)null && (Object)(object)val2.parent != (Object)(object)root) { val2 = val2.parent; } return val2; } internal static Transform FindOrCreateChild(Transform parent, string name, Vector3 localPosition) { //IL_003d: 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_0058: 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_001e: 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_0030: Unknown result type (might be due to invalid IL or missing references) Transform val = parent.Find(name); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(true); val.localPosition = localPosition; val.localRotation = Quaternion.identity; val.localScale = Vector3.one; return val; } val = new GameObject(name).transform; val.SetParent(parent, false); val.localPosition = localPosition; val.localRotation = Quaternion.identity; val.localScale = Vector3.one; return val; } internal static Transform FindChildRecursive(Transform parent, string name) { if ((Object)(object)parent == (Object)null || string.IsNullOrWhiteSpace(name)) { return null; } if (string.Equals(((Object)parent).name, name, StringComparison.OrdinalIgnoreCase)) { return parent; } for (int i = 0; i < parent.childCount; i++) { Transform val = FindChildRecursive(parent.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static void DisableRenderers(Transform root) { Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } private static bool TryGetRendererBounds(GameObject root, out Bounds bounds) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Renderer[] array = (((Object)(object)root != (Object)null) ? root.GetComponentsInChildren(true) : Array.Empty()); bounds = new Bounds(((Object)(object)root != (Object)null) ? root.transform.position : Vector3.zero, Vector3.zero); bool flag = false; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return flag; } private static void EnsureVisibleMaterials(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return; } Material[] array = renderer.sharedMaterials; if (array == null || array.Length == 0) { array = (Material[])(object)new Material[1] { GetOrCreateRuntimeVisibleMaterial(null) }; } bool flag = false; for (int i = 0; i < array.Length; i++) { Material val = array[i]; if (ShouldUseRuntimeMaterial(val)) { array[i] = GetOrCreateRuntimeVisibleMaterial(val); flag = true; } else { flag |= ForceOpaqueMaterial(val); } } if (flag) { renderer.sharedMaterials = array; } } private static bool ShouldUseRuntimeMaterial(Material material) { if ((Object)(object)material == (Object)null) { return true; } if (((Object)material).name.StartsWith("HarmonicRuntimeVisible", StringComparison.OrdinalIgnoreCase)) { return false; } ((Object)material).name.StartsWith("HarmonicVisible", StringComparison.OrdinalIgnoreCase); return ShouldReplaceShader(material.shader); } private static Material GetOrCreateRuntimeVisibleMaterial(Material source) { Texture baseTexture = GetBaseTexture(source); if ((Object)(object)baseTexture != (Object)null && RuntimeVisualMaterials.TryGetValue(baseTexture, out var value) && (Object)(object)value != (Object)null) { return value; } Material val = CreateRuntimeVisibleMaterial(source, baseTexture); if ((Object)(object)baseTexture != (Object)null) { RuntimeVisualMaterials[baseTexture] = val; } else { _fallbackVisibleMaterial = val; } return val; } private static Material CreateRuntimeVisibleMaterial(Material source, Texture texture) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0064: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_007c: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00e7: Expected O, but got Unknown if ((Object)(object)texture == (Object)null && (Object)(object)_fallbackVisibleMaterial != (Object)null) { return _fallbackVisibleMaterial; } Shader val = FindVisibleShader(); Material val2 = (((Object)(object)val != (Object)null) ? new Material(val) : new Material(Shader.Find("Unlit/Color"))); ((Object)val2).name = (((Object)(object)texture != (Object)null) ? "HarmonicRuntimeVisible_Textured" : "HarmonicRuntimeVisible_Fallback"); ApplyBaseTexture(val2, texture); ApplyNormalTexture(val2, GetNormalTexture(source)); ApplyOcclusionTexture(val2, GetOcclusionTexture(source)); ApplyBaseColor(val2, (Color)(((Object)(object)source != (Object)null) ? GetBaseColor(source) : new Color(0.74f, 0.56f, 0.28f, 1f))); SetFloatIfPresent(val2, "_Metallic", 0f); SetFloatIfPresent(val2, "_Smoothness", 0.35f); SetFloatIfPresent(val2, "_Glossiness", 0.35f); ForceOpaqueMaterial(val2); return val2; } internal static void RepairParticleRenderers(GameObject root) { if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } bool flag = false; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if (!((Object)(object)val2 != (Object)null) || ShouldReplaceShader(val2.shader) || !((Object)(object)GetBaseTexture(val2) != (Object)null)) { sharedMaterials[j] = GetOrCreateRuntimeParticleMaterial(val2); flag = true; } } if (flag) { val.sharedMaterials = sharedMaterials; } } } private static Material GetOrCreateRuntimeParticleMaterial(Material source) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source != (Object)null && RuntimeParticleMaterials.TryGetValue(source, out var value) && (Object)(object)value != (Object)null) { return value; } if ((Object)(object)source == (Object)null && (Object)(object)_fallbackParticleMaterial != (Object)null) { return _fallbackParticleMaterial; } Shader val = FindRuntimeParticleShader(); if ((Object)(object)val == (Object)null) { return source; } Material val2 = new Material(val); ((Object)val2).name = "HarmonicRuntimeParticle"; ((Object)val2).hideFlags = (HideFlags)61; Texture texture = (Texture)(((object)GetBaseTexture(source)) ?? ((object)GetOrCreateRuntimeParticleTexture())); ApplyBaseTexture(val2, texture); ApplyParticleColor(val2, RuntimeParticleDustColor); MakeTransparentUnlit(val2); if ((Object)(object)source != (Object)null) { RuntimeParticleMaterials[source] = val2; } else { _fallbackParticleMaterial = val2; } return val2; } private static Shader FindRuntimeParticleShader() { string[] array = new string[3] { "Particles/Standard Unlit", "Legacy Shaders/Particles/Alpha Blended", "Sprites/Default" }; for (int i = 0; i < array.Length; i++) { Shader val = Shader.Find(array[i]); if ((Object)(object)val != (Object)null && val.isSupported) { return val; } } Shader val2 = Shader.Find("HDRP/Unlit"); if ((Object)(object)val2 != (Object)null && val2.isSupported) { return val2; } return Shader.Find("Unlit/Transparent") ?? FindVisibleShader(); } private static Texture2D GetOrCreateRuntimeParticleTexture() { //IL_0019: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0176: 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) if ((Object)(object)_runtimeParticleTexture != (Object)null) { return _runtimeParticleTexture; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, true) { name = "HarmonicRuntimeDustSprite", hideFlags = (HideFlags)61, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { float num = ((float)i + 0.5f) / 64f * 2f - 1f; for (int j = 0; j < 64; j++) { float num2 = ((float)j + 0.5f) / 64f * 2f - 1f; float num3 = Mathf.Atan2(num, num2); float num4 = Mathf.Sqrt(num2 * num2 + num * num); float num5 = 0.94f + Mathf.Sin(num3 * 3f + 0.45f) * 0.045f + Mathf.Sin(num3 * 7f - 0.8f) * 0.025f; float num6 = Mathf.InverseLerp(0.08f, num5, num4); float num7 = Mathf.SmoothStep(1f, 0f, num6); float num8 = 0.88f + 0.08f * Mathf.Sin(num2 * 8.3f + num * 3.7f) + 0.04f * Mathf.Sin(num * 11.1f - num2 * 2.9f); byte b = (byte)Mathf.RoundToInt(Mathf.Clamp01(num7 * num8) * 255f); array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array); val.Apply(true, true); _runtimeParticleTexture = val; return val; } private static void ApplyParticleColor(Material material, Color color) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null) { return; } string[] array = new string[4] { "_BaseColor", "_Color", "_TintColor", "_UnlitColor" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { material.SetColor(array[i], color); } } } private static void MakeTransparentUnlit(Material material) { SetFloatIfPresent(material, "_SurfaceType", 1f); SetFloatIfPresent(material, "_BlendMode", 0f); SetFloatIfPresent(material, "_AlphaCutoffEnable", 0f); SetFloatIfPresent(material, "_SrcBlend", 5f); SetFloatIfPresent(material, "_DstBlend", 10f); SetFloatIfPresent(material, "_AlphaSrcBlend", 5f); SetFloatIfPresent(material, "_AlphaDstBlend", 10f); SetFloatIfPresent(material, "_ZWrite", 0f); SetFloatIfPresent(material, "_TransparentZWrite", 0f); SetFloatIfPresent(material, "_ZTestDepthEqualForOpaque", 4f); SetFloatIfPresent(material, "_CullMode", 0f); SetFloatIfPresent(material, "_TransparentCullMode", 0f); material.SetOverrideTag("RenderType", "Transparent"); material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); material.EnableKeyword("_BLENDMODE_ALPHA"); material.EnableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ENABLE_FOG_ON_TRANSPARENT"); material.DisableKeyword("_BLENDMODE_ADD"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; if ((Object)(object)material.shader != (Object)null && ((Object)material.shader).name.StartsWith("HDRP/", StringComparison.OrdinalIgnoreCase)) { HDMaterial.ValidateMaterial(material); } } private static bool ShouldReplaceShader(Shader shader) { if (IsInvalidShader(shader)) { return true; } if (!shader.isSupported) { return true; } string text = ((Object)shader).name ?? string.Empty; if (!string.Equals(text, "Standard", StringComparison.OrdinalIgnoreCase)) { return text.IndexOf("Universal Render Pipeline", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool IsInvalidShader(Shader shader) { if ((Object)(object)shader == (Object)null) { return true; } return (((Object)shader).name ?? string.Empty).IndexOf("Hidden/InternalErrorShader", StringComparison.OrdinalIgnoreCase) >= 0; } private static Shader FindVisibleShader() { return Shader.Find("HDRP/Lit") ?? Shader.Find("HDRP/Unlit") ?? Shader.Find("Standard") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Unlit/Texture"); } private static Texture GetBaseTexture(Material material) { if ((Object)(object)material == (Object)null) { return null; } string[] array = new string[4] { "_BaseColorMap", "_UnlitColorMap", "_MainTex", "_BaseMap" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { Texture texture = material.GetTexture(array[i]); if (IsLikelyAlbedo(texture)) { return texture; } } } for (int j = 0; j < array.Length; j++) { if (material.HasProperty(array[j])) { Texture texture2 = material.GetTexture(array[j]); if ((Object)(object)texture2 != (Object)null && !IsLikelyUtilityMap(texture2)) { return texture2; } } } Texture val = FindTextureByName(material, "color", "albedo", "diffuse", "base"); if ((Object)(object)val != (Object)null) { return val; } return null; } private static void ApplyBaseTexture(Material material, Texture texture) { if ((Object)(object)material == (Object)null || (Object)(object)texture == (Object)null) { return; } string[] array = new string[4] { "_BaseColorMap", "_UnlitColorMap", "_MainTex", "_BaseMap" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { material.SetTexture(array[i], texture); } } } private static Texture GetNormalTexture(Material material) { if ((Object)(object)material == (Object)null) { return null; } string[] array = new string[2] { "_NormalMap", "_BumpMap" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { Texture texture = material.GetTexture(array[i]); if ((Object)(object)texture != (Object)null) { return texture; } } } return FindTextureByName(material, "normal", "bump"); } private static void ApplyNormalTexture(Material material, Texture texture) { if ((Object)(object)material == (Object)null || (Object)(object)texture == (Object)null) { return; } string[] array = new string[2] { "_NormalMap", "_BumpMap" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { material.SetTexture(array[i], texture); } } material.EnableKeyword("_NORMALMAP"); } private static Texture GetOcclusionTexture(Material material) { if ((Object)(object)material == (Object)null) { return null; } string[] array = new string[1] { "_OcclusionMap" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { Texture texture = material.GetTexture(array[i]); if ((Object)(object)texture != (Object)null) { return texture; } } } return FindTextureByName(material, "occlusion", "_ao", "ao"); } private static void ApplyOcclusionTexture(Material material, Texture texture) { if (!((Object)(object)material == (Object)null) && !((Object)(object)texture == (Object)null) && material.HasProperty("_OcclusionMap")) { material.SetTexture("_OcclusionMap", texture); } } private static Texture FindTextureByName(Material material, params string[] needles) { if ((Object)(object)material == (Object)null || needles == null || needles.Length == 0) { return null; } string[] array; try { array = material.GetTexturePropertyNames(); } catch { array = Array.Empty(); } for (int i = 0; i < array.Length; i++) { if (!material.HasProperty(array[i])) { continue; } Texture texture = material.GetTexture(array[i]); if ((Object)(object)texture == (Object)null || string.IsNullOrEmpty(((Object)texture).name)) { continue; } string name = ((Object)texture).name; for (int j = 0; j < needles.Length; j++) { if (name.IndexOf(needles[j], StringComparison.OrdinalIgnoreCase) >= 0) { return texture; } } } return null; } private static bool IsLikelyAlbedo(Texture texture) { if ((Object)(object)texture == (Object)null || string.IsNullOrEmpty(((Object)texture).name)) { return (Object)(object)texture != (Object)null; } string name = ((Object)texture).name; if (name.IndexOf("color", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("albedo", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("diffuse", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("base", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool IsLikelyUtilityMap(Texture texture) { if ((Object)(object)texture == (Object)null || string.IsNullOrEmpty(((Object)texture).name)) { return false; } string name = ((Object)texture).name; if (name.IndexOf("normal", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("bump", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("metal", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("rough", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("occlusion", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("_ao", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static Color GetBaseColor(Material material) { //IL_0009: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null) { return Color.white; } string[] array = new string[4] { "_BaseColor", "_Color", "_TintColor", "_UnlitColor" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { Color color = material.GetColor(array[i]); color.a = 1f; return color; } } return Color.white; } private static void ApplyBaseColor(Material material, Color color) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null) { return; } color.a = 1f; string[] array = new string[4] { "_BaseColor", "_Color", "_TintColor", "_UnlitColor" }; for (int i = 0; i < array.Length; i++) { if (material.HasProperty(array[i])) { material.SetColor(array[i], color); } } } private static bool ForceOpaqueMaterial(Material material) { int result = (int)(0u | (SetAlphaIfPresent(material, "_Color") ? 1u : 0u) | (SetAlphaIfPresent(material, "_BaseColor") ? 1u : 0u) | (SetAlphaIfPresent(material, "_TintColor") ? 1u : 0u) | (SetAlphaIfPresent(material, "_UnlitColor") ? 1u : 0u) | (SetFloatIfPresent(material, "_Mode", 0f) ? 1u : 0u) | (SetFloatIfPresent(material, "_SurfaceType", 0f) ? 1u : 0u) | (SetFloatIfPresent(material, "_SrcBlend", 1f) ? 1u : 0u) | (SetFloatIfPresent(material, "_DstBlend", 0f) ? 1u : 0u) | (SetFloatIfPresent(material, "_ZWrite", 1f) ? 1u : 0u)) | (SetFloatIfPresent(material, "_AlphaCutoffEnable", 0f) ? 1 : 0); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); material.renderQueue = -1; return (byte)result != 0; } private static bool SetAlphaIfPresent(Material material, string property) { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null || !material.HasProperty(property)) { return false; } Color color = material.GetColor(property); if (color.a >= 0.99f) { return false; } color.a = 1f; material.SetColor(property, color); return true; } private static bool SetFloatIfPresent(Material material, string property, float value) { if ((Object)(object)material == (Object)null || !material.HasProperty(property)) { return false; } if (Mathf.Approximately(material.GetFloat(property), value)) { return false; } material.SetFloat(property, value); return true; } private static void AssignUniqueNetworkHash(GameObject prefab, string key) { try { NetworkObject val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent(); } uint num = BitConverter.ToUInt32(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("y4ngz.lethalcompany.harmonic." + key)), 0); PropertyInfo property = typeof(NetworkObject).GetProperty("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(val, num); return; } FieldInfo fieldInfo = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(NetworkObject).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo != null) { fieldInfo.SetValue(val, num); } } catch (Exception ex) { Log.LogWarning((object)("[Harmonic] Could not assign NetworkObject hash: " + ex.Message)); } } private static void TrySetTag(GameObject obj, string tag) { try { obj.tag = tag; } catch { } } internal static void TrySetLayer(GameObject obj, string layerName) { if ((Object)(object)obj == (Object)null) { return; } int num = LayerMask.NameToLayer(layerName); if (num < 0) { num = ResolveLayerFallback(layerName); } if (num >= 0 && num <= 31) { obj.layer = num; return; } ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[Harmonic] Layer '{layerName}' unresolved; '{((Object)obj).name}' stays on layer {obj.layer}."); } } 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 root) { Transform val = child; while ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(true); if (!((Object)(object)val == (Object)(object)root)) { val = val.parent; continue; } break; } } private static bool IsHelperRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return true; } if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return true; } Transform val = ((Component)renderer).transform; while ((Object)(object)val != (Object)null) { if (string.Equals(((Object)val).name, "Collision", StringComparison.OrdinalIgnoreCase)) { return true; } val = val.parent; } return false; } private static void LogPresentationDiagnostics(GameObject root, string context, int repairedRenderers) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null || Log == null) { return; } Renderer val = null; Renderer[] componentsInChildren = root.GetComponentsInChildren(true); int num = 0; int num2 = 0; int num3 = 0; foreach (Renderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !IsHelperRenderer(val2)) { num++; if (val2 is SkinnedMeshRenderer) { num2++; } else if (val2 is MeshRenderer) { num3++; } if ((Object)(object)val == (Object)null) { val = val2; } } } Transform val3 = root.transform.Find("ScanNode"); string text = (((Object)(object)val3 != (Object)null) ? $"scanLayer={((Component)val3).gameObject.layer}, scanActive={((Component)val3).gameObject.activeInHierarchy}, scanPos={val3.localPosition}" : "scan=missing"); string text2 = "material="; if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMaterial != (Object)null) { Material sharedMaterial = val.sharedMaterial; Texture baseTexture = GetBaseTexture(sharedMaterial); text2 = string.Format("material={0}/{1}, supported={2}, tex={3}", ((Object)sharedMaterial).name, ((Object)(object)sharedMaterial.shader != (Object)null) ? ((Object)sharedMaterial.shader).name : "", (Object)(object)sharedMaterial.shader != (Object)null && sharedMaterial.shader.isSupported, ((Object)(object)baseTexture != (Object)null) ? ((Object)baseTexture).name : ""); } CapsuleCollider component = root.GetComponent(); Transform val4 = root.transform.Find("Collision"); CapsuleCollider val5 = (((Object)(object)val4 != (Object)null) ? ((Component)val4).GetComponent() : null); string text3 = (((Object)(object)component != (Object)null && (Object)(object)val5 != (Object)null) ? $"bodyCollider(center={component.center}, h={component.height:0.00}, r={component.radius:0.00}), hitbox(center={val5.center}, h={val5.height:0.00}, r={val5.radius:0.00})" : "collision=missing"); object obj; if (!((Object)(object)val != (Object)null)) { obj = "firstRenderer="; } else { object[] obj2 = new object[5] { GetHierarchyPath(root.transform, ((Component)val).transform), ((Component)val).gameObject.activeInHierarchy, val.enabled, ((Component)val).gameObject.layer, null }; Bounds bounds = val.bounds; obj2[4] = ((Bounds)(ref bounds)).size; obj = string.Format("firstRenderer='{0}', active={1}, enabled={2}, layer={3}, bounds={4}", obj2); } string text4 = (string)obj; Log.LogInfo((object)$"[Harmonic] Presentation repair ({context}): repaired={repairedRenderers}, renderers={num}, skinned={num2}, mesh={num3}, {text}, {text3}, {text4}, {text2}."); } private static string GetHierarchyPath(Transform root, Transform child) { if ((Object)(object)child == (Object)null) { return ""; } List list = new List(); Transform val = child; while ((Object)(object)val != (Object)null) { list.Add(((Object)val).name); if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } list.Reverse(); return string.Join("/", list); } private static void DumpBundleAssets() { if (!((Object)(object)ModAssets == (Object)null)) { string[] allAssetNames = ModAssets.GetAllAssetNames(); foreach (string text in allAssetNames) { Log.LogError((object)(" - " + text)); } } } } internal static class PluginInfo { public const string PLUGIN_GUID = "y4ngz.lethalcompany.harmonic"; public const string PLUGIN_NAME = "Y4NGZ Harmonic"; public const string PLUGIN_VERSION = "0.1.0"; } } namespace Y4NGZHarmonic.AI { public sealed class HarmonicAI : EnemyAI { private sealed class HornPulseTarget { public readonly Transform Transform; public readonly Vector3 BaseScale; public HornPulseTarget(Transform transform) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Transform = transform; BaseScale = (((Object)(object)transform != (Object)null) ? transform.localScale : Vector3.one); } } private struct AlarmedEnemyState { public PlayerControllerB TargetPlayer; public int BehaviourStateIndex; } public const int StateRoaming = 0; public const int StateAlarm = 1; public const int StateDead = 2; private const int LocalTrackNone = 0; private const int LocalTrackIdle = 1; private const int LocalTrackAlarm = 2; private const float MusicOutputMultiplier = 1f; private const float AlarmOutputMultiplier = 1f; private const float SfxOutputMultiplier = 1f; private const float MusicMaxAudibleDistance = 65f; private const float SfxMaxAudibleDistance = 42f; private const float ClearAudioCutoff = 22000f; private const float DistantAudioCutoff = 6500f; private const float ObstructedAudioCutoff = 2400f; private const float DamageStunFreezeSeconds = 1f; private const float AlarmArrivalReleaseRadius = 4f; private const float AlarmArrivalReleaseImmunitySeconds = 1f; private static readonly int MovingHash = Animator.StringToHash("Moving"); private static readonly string[] IdleAnimationStates = new string[4] { "Idle_1", "Idle_2", "Idle_3", "Idle_4" }; private static readonly string[] HornPulseBoneNames = new string[6] { "JNT_Trumpet_a4", "JNT_Trumpet_b4", "JNT_Trumpet_c4", "JNT_Trumpet_d4", "JNT_Trumpet_e4", "JNT_Trumpet_f4" }; public AISearchRoutine facilitySearch = new AISearchRoutine(); public Transform visualRoot; public AudioSource musicSource; public AudioSource sfxSource; public Light glowLight; public AudioClip[] idleMusicClips; public AudioClip alarmClip; public AudioClip deathClip; public AudioClip deathPopClip; public AudioClip[] hitClips; public GameObject deathEffectPrefab; private readonly Dictionary _alarmedEnemies = new Dictionary(); private readonly Dictionary _alarmReleaseImmunityUntil = new Dictionary(); private readonly List _runtimeMaterials = new List(); private readonly List _hornPulseTargets = new List(); private readonly RaycastHit[] _audioOcclusionHits = (RaycastHit[])(object)new RaycastHit[8]; private Coroutine _serverMusicRoutine; private Coroutine _localPlaybackRoutine; private Vector3 _visualBaseLocalPosition; private Vector3 _visualBaseLocalScale = Vector3.one; private Vector3 _lastMovementCheckPosition; private Quaternion _visualBaseLocalRotation = Quaternion.identity; private float _visualLocalMinY; private float _visualLocalMaxY; private float _visualHoverVelocity; private float _hornPulseAmount; private float _hornPulseVelocity; private float _desiredHornPulseAmount; private float _targetHitInflateAmount; private float _hitInflateAmount; private float _hitInflateVelocity; private float _pulsePhase; private float _localClipStartedAt; private float _localClipDuration; private float _deathFadeStartedAt = -1f; private float _stuckTimer; private float _nextSearchRepairTime; private float _nextAlarmRefreshTime; private float _nextAudioOcclusionUpdateTime; private float _nextNavMeshRepairTime; private float _nextPresentationRepairTime; private float _damageStunUntil; private float _preDamageStunAnimatorSpeed = 1f; private int _lastIdleIndex = -1; private int _localPlaybackToken; private int _localTrackKind; private string _currentAnimationState; private AudioLowPassFilter _musicLowPass; private AudioLowPassFilter _sfxLowPass; private Coroutine _deathPresentationRoutine; private bool _hasCapturedVisualBase; private bool _hasVisualBounds; private bool _hornPulseTargetsScanned; private bool _hasMovingParameter; private bool _localWarningRamp; private bool _serverAlarmActive; private bool _deathSent; private bool _deathBodyHidden; private bool _presentationLogged; private bool _damageStunFrozen; private int Health => Plugin.ModConfig?.Health.Value ?? 4; private float AlarmChance => Mathf.Clamp01(Plugin.ModConfig?.AlarmChance.Value ?? 0.2f); private float AlarmRefreshSeconds => 0.35f; private float AlarmAttractionRadius => Mathf.Max(0f, Plugin.ModConfig?.AlarmAttractionRadius.Value ?? 30f); private float IdleVolume => Mathf.Clamp01(Plugin.ModConfig?.MusicVolume.Value ?? 0.95f); private float AlarmVolume => Mathf.Clamp01(Plugin.ModConfig?.SfxVolume.Value ?? 1f); private float HitVolume => Mathf.Clamp01(Plugin.ModConfig?.SfxVolume.Value ?? 1f); private float DeathVolume => Mathf.Clamp01(Plugin.ModConfig?.SfxVolume.Value ?? 1f); private float PulseRate => 0.42f; private float WarningPulseRate => 1.55f; private float PitchPulseAmount => 0.025f; private float VolumePulseAmount => 0.08f; private float WarningPitchMultiplier => 1.18f; private float AnimationPulseAmount => 0f; private float HoverHeight => 0.55f; private float MaxHitInflateAmount => 0.13f; private float DeathEffectScale => 0.75f; private float RoamSearchWidth => 120f; private float RoamSearchPrecision => 8f; private float RoamStuckRecoverySeconds => 3.5f; private float MovementBobAmount => 0.06f; private float MovementTiltDegrees => 4f; private float HornPulseScale => 0.06f; private float LightBaseIntensity => 45f; private float LightPulseIntensity => 35f; private float LightRange => 8.5f; private float EmissionIntensity => 0.22f; private bool DebugLogs => Plugin.ModConfig?.DebugLogs.Value ?? false; public override void Awake() { try { ((EnemyAI)this).Awake(); ResolveReferences(); ConfigureSearchDefaults(); EnsureRuntimePresentation(force: true); } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[HarmonicAI] Awake failed: {arg}"); } } } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); ResolveReferences(); EnsureRuntimePresentation(force: true); CaptureRuntimeMaterials(); } public override void Start() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) try { ResolveReferences(); ConfigureSearchDefaults(); EnsureRuntimePresentation(force: true); CaptureRuntimeMaterials(); ConfigureAgent(); if (((NetworkBehaviour)this).IsServer) { SnapToInteriorNavMeshIfNeeded(logAlways: true); } ((EnemyAI)this).Start(); base.enemyHP = Health; _pulsePhase = Random.Range(0f, 1000f); _lastMovementCheckPosition = ((Component)this).transform.position; if (((NetworkBehaviour)this).IsServer) { SwitchState(0); EnsureRoamingSearch(); RestartMusicLoop(); } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[HarmonicAI] Start failed: {arg}"); } } } public override void Update() { try { ((EnemyAI)this).Update(); ResolveReferences(); EnsureRuntimePresentation(force: false); if (!ApplyDamageStunFreeze()) { if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead) { ConfigureAgent(); RepairOffNavMeshIfNeeded(); TickRoamingSearch(Time.deltaTime); TickAlarmAttraction(); } TickLocalPulse(); } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[HarmonicAI] Update failed: {arg}"); } } } private void LateUpdate() { try { if (!ApplyDamageStunFreeze()) { ApplyHornPulse(Time.deltaTime); } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[HarmonicAI] LateUpdate failed: {arg}"); } } } public override void DoAIInterval() { try { if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead) { ConfigureAgent(); RepairOffNavMeshIfNeeded(); if ((Object)(object)base.agent == (Object)null || !((Behaviour)base.agent).enabled || !base.agent.isOnNavMesh) { return; } } ((EnemyAI)this).DoAIInterval(); if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead && !((Object)(object)StartOfRound.Instance == (Object)null) && !StartOfRound.Instance.allPlayersDead && (base.currentBehaviourStateIndex == 0 || base.currentBehaviourStateIndex == 1)) { ConfigureAgent(); RepairOffNavMeshIfNeeded(); EnsureRoamingSearch(); } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[HarmonicAI] DoAIInterval failed: {arg}"); } } } 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) { return; } BeginDamageStunFreeze(); if (((NetworkBehaviour)this).IsServer) { int num = Mathf.Max(1, force); base.enemyHP -= num; if (base.enemyHP <= 0) { DieFromDamage(); return; } PlayHitClientRpc(PickHitClipIndex(), Random.Range(0.92f, 1.08f), CalculateHitInflateAmount(base.enemyHP)); RestartMusicLoop(); } } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"[HarmonicAI] HitEnemy failed: {arg}"); } } } public override void KillEnemy(bool destroy = false) { StopServerMusicLoop(); EndAlarmAttraction(); StopLocalMusic(); if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.speed = 1f; } ClearDamageStunFreeze(); ((EnemyAI)this).KillEnemy(destroy); base.isEnemyDead = true; } public override void OnDestroy() { StopServerMusicLoop(); EndAlarmAttraction(); if (_deathPresentationRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_deathPresentationRoutine); _deathPresentationRoutine = null; } DestroyRuntimeMaterials(); ((EnemyAI)this).OnDestroy(); } public void RefreshClipsFromPlugin() { if (idleMusicClips == null || idleMusicClips.Length == 0) { idleMusicClips = Plugin.IdleMusicClips; } if ((Object)(object)alarmClip == (Object)null) { alarmClip = Plugin.AlarmClip; } if ((Object)(object)deathClip == (Object)null) { deathClip = Plugin.DeathClip; } if ((Object)(object)deathPopClip == (Object)null) { deathPopClip = Plugin.DeathPopClip; } if (hitClips == null || hitClips.Length == 0) { hitClips = Plugin.HitClips; } if ((Object)(object)deathEffectPrefab == (Object)null) { deathEffectPrefab = Plugin.DeathEffectPrefab; } } private void RestartMusicLoop() { if (((NetworkBehaviour)this).IsServer && !base.isEnemyDead) { StopServerMusicLoop(); EndAlarmAttraction(); StopMusicClientRpc(); _serverMusicRoutine = ((MonoBehaviour)this).StartCoroutine(ServerMusicLoop()); } } private void StopServerMusicLoop() { if (_serverMusicRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_serverMusicRoutine); _serverMusicRoutine = null; } } private IEnumerator ServerMusicLoop() { yield return (object)new WaitForSeconds(0.05f); while (!base.isEnemyDead && !HasIdleMusic()) { RefreshClipsFromPlugin(); yield return (object)new WaitForSeconds(0.5f); } bool nextWillAlarm = RollAlarm(); while (!base.isEnemyDead) { int num = PickIdleClipIndex(); if (num < 0) { break; } SwitchState(0); PlayIdleClientRpc(num, nextWillAlarm, Random.Range(0f, 1000f)); yield return (object)new WaitForSeconds(GetIdleClipLength(num)); if (base.isEnemyDead) { break; } if (nextWillAlarm && (Object)(object)alarmClip != (Object)null) { SwitchState(1); PlayAlarmClientRpc(Random.Range(0f, 1000f)); BeginAlarmAttraction(); yield return (object)new WaitForSeconds(Mathf.Max(0.5f, alarmClip.length)); EndAlarmAttraction(); if (base.isEnemyDead) { break; } } nextWillAlarm = RollAlarm(); } } private bool HasIdleMusic() { RefreshClipsFromPlugin(); if (idleMusicClips == null || idleMusicClips.Length == 0) { return false; } for (int i = 0; i < idleMusicClips.Length; i++) { if ((Object)(object)idleMusicClips[i] != (Object)null) { return true; } } return false; } private bool RollAlarm() { RefreshClipsFromPlugin(); if ((Object)(object)alarmClip != (Object)null) { return Random.value < AlarmChance; } return false; } private int PickIdleClipIndex() { RefreshClipsFromPlugin(); if (idleMusicClips == null || idleMusicClips.Length == 0) { return -1; } int num = Random.Range(0, idleMusicClips.Length); for (int i = 0; i < idleMusicClips.Length; i++) { int num2 = (num + i) % idleMusicClips.Length; if (!((Object)(object)idleMusicClips[num2] == (Object)null) && (idleMusicClips.Length <= 1 || num2 != _lastIdleIndex)) { _lastIdleIndex = num2; return num2; } } for (int j = 0; j < idleMusicClips.Length; j++) { if ((Object)(object)idleMusicClips[j] != (Object)null) { _lastIdleIndex = j; return j; } } return -1; } private float GetIdleClipLength(int index) { RefreshClipsFromPlugin(); AudioClip val = ((idleMusicClips != null && index >= 0 && index < idleMusicClips.Length) ? idleMusicClips[index] : null); return Mathf.Max(0.5f, ((Object)(object)val != (Object)null) ? val.length : 5f); } private int PickHitClipIndex() { RefreshClipsFromPlugin(); if (hitClips == null || hitClips.Length == 0) { return -1; } int num = Random.Range(0, hitClips.Length); for (int i = 0; i < hitClips.Length; i++) { int num2 = (num + i) % hitClips.Length; if ((Object)(object)hitClips[num2] != (Object)null) { return num2; } } return -1; } private float CalculateHitInflateAmount(int hpAfterDamage) { int num = Mathf.Max(1, Health); float num2 = Mathf.Clamp01((float)(num - Mathf.Max(0, hpAfterDamage)) / (float)num); return MaxHitInflateAmount * num2; } private Vector3 ResolveDeathEffectPosition() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (TryGetRendererBounds(((Component)this).gameObject, out var bounds)) { return ((Bounds)(ref bounds)).center; } return ((Component)this).transform.position + Vector3.up * 1.15f; } private void DieFromDamage() { //IL_0080: 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) if (!base.isEnemyDead && !_deathSent) { _deathSent = true; StopServerMusicLoop(); EndAlarmAttraction(); SwitchState(2); if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { base.agent.ResetPath(); base.agent.velocity = Vector3.zero; base.agent.speed = 0f; } PlayDeathClientRpc(ResolveDeathEffectPosition(), Mathf.Max(MaxHitInflateAmount, CalculateHitInflateAmount(0))); if (((NetworkBehaviour)this).IsOwner || ((NetworkBehaviour)this).IsServer) { ((EnemyAI)this).KillEnemyOnOwnerClient(false); } } } private void BeginAlarmAttraction() { if (((NetworkBehaviour)this).IsServer) { _serverAlarmActive = true; _nextAlarmRefreshTime = 0f; RefreshAlarmAttraction(); } } private void TickAlarmAttraction() { if (_serverAlarmActive && !(Time.time < _nextAlarmRefreshTime)) { RefreshAlarmAttraction(); } } private void RefreshAlarmAttraction() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (!_serverAlarmActive || (Object)(object)RoundManager.Instance == (Object)null) { return; } _nextAlarmRefreshTime = Time.time + AlarmRefreshSeconds; List spawnedEnemies = RoundManager.Instance.SpawnedEnemies; if (spawnedEnemies == null) { return; } for (int i = 0; i < spawnedEnemies.Count; i++) { EnemyAI val = spawnedEnemies[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)this || val is HarmonicAI || val.isEnemyDead || val.isOutside) { continue; } Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; bool flag = _alarmedEnemies.ContainsKey(val); if (flag && sqrMagnitude <= 16f) { ReleaseAlarmedEnemy(val, grantImmunity: true); continue; } float alarmAttractionRadius = AlarmAttractionRadius; if (sqrMagnitude > alarmAttractionRadius * alarmAttractionRadius) { if (flag) { ReleaseAlarmedEnemy(val, grantImmunity: false); } } else if ((flag || !(sqrMagnitude <= 16f)) && (flag || !IsTemporarilyImmuneToAlarm(val))) { AttractEnemy(val); } } } private void AttractEnemy(EnemyAI enemy) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemy == (Object)null || (Object)(object)enemy == (Object)(object)this || enemy is HarmonicAI || enemy.isEnemyDead || enemy.isOutside || (Object)(object)enemy.agent == (Object)null || !((Behaviour)enemy.agent).enabled || !enemy.agent.isOnNavMesh) { return; } if (!_alarmedEnemies.ContainsKey(enemy)) { _alarmedEnemies.Add(enemy, new AlarmedEnemyState { TargetPlayer = enemy.targetPlayer, BehaviourStateIndex = enemy.currentBehaviourStateIndex }); if (enemy.currentSearch != null && enemy.currentSearch.inProgress) { enemy.StopSearch(enemy.currentSearch, true); } } enemy.targetPlayer = null; enemy.movingTowardsTargetPlayer = false; enemy.moveTowardsDestination = true; Vector3 val = ResolveAlarmDestinationFor(enemy); enemy.SetDestinationToPosition(val, false); } private Vector3 ResolveAlarmDestinationFor(EnemyAI enemy) { //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_0032: 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_0044: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; int num = (((Object)(object)enemy != (Object)null && (Object)(object)enemy.agent != (Object)null) ? enemy.agent.areaMask : (-1)); NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val, 8f, num)) { return ((NavMeshHit)(ref val)).position; } return position; } private bool IsTemporarilyImmuneToAlarm(EnemyAI enemy) { if (!_alarmReleaseImmunityUntil.TryGetValue(enemy, out var value)) { return false; } if (Time.time < value) { return true; } _alarmReleaseImmunityUntil.Remove(enemy); return false; } private void ReleaseAlarmedEnemy(EnemyAI enemy, bool grantImmunity) { if (!((Object)(object)enemy == (Object)null) && _alarmedEnemies.TryGetValue(enemy, out var value)) { _alarmedEnemies.Remove(enemy); RestoreAlarmedEnemy(enemy, value); if (grantImmunity && !enemy.isEnemyDead) { _alarmReleaseImmunityUntil[enemy] = Time.time + 1f; } } } private static void RestoreAlarmedEnemy(EnemyAI enemy, AlarmedEnemyState state) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)enemy == (Object)null) && !enemy.isEnemyDead) { if (enemy.currentBehaviourStateIndex != state.BehaviourStateIndex) { enemy.SwitchToBehaviourState(state.BehaviourStateIndex); } if (IsValidRestoredTarget(state.TargetPlayer)) { enemy.targetPlayer = state.TargetPlayer; enemy.movingTowardsTargetPlayer = true; enemy.SetMovingTowardsTargetPlayer(state.TargetPlayer); } else { enemy.targetPlayer = null; enemy.movingTowardsTargetPlayer = false; enemy.moveTowardsDestination = false; enemy.StartSearch(((Component)enemy).transform.position, (AISearchRoutine)null); } } } private void EndAlarmAttraction() { if (!_serverAlarmActive && _alarmedEnemies.Count == 0) { return; } _serverAlarmActive = false; foreach (KeyValuePair alarmedEnemy in _alarmedEnemies) { EnemyAI key = alarmedEnemy.Key; if (!((Object)(object)key == (Object)null) && !key.isEnemyDead) { RestoreAlarmedEnemy(key, alarmedEnemy.Value); } } _alarmedEnemies.Clear(); _alarmReleaseImmunityUntil.Clear(); if (!base.isEnemyDead) { SwitchState(0); } } private static bool IsValidRestoredTarget(PlayerControllerB player) { if ((Object)(object)player != (Object)null) { return !player.isPlayerDead; } return false; } [ClientRpc] private void PlayIdleClientRpc(int clipIndex, bool warningRamp, float phase) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00a5: 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_00bf: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2294735284u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, clipIndex); ((FastBufferWriter)(ref val)).WriteValueSafe(ref warningRamp, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref phase, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2294735284u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; QueueLocalPlayback(1, clipIndex, warningRamp, phase); } } } [ClientRpc] private void PlayAlarmClientRpc(float phase) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(643380925u, val2, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe(ref phase, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 643380925u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; QueueLocalPlayback(2, -1, warningRamp: false, phase); } } } [ClientRpc] private void StopMusicClientRpc() { //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) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(4194604744u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 4194604744u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; StopLocalMusic(); } } } [ClientRpc] private void PlayHitClientRpc(int clipIndex, float pitch, float inflateAmount) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00a5: 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_00bf: 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) 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(1244013670u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, clipIndex); ((FastBufferWriter)(ref val)).WriteValueSafe(ref pitch, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref inflateAmount, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 1244013670u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveReferences(); RefreshClipsFromPlugin(); SetInflationTarget(inflateAmount); AudioClip val3 = ((hitClips != null && clipIndex >= 0 && clipIndex < hitClips.Length) ? hitClips[clipIndex] : null); if (!((Object)(object)val3 == (Object)null) && !((Object)(object)sfxSource == (Object)null)) { sfxSource.pitch = Mathf.Clamp(pitch, 0.75f, 1.3f); sfxSource.PlayOneShot(val3, HitVolume * 1f); _deathFadeStartedAt = -1f; } } } [ClientRpc] private void PlayDeathClientRpc(Vector3 effectPosition, float fatalInflateAmount) { //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_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) //IL_0190: 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(2758446597u, val2, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe(ref effectPosition); ((FastBufferWriter)(ref val)).WriteValueSafe(ref fatalInflateAmount, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2758446597u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ResolveReferences(); RefreshClipsFromPlugin(); StopLocalMusic(); _deathFadeStartedAt = -1f; _desiredHornPulseAmount = 0f; SetInflationTarget(fatalInflateAmount); AudioClip val3 = (((Object)(object)deathPopClip != (Object)null) ? deathPopClip : deathClip); if ((Object)(object)sfxSource != (Object)null && (Object)(object)val3 != (Object)null) { sfxSource.pitch = 1f; sfxSource.PlayOneShot(val3, DeathVolume * 1f); } if (_deathPresentationRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_deathPresentationRoutine); } _deathPresentationRoutine = ((MonoBehaviour)this).StartCoroutine(DeathPopPresentation(effectPosition, fatalInflateAmount)); } } private void QueueLocalPlayback(int kind, int clipIndex, bool warningRamp, float phase) { ResolveReferences(); RefreshClipsFromPlugin(); _localPlaybackToken++; if (_localPlaybackRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_localPlaybackRoutine); } _localPlaybackRoutine = ((MonoBehaviour)this).StartCoroutine(PlayWhenReady(_localPlaybackToken, kind, clipIndex, warningRamp, phase)); } private IEnumerator PlayWhenReady(int token, int kind, int clipIndex, bool warningRamp, float phase) { float deadline = Time.realtimeSinceStartup + 10f; AudioClip clip = ResolvePlaybackClip(kind, clipIndex); while ((Object)(object)clip == (Object)null && Time.realtimeSinceStartup < deadline) { if (token != _localPlaybackToken) { yield break; } RefreshClipsFromPlugin(); clip = ResolvePlaybackClip(kind, clipIndex); yield return (object)new WaitForSeconds(0.2f); } if (token == _localPlaybackToken && !((Object)(object)clip == (Object)null)) { PlayLocalMusicClip(kind, clipIndex, clip, warningRamp, phase); } } private AudioClip ResolvePlaybackClip(int kind, int clipIndex) { RefreshClipsFromPlugin(); switch (kind) { case 2: return alarmClip; case 1: if (idleMusicClips != null && clipIndex >= 0 && clipIndex < idleMusicClips.Length) { return idleMusicClips[clipIndex]; } break; } return null; } private void PlayLocalMusicClip(int kind, int clipIndex, AudioClip clip, bool warningRamp, float phase) { if (!((Object)(object)musicSource == (Object)null) && !((Object)(object)clip == (Object)null)) { CrossFadeAnimationForTrack(kind, clipIndex, warningRamp); musicSource.Stop(); musicSource.clip = clip; musicSource.loop = false; musicSource.pitch = 1f; musicSource.volume = ResolveEffectiveMusicVolume(kind == 2); musicSource.Play(); _pulsePhase = phase; _localTrackKind = kind; _localWarningRamp = warningRamp; _localClipStartedAt = Time.time; _localClipDuration = Mathf.Max(0.1f, clip.length); _deathFadeStartedAt = -1f; } } private void StopLocalMusic() { _localPlaybackToken++; if (_localPlaybackRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_localPlaybackRoutine); _localPlaybackRoutine = null; } if ((Object)(object)musicSource != (Object)null) { musicSource.Stop(); musicSource.pitch = 1f; } _localTrackKind = 0; _localWarningRamp = false; _desiredHornPulseAmount = 0f; } private void CrossFadeAnimationForTrack(int kind, int clipIndex, bool warningRamp) { if (!((Object)(object)base.creatureAnimator == (Object)null) && IdleAnimationStates.Length != 0) { string text; if (kind == 2) { text = "Idle_4"; } else if (warningRamp) { text = "Idle_3"; } else { int num = Mathf.Abs(clipIndex) % IdleAnimationStates.Length; text = IdleAnimationStates[num]; } if (!string.Equals(_currentAnimationState, text, StringComparison.Ordinal)) { base.creatureAnimator.CrossFade(text, 0.35f, 0, 0f); _currentAnimationState = text; } } } private void TickLocalPulse() { ResolveReferences(); TickAudioOcclusion(); if (_deathFadeStartedAt >= 0f) { TickDeathFade(); return; } float warningAmount = GetWarningAmount(); bool flag = _localTrackKind == 2; float num = (flag ? 1f : warningAmount); float num2 = Mathf.Lerp(PulseRate, WarningPulseRate, num); float num3 = (Mathf.Sin((Time.time + _pulsePhase) * num2 * MathF.PI * 2f) + 1f) * 0.5f; float centeredPulse = num3 * 2f - 1f; TickMusicModulation(warningAmount, flag, centeredPulse); TickLightAndEmission(num3, num); TickAnimatorSpeed(centeredPulse, num); TickVisualHover(num3, num); TickHornPulseTarget(num3, num); } private float GetWarningAmount() { if (!_localWarningRamp || _localTrackKind != 1 || _localClipDuration <= 0f) { return 0f; } float num = Mathf.Clamp01((Time.time - _localClipStartedAt) / _localClipDuration); return Mathf.SmoothStep(0f, 1f, num); } private void TickMusicModulation(float warningAmount, bool alarmActive, float centeredPulse) { if (!((Object)(object)musicSource == (Object)null) && musicSource.isPlaying) { float num = ResolveEffectiveMusicVolume(alarmActive); float num2 = (alarmActive ? 1f : Mathf.Lerp(1f, WarningPitchMultiplier, warningAmount)); float num3 = centeredPulse * PitchPulseAmount * (alarmActive ? 1.35f : 1f); float num4 = centeredPulse * VolumePulseAmount * (alarmActive ? 1.25f : 1f); musicSource.pitch = Mathf.Clamp(num2 + num3, 0.65f, 1.65f); musicSource.volume = Mathf.Clamp01(num * (1f + num4 + warningAmount * 0.12f)); } } private void TickLightAndEmission(float pulse, float urgency) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00ce: 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_00df: Unknown result type (might be due to invalid IL or missing references) Color val = Color.Lerp(new Color(0.28f, 0.18f, 0.72f, 1f), new Color(0.72f, 0.36f, 0.9f, 1f), urgency); float intensity = LightBaseIntensity + LightPulseIntensity * Mathf.Lerp(pulse * 0.55f, 1f, urgency * 0.35f); if ((Object)(object)glowLight != (Object)null) { ((Behaviour)glowLight).enabled = true; glowLight.color = val; glowLight.range = LightRange; glowLight.intensity = intensity; } Color color = val * (EmissionIntensity * Mathf.Lerp(0.08f + pulse * 0.14f, 0.42f, urgency * 0.55f)); for (int i = 0; i < _runtimeMaterials.Count; i++) { ApplyEmission(_runtimeMaterials[i], color); } } private void TickAnimatorSpeed(float centeredPulse, float urgency) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.creatureAnimator == (Object)null) { return; } base.creatureAnimator.speed = Mathf.Clamp(1f + urgency * 0.1f, 0.85f, 1.25f); if (_hasMovingParameter) { int num; if (base.currentBehaviourStateIndex != 2 && (Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { Vector3 velocity = base.agent.velocity; num = ((((Vector3)(ref velocity)).sqrMagnitude > 0.01f) ? 1 : 0); } else { num = 0; } bool flag = (byte)num != 0; base.creatureAnimator.SetBool(MovingHash, flag); } } private void TickVisualHover(float pulse, float urgency) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)visualRoot == (Object)null) && !((Object)(object)visualRoot == (Object)(object)((Component)this).transform)) { if (!_hasCapturedVisualBase) { _visualBaseLocalPosition = visualRoot.localPosition; _visualBaseLocalRotation = visualRoot.localRotation; _visualBaseLocalScale = visualRoot.localScale; _hasCapturedVisualBase = true; } if (!_hasVisualBounds) { CaptureVisualBounds(); } float num = Mathf.Max(0.05f, Mathf.Abs(((Component)this).transform.lossyScale.y)); float num2 = HoverHeight / num; float movementAmount = GetMovementAmount(); float num3 = Mathf.Lerp(0.018f, 0.04f, urgency) * (pulse * 2f - 1f) / num; float num4 = Mathf.Sin((Time.time + _pulsePhase * 0.17f) * MathF.PI * 2f * 0.72f) * MovementBobAmount * movementAmount / num; float num5 = num3 + num4; float num6 = (_hasVisualBounds ? (num2 - _visualLocalMinY + num5) : (_visualBaseLocalPosition.y + num2 + num5)); if (_hasVisualBounds && TryGetCeilingClearanceLocal(out var clearanceLocal)) { float num7 = 0.18f / num; float num8 = clearanceLocal - num7 - _visualLocalMaxY; num6 = Mathf.Min(num6, num8); } Vector3 visualBaseLocalPosition = _visualBaseLocalPosition; visualBaseLocalPosition.y = num6; Vector3 localPosition = visualRoot.localPosition; localPosition.y = Mathf.SmoothDamp(localPosition.y, visualBaseLocalPosition.y, ref _visualHoverVelocity, 0.18f, 6f, Time.deltaTime); visualRoot.localPosition = localPosition; float num9 = Mathf.Sin((Time.time + _pulsePhase * 0.11f) * MathF.PI * 2f * 0.55f) * MovementTiltDegrees * movementAmount; Quaternion val = _visualBaseLocalRotation * Quaternion.Euler(0f, 0f, num9); float num10 = 1f - Mathf.Exp((0f - Time.deltaTime) * 5f); visualRoot.localRotation = Quaternion.Slerp(visualRoot.localRotation, val, num10); TickVisualInflation(Time.deltaTime); } } private float GetMovementAmount() { //IL_0062: 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) if (base.currentBehaviourStateIndex == 2 || (Object)(object)base.agent == (Object)null || !((Behaviour)base.agent).enabled || !base.agent.isOnNavMesh) { return 0f; } float num = Mathf.Max(0.1f, Plugin.ModConfig?.MoveSpeed.Value ?? 1.15f); Vector3 velocity = base.agent.velocity; float num2 = Mathf.Clamp01(((Vector3)(ref velocity)).magnitude / num); if (num2 > 0.05f) { return num2; } if (base.agent.hasPath && !base.agent.pathPending && base.agent.remainingDistance > Mathf.Max(base.agent.stoppingDistance + 0.8f, 1.2f)) { return 0.35f; } return 0f; } private void SetInflationTarget(float inflateAmount) { _targetHitInflateAmount = Mathf.Max(_targetHitInflateAmount, Mathf.Clamp(inflateAmount, 0f, MaxHitInflateAmount)); } private void TickVisualInflation(float deltaTime) { //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_0026: 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 (!((Object)(object)visualRoot == (Object)null) && !_deathBodyHidden) { if (!_hasCapturedVisualBase) { _visualBaseLocalScale = visualRoot.localScale; _hasCapturedVisualBase = true; } _hitInflateAmount = Mathf.SmoothDamp(_hitInflateAmount, _targetHitInflateAmount, ref _hitInflateVelocity, 0.12f, 8f, Mathf.Max(0.0001f, deltaTime)); visualRoot.localScale = _visualBaseLocalScale * (1f + _hitInflateAmount); } } private IEnumerator DeathPopPresentation(Vector3 effectPosition, float fatalInflateAmount) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!_deathBodyHidden) { _targetHitInflateAmount = Mathf.Clamp(fatalInflateAmount, 0f, Mathf.Max(MaxHitInflateAmount, fatalInflateAmount)); _hitInflateAmount = _targetHitInflateAmount; if ((Object)(object)visualRoot != (Object)null) { visualRoot.localScale = _visualBaseLocalScale * (1f + _hitInflateAmount); } yield return (object)new WaitForSeconds(0.08f); SpawnDeathEffect(effectPosition); SpawnDeathBloodSplatter(effectPosition); HideDeathBody(); _deathPresentationRoutine = null; } } private void SpawnDeathBloodSplatter(Vector3 point) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) //IL_006b: 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_0075: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_009b: 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_00af: 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_00b8: 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_00c0: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(((Component)this).transform.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = Vector3.forward; } else { ((Vector3)(ref val)).Normalize(); } Vector3 val2 = Vector3.Cross(Vector3.up, val); Vector3 normalized = ((Vector3)(ref val2)).normalized; Vector3[] array = new Vector3[5]; val2 = val + normalized * 0.25f + Vector3.down * 0.25f; array[0] = ((Vector3)(ref val2)).normalized; val2 = -val + normalized * 0.2f + Vector3.down * 0.3f; array[1] = ((Vector3)(ref val2)).normalized; val2 = normalized + Vector3.down * 0.45f; array[2] = ((Vector3)(ref val2)).normalized; val2 = -normalized + Vector3.down * 0.55f; array[3] = ((Vector3)(ref val2)).normalized; array[4] = Vector3.down; Vector3[] array2 = (Vector3[])(object)array; Color tint = default(Color); ((Color)(ref tint))..ctor(0.32f, 0.44f, 0.06f, 1f); int instanceID = ((Object)this).GetInstanceID(); for (int i = 0; i < array2.Length; i++) { HarmonicBloodFxBridge.PlayCreatureBleed(instanceID, point, array2[i], tint, 4, 1.25f); } } private void SpawnDeathEffect(Vector3 position) { //IL_0027: 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_0044: 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_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) GameObject val = (((Object)(object)deathEffectPrefab != (Object)null) ? deathEffectPrefab : Plugin.DeathEffectPrefab); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = Object.Instantiate(val, position, Quaternion.identity); ((Object)val2).name = "HarmonicDeathDustExplosion_Local"; val2.transform.localScale = Vector3.one * DeathEffectScale; Plugin.RepairParticleRenderers(val2); ParticleSystem[] componentsInChildren = val2.GetComponentsInChildren(true); foreach (ParticleSystem val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { MainModule main = val3.main; ((MainModule)(ref main)).loop = false; ((Component)val3).gameObject.SetActive(true); val3.Play(true); } } Object.Destroy((Object)(object)val2, 5f); } private void HideDeathBody() { _deathBodyHidden = true; _desiredHornPulseAmount = 0f; if ((Object)(object)glowLight != (Object)null) { ((Behaviour)glowLight).enabled = false; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.enabled = false; } } Collider[] componentsInChildren2 = ((Component)this).GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { val2.enabled = false; } } if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.speed = 0f; } } private void TickHornPulseTarget(float pulse, float urgency) { if (_localTrackKind == 0 || !((Object)(object)musicSource != (Object)null) || !musicSource.isPlaying) { _desiredHornPulseAmount = 0f; return; } float num = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(pulse)); _desiredHornPulseAmount = Mathf.Clamp01(num * Mathf.Lerp(0.7f, 1f, urgency)); } private void ApplyHornPulse(float deltaTime) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) EnsureHornPulseTargets(); if (_hornPulseTargets.Count == 0) { return; } float num = (base.isEnemyDead ? 0f : _desiredHornPulseAmount); _hornPulseAmount = Mathf.SmoothDamp(_hornPulseAmount, num, ref _hornPulseVelocity, 0.07f, 18f, Mathf.Max(0.0001f, deltaTime)); float num2 = 1f + HornPulseScale * _hornPulseAmount; for (int num3 = _hornPulseTargets.Count - 1; num3 >= 0; num3--) { HornPulseTarget hornPulseTarget = _hornPulseTargets[num3]; if (hornPulseTarget == null || (Object)(object)hornPulseTarget.Transform == (Object)null) { _hornPulseTargets.RemoveAt(num3); } else { hornPulseTarget.Transform.localScale = hornPulseTarget.BaseScale * num2; } } } private void EnsureHornPulseTargets() { if (_hornPulseTargetsScanned) { return; } _hornPulseTargetsScanned = true; for (int i = 0; i < HornPulseBoneNames.Length; i++) { Transform val = Plugin.FindChildRecursive(((Component)this).transform, HornPulseBoneNames[i]); if (!((Object)(object)val == (Object)null)) { _hornPulseTargets.Add(new HornPulseTarget(val)); } } if (DebugLogs) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[HarmonicAI] Horn pulse targets found: {_hornPulseTargets.Count}."); } } } private void CaptureVisualBounds() { //IL_0054: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0083: 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_008f: 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_009d: 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_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_00b7: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00f2: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visualRoot == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); bool flag = false; float num = 0f; float num2 = 0f; foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { continue; } Bounds bounds = val.bounds; Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; Vector3[] array = (Vector3[])(object)new Vector3[8] { new Vector3(min.x, min.y, min.z), new Vector3(min.x, min.y, max.z), new Vector3(min.x, max.y, min.z), new Vector3(min.x, max.y, max.z), new Vector3(max.x, min.y, min.z), new Vector3(max.x, min.y, max.z), new Vector3(max.x, max.y, min.z), new Vector3(max.x, max.y, max.z) }; for (int j = 0; j < array.Length; j++) { float num3 = ((Component)this).transform.InverseTransformPoint(array[j]).y - visualRoot.localPosition.y; if (!flag) { num = num3; num2 = num3; flag = true; } else { num = Mathf.Min(num, num3); num2 = Mathf.Max(num2, num3); } } } if (flag) { _visualLocalMinY = num; _visualLocalMaxY = num2; _hasVisualBounds = true; } } private static bool TryGetRendererBounds(GameObject root, out Bounds bounds) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0074: 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_0069: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(((Object)(object)root != (Object)null) ? root.transform.position : Vector3.zero, Vector3.zero); if ((Object)(object)root == (Object)null) { return false; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); bool flag = false; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return flag; } private bool TryGetCeilingClearanceLocal(out float clearanceLocal) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_00a8: Unknown result type (might be due to invalid IL or missing references) clearanceLocal = 0f; RaycastHit[] array = Physics.RaycastAll(((Component)this).transform.position + Vector3.up * 0.15f, Vector3.up, 5.5f, -1, (QueryTriggerInteraction)1); float num = float.MaxValue; bool flag = false; for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)this).transform) && ((RaycastHit)(ref val)).distance < num) { num = ((RaycastHit)(ref val)).distance; flag = true; } } if (!flag) { return false; } float num2 = Mathf.Max(0.05f, Mathf.Abs(((Component)this).transform.lossyScale.y)); clearanceLocal = (0.15f + num) / num2; return true; } private void TickDeathFade() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01((Time.time - _deathFadeStartedAt) / 3f); float num2 = 1f - num; Color color = new Color(0.18f, 0.12f, 0.58f, 1f) * Mathf.Max(0f, num2 * EmissionIntensity); _desiredHornPulseAmount = 0f; if ((Object)(object)glowLight != (Object)null) { glowLight.intensity = LightBaseIntensity * num2; } for (int i = 0; i < _runtimeMaterials.Count; i++) { ApplyEmission(_runtimeMaterials[i], color); } if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.speed = Mathf.Lerp(0.35f, 0f, num); } } private void ResolveReferences() { if ((Object)(object)base.agent == (Object)null) { base.agent = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInChildren(true); } if ((Object)(object)base.creatureAnimator == (Object)null) { base.creatureAnimator = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInChildren(true); } if ((Object)(object)visualRoot == (Object)null) { visualRoot = Plugin.FindChildRecursive(((Component)this).transform, "VisualRoot") ?? Plugin.FindChildRecursive(((Component)this).transform, "Armature") ?? ((Component)this).transform; } if ((Object)(object)base.eye == (Object)null) { base.eye = Plugin.FindChildRecursive(((Component)this).transform, "EyeTransform") ?? ((Component)this).transform; } if ((Object)(object)musicSource == (Object)null) { musicSource = FindAudioSource("HarmonicMusic"); } if ((Object)(object)sfxSource == (Object)null) { sfxSource = FindAudioSource("HarmonicSFX"); } if ((Object)(object)base.creatureVoice == (Object)null) { base.creatureVoice = musicSource; } if ((Object)(object)base.creatureSFX == (Object)null) { base.creatureSFX = sfxSource; } if ((Object)(object)glowLight == (Object)null) { glowLight = ((Component)this).GetComponentInChildren(true); } ConfigureAudioSource(musicSource, Plugin.ModConfig?.MusicMaxDistance.Value ?? 65f, 65f); ConfigureAudioSource(sfxSource, Plugin.ModConfig?.SfxMaxDistance.Value ?? 42f, 42f); _musicLowPass = EnsureLowPass(musicSource, _musicLowPass); _sfxLowPass = EnsureLowPass(sfxSource, _sfxLowPass); RefreshClipsFromPlugin(); if ((Object)(object)base.creatureAnimator != (Object)null) { _hasMovingParameter = HasParam(base.creatureAnimator, MovingHash, (AnimatorControllerParameterType)4); } } private void EnsureRuntimePresentation(bool force) { if (!_deathBodyHidden && (force || !(Time.time < _nextPresentationRepairTime))) { _nextPresentationRepairTime = Time.time + 1f; bool flag = !_presentationLogged || DebugLogs; int num = Plugin.RepairRuntimePresentation(((Component)this).gameObject, force ? "spawned instance" : "runtime", flag); if (flag) { _presentationLogged = true; } if (num > 0 && _runtimeMaterials.Count == 0) { CaptureRuntimeMaterials(); } if (num > 0 && !_hasVisualBounds) { CaptureVisualBounds(); } } } private void ConfigureAgent() { if (!((Object)(object)base.agent == (Object)null)) { Plugin.ConfigureAgent(base.agent); } } private void BeginDamageStunFreeze() { _damageStunUntil = Mathf.Max(_damageStunUntil, Time.time + 1f); ApplyDamageStunFreeze(); } private bool ApplyDamageStunFreeze() { if (!(base.stunNormalizedTimer >= 0f) && !(Time.time < _damageStunUntil)) { ClearDamageStunFreeze(); return false; } StopAgentForDamageStun(); if (!_damageStunFrozen) { _preDamageStunAnimatorSpeed = (((Object)(object)base.creatureAnimator != (Object)null) ? Mathf.Max(0.01f, base.creatureAnimator.speed) : 1f); _damageStunFrozen = true; } if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.speed = 0f; } return true; } private void ClearDamageStunFreeze() { if (_damageStunFrozen) { if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.speed = _preDamageStunAnimatorSpeed; } if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled) { base.agent.isStopped = false; } _damageStunFrozen = false; } } private void StopAgentForDamageStun() { //IL_0046: 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.isStopped = true; if (base.agent.isOnNavMesh) { base.agent.ResetPath(); base.agent.velocity = Vector3.zero; } } } 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 (facilitySearch == null) { facilitySearch = new AISearchRoutine(); } facilitySearch.loopSearch = true; facilitySearch.randomized = true; facilitySearch.onlySearchNodesInLOS = false; facilitySearch.searchWidth = RoamSearchWidth; facilitySearch.searchPrecision = RoamSearchPrecision; } private void EnsureRoamingSearch() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsOwner && !base.isEnemyDead && (base.currentBehaviourStateIndex == 0 || base.currentBehaviourStateIndex == 1) && !((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { ConfigureSearchDefaults(); if (facilitySearch == null || base.currentSearch != facilitySearch || !facilitySearch.inProgress) { StartRoamingSearch(((Component)this).transform.position); } } } private void StartRoamingSearch(Vector3 start) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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) if (((NetworkBehaviour)this).IsOwner && !((Object)(object)base.agent == (Object)null) && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { ConfigureSearchDefaults(); if (base.currentSearch != null && base.currentSearch.inProgress) { ((EnemyAI)this).StopSearch(base.currentSearch, false); } ((EnemyAI)this).StartSearch(start, facilitySearch); _stuckTimer = 0f; _lastMovementCheckPosition = ((Component)this).transform.position; _nextSearchRepairTime = Time.time + 1f; } } private void TickRoamingSearch(float deltaTime) { //IL_0083: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsOwner || base.isEnemyDead) { return; } if (base.currentBehaviourStateIndex != 0 && base.currentBehaviourStateIndex != 1) { _stuckTimer = 0f; return; } EnsureRoamingSearch(); if ((Object)(object)base.agent == (Object)null || !((Behaviour)base.agent).enabled || !base.agent.isOnNavMesh || facilitySearch == null || !facilitySearch.inProgress) { _stuckTimer = 0f; _lastMovementCheckPosition = ((Component)this).transform.position; return; } Vector3 val = ((Component)this).transform.position - _lastMovementCheckPosition; val.y = 0f; _lastMovementCheckPosition = ((Component)this).transform.position; bool num = base.agent.hasPath && !base.agent.pathPending && base.agent.remainingDistance > Mathf.Max(base.agent.stoppingDistance + 0.8f, 1.4f); int num2; if (!(((Vector3)(ref val)).sqrMagnitude > 0.001f)) { Vector3 velocity = base.agent.velocity; num2 = ((((Vector3)(ref velocity)).sqrMagnitude > 0.01f) ? 1 : 0); } else { num2 = 1; } bool flag = (byte)num2 != 0; if (!num || flag) { _stuckTimer = 0f; return; } _stuckTimer += Mathf.Max(0f, deltaTime); if (_stuckTimer < RoamStuckRecoverySeconds || Time.time < _nextSearchRepairTime) { return; } _nextSearchRepairTime = Time.time + 1.5f; StartRoamingSearch(((Component)this).transform.position); if (DebugLogs) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[HarmonicAI] Restarted roaming search after movement stall."); } } } private void RepairOffNavMeshIfNeeded() { if (((NetworkBehaviour)this).IsServer && !((Object)(object)base.agent == (Object)null) && !(Time.time < _nextNavMeshRepairTime) && (!((Behaviour)base.agent).enabled || !base.agent.isOnNavMesh)) { _nextNavMeshRepairTime = Time.time + 1f; SnapToInteriorNavMeshIfNeeded(logAlways: false); } } private bool SnapToInteriorNavMeshIfNeeded(bool logAlways) { //IL_003a: 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_0047: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer || (Object)(object)base.agent == (Object)null) { return false; } if (((Behaviour)base.agent).enabled && base.agent.isOnNavMesh) { return true; } Vector3 position = ((Component)this).transform.position; int areaMask = ResolveAgentAreaMask(); if (TrySampleNavMesh(position, 12f, areaMask, out var position2) || TrySampleInsideAINodes(position, areaMask, out position2) || TrySampleNearPlayers(position, areaMask, out position2) || TrySampleNavMesh(position, 80f, -1, out position2)) { if (((Behaviour)base.agent).enabled) { ((Behaviour)base.agent).enabled = false; } ((Component)this).transform.position = position2; ((Behaviour)base.agent).enabled = true; ConfigureAgent(); bool flag = base.agent.Warp(position2); if (flag) { _nextNavMeshRepairTime = Time.time + 1f; } if (logAlways || DebugLogs) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[HarmonicAI] Snapped off-mesh spawn from {position} to {position2} (warp={flag})."); } } if (!flag) { return base.agent.isOnNavMesh; } return true; } if (logAlways || DebugLogs) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"[HarmonicAI] Could not find an interior NavMesh point near off-mesh spawn at {position}."); } } return false; } private int ResolveAgentAreaMask() { if ((Object)(object)base.agent == (Object)null || base.agent.areaMask == 0) { return -1; } return base.agent.areaMask; } private static bool TrySampleNavMesh(Vector3 candidate, float radius, int areaMask, out Vector3 position) { //IL_0000: 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_002b: 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_001e: Unknown result type (might be due to invalid IL or missing references) NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(candidate, ref val, Mathf.Max(0.25f, radius), areaMask)) { position = ((NavMeshHit)(ref val)).position; return true; } position = Vector3.zero; return false; } private static bool TrySampleInsideAINodes(Vector3 origin, int areaMask, out Vector3 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_00f1: 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_00d0: Unknown result type (might be due to invalid IL or missing references) GameObject[] array = null; if ((Object)(object)RoundManager.Instance != (Object)null) { array = RoundManager.Instance.insideAINodes; } if (array == null || array.Length == 0) { array = GameObject.FindGameObjectsWithTag("AINode"); } if (array == null || array.Length == 0) { position = Vector3.zero; return false; } List list = new List(array.Length); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { list.Add(array[i]); } } list.Sort(delegate(GameObject left, GameObject right) { //IL_0006: 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_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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val = left.transform.position - origin; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; val = right.transform.position - origin; return sqrMagnitude.CompareTo(((Vector3)(ref val)).sqrMagnitude); }); int num = Mathf.Min(list.Count, 32); for (int num2 = 0; num2 < num; num2++) { if (TrySampleNavMesh(list[num2].transform.position, 10f, areaMask, out position) || TrySampleNavMesh(list[num2].transform.position, 10f, -1, out position)) { return true; } } position = Vector3.zero; return false; } private static bool TrySampleNearPlayers(Vector3 origin, int areaMask, out Vector3 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a2: 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_00c2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null) { position = Vector3.zero; return false; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; List list = new List(allPlayerScripts.Length); foreach (PlayerControllerB val in allPlayerScripts) { if ((Object)(object)val != (Object)null && val.isPlayerControlled && !val.isPlayerDead) { list.Add(val); } } list.Sort(delegate(PlayerControllerB left, PlayerControllerB right) { //IL_0006: 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_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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = ((Component)left).transform.position - origin; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; val2 = ((Component)right).transform.position - origin; return sqrMagnitude.CompareTo(((Vector3)(ref val2)).sqrMagnitude); }); for (int num = 0; num < list.Count; num++) { if (TrySampleNavMesh(((Component)list[num]).transform.position, 18f, areaMask, out position) || TrySampleNavMesh(((Component)list[num]).transform.position, 18f, -1, out position)) { return true; } } position = Vector3.zero; return false; } private bool IsSearching() { if (base.currentSearch != null) { return base.currentSearch.inProgress; } return false; } private void SwitchState(int state) { if (base.currentBehaviourStateIndex != state) { ((EnemyAI)this).SwitchToBehaviourState(state); } } private AudioSource FindAudioSource(string childName) { Transform val = ((Component)this).transform.Find(childName); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent(); } private static void ConfigureAudioSource(AudioSource source, float maxDistance, float hardMaxDistance) { if (!((Object)(object)source == (Object)null)) { source.playOnAwake = false; source.spatialBlend = 1f; source.rolloffMode = (AudioRolloffMode)0; source.minDistance = 4f; source.maxDistance = Mathf.Clamp(maxDistance, 8f, hardMaxDistance); source.dopplerLevel = 0f; source.spread = 55f; } } private static AudioLowPassFilter EnsureLowPass(AudioSource source, AudioLowPassFilter existing) { if ((Object)(object)source == (Object)null) { return null; } if ((Object)(object)existing != (Object)null && (Object)(object)((Component)existing).gameObject == (Object)(object)((Component)source).gameObject) { return existing; } AudioLowPassFilter val = ((Component)source).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)source).gameObject.AddComponent(); } val.cutoffFrequency = 22000f; val.lowpassResonanceQ = 1f; return val; } private void TickAudioOcclusion() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) if (Time.time < _nextAudioOcclusionUpdateTime) { return; } _nextAudioOcclusionUpdateTime = Time.time + 0.15f; PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null && (Object)(object)StartOfRound.Instance != (Object)null) { val = StartOfRound.Instance.localPlayerController; } if ((Object)(object)val == (Object)null) { SetLowPass(_musicLowPass, 22000f); SetLowPass(_sfxLowPass, 22000f); return; } Vector3 val2 = (((Object)(object)val.gameplayCamera != (Object)null) ? ((Component)val.gameplayCamera).transform.position : (((Component)val).transform.position + Vector3.up * 1.6f)); Vector3 val3 = (((Object)(object)musicSource != (Object)null) ? ((Component)musicSource).transform.position : (((Component)this).transform.position + Vector3.up * 0.8f)); float num = (((Object)(object)musicSource != (Object)null) ? Mathf.Max(8f, musicSource.maxDistance) : 65f); float num2 = Vector3.Distance(val3, val2); float num3 = Mathf.InverseLerp(num * 0.35f, num, num2); bool num4 = IsAudioObstructed(val3, val2, val); float num5 = Mathf.Lerp(22000f, 6500f, num3); if (num4) { num5 = Mathf.Min(num5, Mathf.Lerp(2400f, 1500f, num3)); } SetLowPass(_musicLowPass, num5); SetLowPass(_sfxLowPass, Mathf.Lerp(num5, 22000f, 0.25f)); } private bool IsAudioObstructed(Vector3 sourcePosition, Vector3 listenerPosition, PlayerControllerB localPlayer) { //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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) Vector3 val = listenerPosition - sourcePosition; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 0.75f) { return false; } int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-1)); int num2 = Physics.RaycastNonAlloc(sourcePosition, val / magnitude, _audioOcclusionHits, magnitude - 0.1f, num, (QueryTriggerInteraction)1); for (int i = 0; i < num2; i++) { Collider collider = ((RaycastHit)(ref _audioOcclusionHits[i])).collider; if (!((Object)(object)collider == (Object)null)) { Transform transform = ((Component)collider).transform; if (!((Object)(object)transform == (Object)null) && !transform.IsChildOf(((Component)this).transform) && (!((Object)(object)localPlayer != (Object)null) || !transform.IsChildOf(((Component)localPlayer).transform))) { return true; } } } return false; } private static void SetLowPass(AudioLowPassFilter lowPass, float cutoff) { if (!((Object)(object)lowPass == (Object)null)) { lowPass.cutoffFrequency = Mathf.Lerp(lowPass.cutoffFrequency, Mathf.Clamp(cutoff, 800f, 22000f), 0.35f); } } private float ResolveEffectiveMusicVolume(bool alarmActive) { float num = (alarmActive ? AlarmVolume : IdleVolume); float num2 = (alarmActive ? 1f : 1f); return Mathf.Clamp01(num * num2); } private void CaptureRuntimeMaterials() { if (_runtimeMaterials.Count > 0) { return; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { continue; } Material[] materials = val.materials; if (materials == null) { continue; } foreach (Material val2 in materials) { if ((Object)(object)val2 != (Object)null && !_runtimeMaterials.Contains(val2)) { val2.EnableKeyword("_EMISSION"); _runtimeMaterials.Add(val2); } } } } private void DestroyRuntimeMaterials() { for (int i = 0; i < _runtimeMaterials.Count; i++) { Material val = _runtimeMaterials[i]; if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } _runtimeMaterials.Clear(); } private static void ApplyEmission(Material material, Color color) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { SetColorIfPresent(material, "_EmissionColor", color); SetColorIfPresent(material, "_EmissiveColor", color); SetFloatIfPresent(material, "_EmissiveIntensity", Mathf.Max(((Color)(ref color)).maxColorComponent, 0f)); material.EnableKeyword("_EMISSION"); } } private static void SetColorIfPresent(Material material, string property, Color value) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetColor(property, value); } } private static void SetFloatIfPresent(Material material, string property, float value) { if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetFloat(property, value); } } private static bool HasParam(Animator anim, int hash, AnimatorControllerParameterType type) { //IL_0024: 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) if ((Object)(object)anim == (Object)null) { return false; } AnimatorControllerParameter[] parameters = anim.parameters; foreach (AnimatorControllerParameter val in parameters) { if (val.nameHash == hash && val.type == type) { return true; } } return false; } 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(2294735284u, new RpcReceiveHandler(__rpc_handler_2294735284), "PlayIdleClientRpc"); ((NetworkBehaviour)this).__registerRpc(643380925u, new RpcReceiveHandler(__rpc_handler_643380925), "PlayAlarmClientRpc"); ((NetworkBehaviour)this).__registerRpc(4194604744u, new RpcReceiveHandler(__rpc_handler_4194604744), "StopMusicClientRpc"); ((NetworkBehaviour)this).__registerRpc(1244013670u, new RpcReceiveHandler(__rpc_handler_1244013670), "PlayHitClientRpc"); ((NetworkBehaviour)this).__registerRpc(2758446597u, new RpcReceiveHandler(__rpc_handler_2758446597), "PlayDeathClientRpc"); ((EnemyAI)this).__initializeRpcs(); } private static void __rpc_handler_2294735284(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_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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int clipIndex = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref clipIndex); bool warningRamp = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref warningRamp, default(ForPrimitives)); float phase = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref phase, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((HarmonicAI)(object)target).PlayIdleClientRpc(clipIndex, warningRamp, phase); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_643380925(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { float phase = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref phase, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((HarmonicAI)(object)target).PlayAlarmClientRpc(phase); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_4194604744(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; ((HarmonicAI)(object)target).StopMusicClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1244013670(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_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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int clipIndex = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref clipIndex); float pitch = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref pitch, default(ForPrimitives)); float inflateAmount = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref inflateAmount, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((HarmonicAI)(object)target).PlayHitClientRpc(clipIndex, pitch, inflateAmount); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2758446597(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //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_005c: 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) { Vector3 effectPosition = default(Vector3); ((FastBufferReader)(ref reader)).ReadValueSafe(ref effectPosition); float fatalInflateAmount = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref fatalInflateAmount, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((HarmonicAI)(object)target).PlayDeathClientRpc(effectPosition, fatalInflateAmount); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "HarmonicAI"; } } } 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 Y4NGZHarmonic.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }