using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EnhancedMonsters.Config; using EnhancedMonsters.Monobehaviours; using EnhancedMonsters.NetcodePatcher; using EnhancedMonsters.Networking; using EnhancedMonsters.Patches; using EnhancedMonsters.Utils; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalLib.Modules; using LethalSettings.UI; using LethalSettings.UI.Components; using MelanieMeliciousCooked; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using TMPro; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyFileVersion("1.4.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 EnhancedMonsters { [BepInPlugin("com.velddev.enhancedmonsters", "Enhanced Monsters", "1.4.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("Entity378.sellbodies")] public class Plugin : BaseUnityPlugin { private static readonly Harmony harmony = new Harmony("com.velddev.enhancedmonsters"); [NotNull] public static ManualLogSource? logger; internal static Plugin Singleton { [return: NotNull] get; private set; } public static GameObject EnemyToPropPrefab { get; private set; } public static GameObject NetworkHandlerPrefab { get; private set; } private void Awake() { Singleton = this; logger = ((BaseUnityPlugin)this).Logger; new LocalConfig(((BaseUnityPlugin)this).Config); logger.LogInfo((object)"Local config initialized."); logger.LogInfo((object)"This is (maybe) NOT an RPG mod. And hi btw."); EnemiesDataManager.LoadEnemiesData(); new SyncedConfig(((BaseUnityPlugin)this).Config); logger.LogInfo((object)"Enemies data loaded and ready to be synchronized."); ApplyAllPatches(); logger.LogDebug((object)"All harmony patches have been applied (energistics)."); CreateThePrefab(); logger.LogDebug((object)"The Prefab have been created correctly"); CreateNetworkHandlerPrefab(); logger.LogDebug((object)"EnhancedMonstersNetworkHandler network prefab registered"); if ((Object)(object)FastResourcesManager.EnemyScrapIcon == (Object)null) { logger.LogError((object)"EnemyScrapIcon didn't load yet. Caution advised."); } else { logger.LogInfo((object)"EnemyScrapIcon loaded correctly and is ready to use !"); } } private static void ApplyAllPatches() { if (logger == null) { throw new NullReferenceException("logger is null. Cannot process further because it means that the mod was not initialized yet."); } logger.LogDebug((object)"Applying patches..."); harmony.PatchAll(typeof(EnemyAI_Patches)); harmony.PatchAll(typeof(MenuManager_Patches)); harmony.PatchAll(typeof(PlayerControllerB_Patches)); harmony.PatchAll(typeof(GameNetworkManager_Patches)); harmony.PatchAll(typeof(StartOfRound_Patches)); logger.LogDebug((object)"All Harmony patches applied."); } private static void CreateThePrefab() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) GameObject val = NetworkPrefabs.CreateNetworkPrefab("EnemyAsProp"); val.tag = "PhysicsProp"; val.layer = 6; NetworkObject component = val.GetComponent(); component.AutoObjectParentSync = false; component.DontDestroyWithOwner = true; BoxCollider val2 = val.AddComponent(); ((Collider)val2).enabled = true; ((Collider)val2).isTrigger = true; val2.size = new Vector3(1.5f, 1.5f, 1.5f); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); NetworkPrefabs.RegisterNetworkPrefab(val); EnemyToPropPrefab = val; } private static void CreateNetworkHandlerPrefab() { GameObject val = NetworkPrefabs.CreateNetworkPrefab("EnhancedMonstersNetworkHandler"); NetworkObject component = val.GetComponent(); component.AutoObjectParentSync = false; component.DontDestroyWithOwner = true; val.AddComponent(); NetworkPrefabs.RegisterNetworkPrefab(val); NetworkHandlerPrefab = val; } } public static class PluginInfo { public const int ConfigVersion = 11; public const string Version = "1.4.0"; public const string GUID = "com.velddev.enhancedmonsters"; public const string DisplayName = "Enhanced Monsters"; } } namespace EnhancedMonsters.Utils { public static class EnemiesDataManager { [JsonObject] public class EnemyDataFile { public int Version { get; set; } public Dictionary EnemiesData { get; set; } [JsonConstructor] public EnemyDataFile(int version, Dictionary enemiesData) { Version = version; EnemiesData = enemiesData ?? new Dictionary(); base..ctor(); } } public static readonly Dictionary EnemiesData = new Dictionary(); public static readonly Dictionary DefaultEnemiesData = new Dictionary { ["Manticoil"] = new EnemyData(pickupable: true, 10, 20, 12f, "F", new EnemyData.EnemyMetadata(new Vec3(-0.25f, 0.25f, 0.15f), new Vec3(180f, 0f, -90f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)), ["Tulip Snake"] = new EnemyData(pickupable: true, 20, 30, 7f, "F", new EnemyData.EnemyMetadata(new Vec3(-0.15f, 0.1f, 0.11f), new Vec3(0f, 90f, 90f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)), ["Hoarding bug"] = new EnemyData(pickupable: true, 55, 90, 50f, "E", new EnemyData.EnemyMetadata(new Vec3(0.1f, 0.2f, -0.3f), new Vec3(0f, 0f, 90f), new Vec3(0f, 0f, 0f))), ["Puffer"] = new EnemyData(pickupable: true, 30, 60, 69f, "E", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))), ["Centipede"] = new EnemyData(pickupable: true, 45, 70, 35f, "D", new EnemyData.EnemyMetadata(new Vec3(-0.25f, 0.1f, 0f), new Vec3(0f, 0f, -90f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)), ["Baboon hawk"] = new EnemyData(pickupable: true, 75, 100, 105f, "D", new EnemyData.EnemyMetadata(new Vec3(-0.3f, 0.5f, 1.5f), new Vec3(0f, 0f, 90f), new Vec3(0f, 0f, 0f))), ["Bunker Spider"] = new EnemyData(pickupable: true, 70, 110, 75f, "C", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))), ["MouthDog"] = new EnemyData(pickupable: true, 175, 250, 250f, "C", new EnemyData.EnemyMetadata(new Vec3(-1.25f, -1f, -0.5f), new Vec3(180f, 0f, -90f), new Vec3(180f, 0f, 180f))), ["Crawler"] = new EnemyData(pickupable: true, 120, 160, 100f, "B", new EnemyData.EnemyMetadata(new Vec3(-0.5f, 0f, -1f), new Vec3(0f, 0f, -60f), new Vec3(0f, 0f, 0f))), ["Flowerman"] = new EnemyData(pickupable: true, 160, 190, 40f, "B", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 1.5f), new Vec3(0f, 90f, -90f), new Vec3(-90f, 0f, 0f), animateOnDeath: false)), ["Butler"] = new EnemyData(pickupable: true, 170, 199, 77f, "B", new EnemyData.EnemyMetadata(new Vec3(-0.5f, 0f, 1f), new Vec3(0f, 90f, -90f), new Vec3(-90f, 0f, 0f), animateOnDeath: false)), ["Nutcracker"] = new EnemyData(pickupable: true, 190, 220, 43f, "A", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 1.5f), new Vec3(0f, 90f, -90f), new Vec3(-90f, 0f, 0f), animateOnDeath: false)), ["Maneater"] = new EnemyData(pickupable: true, 250, 290, 42f, "S", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)), ["Docile Locust Bees"] = new EnemyData(pickupable: false, 0, 0, 0f, "F", new EnemyData.EnemyMetadata()), ["Red pill"] = new EnemyData(pickupable: false, 0, 0, 0f, "F", new EnemyData.EnemyMetadata()), ["Blob"] = new EnemyData(pickupable: false, 0, 0, 0f, "D", new EnemyData.EnemyMetadata()), ["Red Locust Bees"] = new EnemyData(pickupable: false, 0, 0, 0f, "C", new EnemyData.EnemyMetadata()), ["Butler Bees"] = new EnemyData(pickupable: false, 0, 0, 0f, "C", new EnemyData.EnemyMetadata()), ["Earth Leviathan"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()), ["Masked"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()), ["Clay Surgeon"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()), ["Spring"] = new EnemyData(pickupable: false, 0, 0, 0f, "A", new EnemyData.EnemyMetadata()), ["Jester"] = new EnemyData(pickupable: false, 0, 0, 0f, "S+", new EnemyData.EnemyMetadata()), ["RadMech"] = new EnemyData(pickupable: false, 0, 0, 0f, "S+", new EnemyData.EnemyMetadata()), ["Girl"] = new EnemyData(pickupable: false, 0, 0, 0f, "?", new EnemyData.EnemyMetadata()), ["Lasso"] = new EnemyData(pickupable: false, 0, 0, 0f, "dont exist haha", new EnemyData.EnemyMetadata()), ["ForestGiant"] = new EnemyData(pickupable: false, 0, 0, 0f, "S", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 90f, 0f), new Vec3(90f, 0f, 0f), animateOnDeath: false)), ["PinkGiant"] = new EnemyData(pickupable: false, 0, 0, 0f, "F", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 90f, 0f), new Vec3(0f, 0f, 0f), animateOnDeath: false)), ["Football"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()), ["Locker"] = new EnemyData(pickupable: false, 0, 0, 0f, "A", new EnemyData.EnemyMetadata()), ["Bush Wolf"] = new EnemyData(pickupable: true, 250, 320, 51f, "A", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))), ["PjonkGoose"] = new EnemyData(pickupable: true, 279, 340, 64f, "A", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))) }; public static string EnemiesDataFile = Path.Combine(Paths.ConfigPath, "EnhancedMonsters", "EnemiesData.json"); public static readonly Dictionary Enemies2Props = new Dictionary(); public static readonly List AllEnemiesScraps = new List(); public static void LoadEnemiesData() { if (!File.Exists(EnemiesDataFile)) { Plugin.logger.LogWarning((object)"Enemy Data File did not exist!"); EnemiesData.ProperConcat(DefaultEnemiesData); SaveEnemiesData(); return; } string text = File.ReadAllText(EnemiesDataFile); Plugin.logger.LogDebug((object)text); EnemyDataFile enemyDataFile = JsonConvert.DeserializeObject(text); if (enemyDataFile == null) { Plugin.logger.LogWarning((object)"Enemy Data File seems to be empty or invalid."); EnemiesData.ProperConcat(DefaultEnemiesData); SaveEnemiesData(); } else if (checked(11 - enemyDataFile.Version) > 1) { Plugin.logger.LogWarning((object)"Enemy Data File seems to be outdated. A new config file will be created."); EnemiesData.ProperConcat(DefaultEnemiesData); string text2 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "..", "config", "EnhancedMonsters", "OLD_EnemiesData.json"); if (File.Exists(text2)) { File.Delete(text2); } File.Move(EnemiesDataFile, text2); SaveEnemiesData(); } else { EnemiesData.ProperConcat(enemyDataFile.EnemiesData); Plugin.logger.LogDebug((object)$"{enemyDataFile} => {EnemiesData.Count}"); EnemiesData.ProperConcat(DefaultEnemiesData); Plugin.logger.LogDebug((object)$"{DefaultEnemiesData.Count} => {EnemiesData.Count}"); SaveEnemiesData(); } } public static void RegisterEnemy(string enemyName, bool sellable, int minPrice, int maxPrice, float mass, string rank, EnemyData.EnemyMetadata metadata, bool overrideRegister = false) { if (!EnemiesData.ContainsKey(enemyName)) { EnemiesData.Add(enemyName, new EnemyData(sellable, minPrice, maxPrice, mass, rank, metadata)); } else { if (!overrideRegister) { string name = Assembly.GetCallingAssembly().GetName().Name; Plugin.logger.LogWarning((object)("Cannot register modded from mod " + name + " enemy " + enemyName + ": It is already registered (either from file or from .")); return; } EnemiesData[enemyName] = new EnemyData(sellable, minPrice, maxPrice, mass, rank, metadata); } if (SyncedConfig.Instance == null || SyncedConfig.IsHost || !NetworkManager.Singleton.IsListening) { SyncedConfig.BroadcastSync(); } } internal static void RegisterEnemy(string enemyName, EnemyData enemyData) { if (SyncedConfig.IsHost || !NetworkManager.Singleton.IsListening) { if (EnemiesData != SyncedConfig.Instance.EnemiesData) { Plugin.logger.LogError((object)"Cannot update the mob configs. Somehow, the EnemiesData from the EnemiesDataManager and the one from the SyncedConfigs are not the same, even though they both are yours."); } else if (!EnemiesData.TryAdd(enemyName, enemyData)) { Plugin.logger.LogDebug((object)("EnemyData '" + enemyName + "' already exists!")); } else { SyncedConfig.BroadcastSync(); } } } public static void SaveEnemiesData() { if (!SyncedConfig.IsHost) { NetworkManager singleton = NetworkManager.Singleton; if (singleton != null && singleton.IsListening) { return; } } EnemyDataFile enemyDataFile = new EnemyDataFile(11, EnemiesData); string contents = JsonConvert.SerializeObject((object)enemyDataFile, (Formatting)1); if (!Directory.Exists(Path.GetDirectoryName(EnemiesDataFile))) { Directory.CreateDirectory(Path.GetDirectoryName(EnemiesDataFile)); } File.WriteAllText(EnemiesDataFile, contents); Plugin.logger.LogInfo((object)"Saved enemies data."); } public static void ScanAndRegisterUnknownEnemies() { EnemyAI[] array = Resources.FindObjectsOfTypeAll(); Plugin.logger.LogInfo((object)$"Scanning {array.Length} enemies for unknown entries"); EnemyAI[] array2 = array; foreach (EnemyAI val in array2) { if (val == null) { Plugin.logger.LogWarning((object)"An enemy is null!"); } else if (val.enemyType == null) { Plugin.logger.LogWarning((object)(((Object)val).name + " has a null enemyType (tf?)")); } else if (!SyncedConfig.Instance.EnemiesData.ContainsKey(val.enemyType.enemyName)) { RegisterEnemy(val.enemyType.enemyName, new EnemyData(pickupable: true, 80, 250, 50f, "E", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f)))); Plugin.logger.LogInfo((object)("Mob was not registered. Registered it with name '" + val.enemyType.enemyName + "'")); } } SaveEnemiesData(); } public static void EnsureEnemy2PropPrefabs() { EnemyAI[] array = Resources.FindObjectsOfTypeAll(); EnemyAI[] array2 = array; foreach (EnemyAI val in array2) { if ((Object)(object)val.enemyType == (Object)null) { Plugin.logger.LogWarning((object)("Entity " + ((Object)val).name + " have been skipped: This entity lacks an EnemyType !")); continue; } string enemyName = val.enemyType.enemyName; Plugin.logger.LogInfo((object)("Ensuring NetworkPrefab '" + enemyName + "'")); if (!TryUpdateExistingPrefab(val, enemyName) && SyncedConfig.Instance.EnemiesData.TryGetValue(enemyName, out var value) && value.Pickupable) { GameObject visual = BuildVisualCopy(val); GameObject val2 = BuildScrapPrefab(val, enemyName, visual, value); if (!((Object)(object)val2 == (Object)null)) { ScanNodeProperties componentInChildren = val2.GetComponentInChildren(); Item enemyItem = BuildItemScriptable(enemyName, value, val2, componentInChildren); RegisterPrefabAndItem(enemyName, val2, enemyItem); } } } if (FarmingAndCookingSupport.FarmingAndCookingLoaded) { FarmingAndCookingSupport.RegisterFarmingAndCookingBodies(AllEnemiesScraps); } } private static bool TryUpdateExistingPrefab(EnemyAI enemy, string enemyName) { if (!Enemies2Props.TryGetValue(enemyName, out GameObject value)) { return false; } EnemyData enemyData = SyncedConfig.Instance.EnemiesData[enemyName]; if (!enemyData.Pickupable) { Enemies2Props.Remove(enemyName); return true; } EnemyScrap component = value.GetComponent(); component.enemyType = enemy.enemyType; ((GrabbableObject)component).itemProperties.minValue = enemyData.MinValue; ((GrabbableObject)component).itemProperties.maxValue = enemyData.MaxValue; ((GrabbableObject)component).itemProperties.weight = enemyData.LCMass; return true; } private static GameObject BuildVisualCopy(EnemyAI enemy) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(((Object)enemy).name + " neutralized"); foreach (Transform item in ((Component)enemy).transform) { Transform val2 = item; if (!((Object)val2).name.StartsWith("MapDot") && !((Object)val2).name.StartsWith("Collider") && !((Object)val2).name.StartsWith("VoiceSFX") && !((Object)val2).name.StartsWith("CreatureSFX") && !((Object)val2).name.StartsWith("SeepingSFX") && !((Object)val2).name.StartsWith("CreatureVoice") && !((Object)val2).name.StartsWith("Ambience")) { Transform val3 = Object.Instantiate(val2); ((Object)val3).name = ((Object)val2).name; ((Component)val3).transform.parent = val.transform; } } val.RemoveComponentsInChildren(); val.RemoveComponentsInChildren(); val.RemoveComponentsInChildren(); val.RemoveComponentsInChildren(); val.RemoveComponentsInChildren(); val.RemoveComponentsInChildren(); val.RemoveComponentsInChildren(); val.RemoveComponentsInChildren(); val.transform.localScale = ((Component)enemy).transform.localScale; return val; } private static GameObject BuildScrapPrefab(EnemyAI enemy, string enemyName, GameObject visual, EnemyData enemyData) { //IL_00a1: 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) GameObject val = NetworkPrefabs.CloneNetworkPrefab(Plugin.EnemyToPropPrefab, "Dead " + enemyName); visual.transform.parent = val.transform; Plugin.logger.LogInfo((object)("Attached " + ((Object)visual).name + " to " + ((Object)visual.transform.parent).name)); EnemyScrap component = val.GetComponent(); component.EnemyGameObject = visual; CleanEnemyObj(component.EnemyGameObject); ((GrabbableObject)component).grabbable = true; ((GrabbableObject)component).grabbableToEnemies = false; component.enemyType = enemy.enemyType; BoxCollider component2 = val.GetComponent(); component2.size = enemyData.Metadata.CollisionExtents; if (enemyName == "Bunker Spider") { val.AddComponent(); } ScanNodeProperties componentInChildren = visual.GetComponentInChildren(); if (!Object.op_Implicit((Object)(object)componentInChildren)) { Plugin.logger.LogWarning((object)("Enemy '" + enemyName + "' has no ScanNodeProperties; corpse cannot be networked-scanned. Discarding scrap prefab.")); Object.Destroy((Object)(object)val); return null; } Transform transform = ((Component)componentInChildren).gameObject.transform; ((Component)transform).transform.parent = val.transform; ((Component)transform).gameObject.AddComponent(); transform.localPosition = new Vector3(0f, 0f, 0f); componentInChildren.maxRange = 13; componentInChildren.minRange = 1; componentInChildren.nodeType = 2; componentInChildren.requiresLineOfSight = true; componentInChildren.headerText = "Dead " + componentInChildren.headerText; return val; } private static Item BuildItemScriptable(string enemyName, EnemyData enemyData, GameObject scrapPrefab, ScanNodeProperties scanNodeProperties) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00ee: 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) Item val = ScriptableObject.CreateInstance(); EnemyScrap component = scrapPrefab.GetComponent(); ((GrabbableObject)component).itemProperties = val; ((Object)val).name = enemyName + " scrap"; val.itemName = scanNodeProperties.headerText; val.saveItemVariable = true; val.itemIcon = FastResourcesManager.EnemyScrapIcon; val.minValue = enemyData.MinValue; val.maxValue = enemyData.MaxValue; val.allowDroppingAheadOfPlayer = true; val.canBeGrabbedBeforeGameStart = true; val.isScrap = true; val.itemSpawnsOnGround = false; val.twoHanded = enemyData.Metadata.TwoHanded; val.requiresBattery = false; val.twoHandedAnimation = enemyData.Metadata.TwoHanded; val.weight = enemyData.LCMass; val.spawnPrefab = scrapPrefab; val.restingRotation = enemyData.Metadata.FloorRotation; val.rotationOffset = enemyData.Metadata.HandRotation; val.positionOffset = enemyData.Metadata.MeshOffset; EnemyData enemyData2 = SyncedConfig.Default.EnemiesData[enemyName]; val.dropSFX = ResolveSfx(enemyData2.Metadata.DropSFX); val.grabSFX = ResolveSfx(enemyData2.Metadata.GrabSFX); val.pocketSFX = ResolveSfx(enemyData2.Metadata.PocketSFX); return val; } private static AudioClip ResolveSfx(string sfxKey) { if (string.IsNullOrEmpty(sfxKey) || sfxKey == "none") { return null; } if (sfxKey == "default") { return FastResourcesManager.EnemyDropDefaultSound; } if (FastResourcesManager.CustomAudioClips.TryGetValue(sfxKey, out AudioClip value)) { return value; } Plugin.logger.LogWarning((object)("Custom SFX '" + sfxKey + "' not found in CustomAudioClips. Using default. (File missing or coroutine still running?)")); return FastResourcesManager.EnemyDropDefaultSound; } private static void RegisterPrefabAndItem(string enemyName, GameObject scrapPrefab, Item enemyItem) { NetworkPrefabs.RegisterNetworkPrefab(scrapPrefab); NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && !singleton.NetworkConfig.Prefabs.Contains(scrapPrefab)) { singleton.AddNetworkPrefab(scrapPrefab); } Items.RegisterItem(enemyItem); Items.RegisterScrap(enemyItem, 0, (LevelTypes)1); AllEnemiesScraps.Add(enemyItem); Enemies2Props.Add(enemyName, scrapPrefab); Plugin.logger.LogInfo((object)("Registered NetworkPrefab '" + ((Object)scrapPrefab).name + "' (" + enemyItem.itemName + ")")); } public static void CleanEnemyObj(GameObject enemyObj) { //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown try { if (((Object)enemyObj).name.Contains("SandSpider")) { return; } int num = (Object.op_Implicit((Object)(object)Camera.main) ? Camera.main.cullingMask : 591075327); Renderer[] componentsInChildren = enemyObj.GetComponentsInChildren(true); Animator component = enemyObj.GetComponent(); if ((Object)(object)component != (Object)null) { component.Update(0f); } Plugin.logger.LogInfo((object)("Starting cleanup on '" + ((Object)enemyObj).name + "'")); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { bool enabled = val.enabled; bool flag = ((1 << ((Component)val).gameObject.layer) & num) != 0; if (!enabled || !flag) { Plugin.logger.LogInfo((object)("Removing renderer '" + ((Object)val).name + "' from '" + ((Object)enemyObj).name + "'")); Object.DestroyImmediate((Object)(object)val); } SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); if (val2 != null) { Mesh val3 = new Mesh(); val2.BakeMesh(val3); } } } Plugin.logger.LogInfo((object)("Cleanup completed on '" + ((Object)enemyObj).name + "'")); } catch (Exception arg) { Plugin.logger.LogError((object)$"ERROR cleaning '{((Object)enemyObj).name}': {arg}"); } } } [Serializable] [JsonObject(Description = "The value of a mob once killed, if it can be killed.")] public record struct EnemyData { [Serializable] [JsonObject(Description = "The metadata of a mob once killed, if it can be killed.")] public record struct EnemyMetadata { public Vec3 MeshOffset; public Vec3 HandRotation; public Vec3 FloorRotation; public Vec3 CollisionExtents; public bool AnimateOnDeath; public bool TwoHanded; public string DropSFX; public string GrabSFX; public string PocketSFX; public Dictionary LootTable; [JsonConstructor] public EnemyMetadata() { DropSFX = "default"; GrabSFX = "none"; PocketSFX = "none"; MeshOffset = default(Vec3); HandRotation = default(Vec3); FloorRotation = default(Vec3); CollisionExtents = new Vec3(1.5f, 1.5f, 1.5f); AnimateOnDeath = false; TwoHanded = true; DropSFX = "default"; GrabSFX = "none"; PocketSFX = "none"; LootTable = new Dictionary(); } public EnemyMetadata(Vec3 meshOffset = default(Vec3), Vec3 handRotation = default(Vec3), Vec3 floorRotation = default(Vec3), bool animateOnDeath = true, bool twoHanded = true, Dictionary? loots = null, string dropsfx = "default", string grabsfx = "none", string pocketsfx = "none", Vec3? collisionSize = null) { DropSFX = "default"; GrabSFX = "none"; PocketSFX = "none"; MeshOffset = meshOffset; HandRotation = handRotation; FloorRotation = floorRotation; CollisionExtents = collisionSize ?? new Vec3(1.5f, 1.5f, 1.5f); AnimateOnDeath = animateOnDeath; TwoHanded = twoHanded; DropSFX = dropsfx; GrabSFX = grabsfx; PocketSFX = pocketsfx; LootTable = loots ?? new Dictionary(); } } [JsonIgnore] public readonly float LCMass => Mass / 105f + 1f; public bool Pickupable; public int MinValue; public int MaxValue; public float Mass; public string Rank; public EnemyMetadata Metadata; [JsonConstructor] public EnemyData() { Pickupable = true; MinValue = 80; MaxValue = 110; Mass = 50f; Rank = "C"; Metadata = new EnemyMetadata(); } public EnemyData(bool pickupable = true, int minValue = 80, int maxValue = 250, float mass = 50f, string rank = "E", EnemyMetadata? metadata = null) { Pickupable = pickupable; MinValue = minValue; MaxValue = maxValue; Mass = mass; Rank = rank; Metadata = metadata ?? new EnemyMetadata(); } [CompilerGenerated] private readonly bool PrintMembers(StringBuilder builder) { builder.Append("Pickupable = "); builder.Append(Pickupable.ToString()); builder.Append(", MinValue = "); builder.Append(MinValue.ToString()); builder.Append(", MaxValue = "); builder.Append(MaxValue.ToString()); builder.Append(", Mass = "); builder.Append(Mass.ToString()); builder.Append(", Rank = "); builder.Append((object?)Rank); builder.Append(", Metadata = "); builder.Append(Metadata.ToString()); builder.Append(", LCMass = "); builder.Append(LCMass.ToString()); return true; } } [Serializable] [JsonObject(Description = "A simple and flexible Vector3 structure.")] public record struct Vec3 { public float X; public float Y; public float Z; [JsonConstructor] public Vec3(float x, float y, float z) { Z = 0f; X = x; Y = y; Z = z; } public static implicit operator Vector3(Vec3 v) { return new Vector3(v.X, v.Y, v.Z); } public static implicit operator Vector3(Vec3 v) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(v.X, v.Y, v.Z); } public static implicit operator Vec3(Vector3 v) { return new Vec3(v.X, v.Y, v.Z); } public static implicit operator Vec3(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new Vec3(v.x, v.y, v.z); } public static Vec3 operator *(Vec3 l, float r) { return new Vec3(l.X * r, l.Y * r, l.Z * r); } public static Vec3 operator *(Vec3 l, Vec3 r) { return new Vec3(l.X * r.X, l.Y * r.Y, l.Z * r.Z); } public static Vec3 operator /(Vec3 l, float r) { return new Vec3(l.X / r, l.Y / r, l.Z / r); } public static Vec3 operator /(Vec3 l, Vec3 r) { return new Vec3(l.X / r.X, l.Y / r.Y, l.Z / r.Z); } public static Vec3 operator +(Vec3 l, Vec3 r) { return new Vec3(l.X + r.X, l.Y + r.Y, l.Z + r.Z); } public static Vec3 operator -(Vec3 l, Vec3 r) { return new Vec3(l.X - r.X, l.Y - r.Y, l.Z - r.Z); } public static Vec3 operator -(Vec3 s) { return new Vec3(0f - s.X, 0f - s.Y, 0f - s.Z); } public static float operator ~(Vec3 l) { return l.Length(); } public readonly float Length() { return (float)Math.Sqrt(Math.Pow(X, 2.0) + Math.Pow(Y, 2.0) + Math.Pow(Z, 2.0)); } public readonly void Deconstruct(out float x, out float y, out float z) { x = X; y = Y; z = Z; } public readonly void Deconstruct(out float x, out float y) { x = X; y = Y; } } internal static class FarmingAndCookingSupport { private const string FarmingAndCookingGuid = "MelanieMelicious.FarmAndCook"; private static bool? farmingAndCookingLoaded; public static bool FarmingAndCookingLoaded { get { bool valueOrDefault = farmingAndCookingLoaded.GetValueOrDefault(); if (!farmingAndCookingLoaded.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("MelanieMelicious.FarmAndCook"); farmingAndCookingLoaded = valueOrDefault; } return farmingAndCookingLoaded.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void RegisterFarmingAndCookingBodies(List bodies) { foreach (Item body in bodies) { Plugin.bodyHash.Add(body); Plugin.logger.LogDebug((object)("Registered " + body.itemName + " for MelanieMeliciousCooked plugin.")); } Plugin.logger.LogInfo((object)"Successfully registered all the corpses as grindable for the Farming & Cooking mod."); } } internal static class FastResourcesManager { public static AssetBundle Resources; public static readonly Dictionary CustomAudioClips; public static Sprite EnemyScrapIcon { get; private set; } public static AudioClip EnemyDropDefaultSound { get; private set; } public static string CustomSoundsFolder => Path.Combine(Paths.ConfigPath, "EnhancedMonsters", "CustomSFX"); static FastResourcesManager() { CustomAudioClips = new Dictionary(); string name = Assembly.GetExecutingAssembly().GetManifestResourceNames()[0]; Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name); Resources = AssetBundle.LoadFromStream(manifestResourceStream); EnemyScrapIcon = Resources.LoadAsset("EnemyScrapItemIcon"); EnemyDropDefaultSound = Resources.LoadAsset("BodyDrop"); LoadCustomSounds(); } private static void LoadCustomSounds() { if (!Directory.Exists(CustomSoundsFolder)) { Directory.CreateDirectory(CustomSoundsFolder); Plugin.logger.LogInfo((object)("CustomSFX folder didn't exist, created at " + CustomSoundsFolder)); } string[] files = Directory.GetFiles(CustomSoundsFolder, "*.wav", SearchOption.TopDirectoryOnly); int num = 0; string[] array = files; foreach (string text in array) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); if (fileNameWithoutExtension == "default" || fileNameWithoutExtension == "none") { Plugin.logger.LogWarning((object)("Skipping '" + Path.GetFileName(text) + "': '" + fileNameWithoutExtension + "' is a reserved SFX key.")); continue; } if (CustomAudioClips.ContainsKey(fileNameWithoutExtension)) { Plugin.logger.LogWarning((object)("Skipping '" + Path.GetFileName(text) + "': key '" + fileNameWithoutExtension + "' already loaded.")); continue; } try { AudioClip value = LoadWav(text, fileNameWithoutExtension); CustomAudioClips[fileNameWithoutExtension] = value; num = checked(num + 1); Plugin.logger.LogInfo((object)("Loaded custom SFX '" + fileNameWithoutExtension + "' from " + Path.GetFileName(text))); } catch (Exception ex) { Plugin.logger.LogError((object)("Failed to load '" + Path.GetFileName(text) + "': " + ex.Message)); } } Plugin.logger.LogInfo((object)$"CustomSFX loading complete: {num} clip(s) loaded from {CustomSoundsFolder}"); } private static AudioClip LoadWav(string filePath, string key) { using FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); using BinaryReader binaryReader = new BinaryReader(fileStream); if (FourCC(binaryReader) != "RIFF") { throw new InvalidDataException("Not a RIFF file"); } binaryReader.ReadInt32(); if (FourCC(binaryReader) != "WAVE") { throw new InvalidDataException("Not a WAVE file"); } short num = 0; short num2 = 0; int num3 = 0; short num4 = 0; byte[] array = null; checked { while (fileStream.Position < fileStream.Length) { string text = FourCC(binaryReader); int num5 = binaryReader.ReadInt32(); if (text == "fmt ") { num = binaryReader.ReadInt16(); num2 = binaryReader.ReadInt16(); num3 = binaryReader.ReadInt32(); binaryReader.ReadInt32(); binaryReader.ReadInt16(); num4 = binaryReader.ReadInt16(); int num6 = 16; if ((ushort)num == 65534 && num5 >= 40) { binaryReader.ReadInt16(); binaryReader.ReadInt16(); binaryReader.ReadInt32(); byte[] value = binaryReader.ReadBytes(16); num6 += 24; switch (BitConverter.ToInt32(value, 0)) { case 1: num = 1; break; case 3: num = 3; break; } } if (num5 > num6) { fileStream.Seek(num5 - num6, SeekOrigin.Current); } } else { if (text == "data") { array = binaryReader.ReadBytes(num5); break; } fileStream.Seek(num5, SeekOrigin.Current); } } if (array == null) { throw new InvalidDataException("No 'data' chunk found"); } } float[] array2; if (num == 1 && num4 == 16) { int num7 = array.Length / 2; array2 = new float[num7]; checked { for (int i = 0; i < num7; i++) { short num8 = (short)(array[i * 2] | (array[i * 2 + 1] << 8)); array2[i] = (float)num8 / 32768f; } } } else if (num == 1 && num4 == 24) { int num9 = array.Length / 3; array2 = new float[num9]; for (int j = 0; j < num9; j = checked(j + 1)) { int num10 = checked(array[j * 3] | (array[j * 3 + 1] << 8) | (array[j * 3 + 2] << 16)); if (((uint)num10 & 0x800000u) != 0) { num10 |= -16777216; } array2[j] = (float)num10 / 8388608f; } } else if (num == 1 && num4 == 32) { int num11 = array.Length / 4; array2 = new float[num11]; checked { for (int k = 0; k < num11; k++) { int num12 = array[k * 4] | (array[k * 4 + 1] << 8) | (array[k * 4 + 2] << 16) | (array[k * 4 + 3] << 24); array2[k] = (float)num12 / 2.1474836E+09f; } } } else { if (num != 3 || num4 != 32) { throw new InvalidDataException($"Unsupported WAV format (format={num}, bits={num4}). Use 16/24/32-bit PCM or 32-bit IEEE float."); } int num13 = array.Length / 4; array2 = new float[num13]; Buffer.BlockCopy(array, 0, array2, 0, array.Length); } int num14 = array2.Length / num2; AudioClip val = AudioClip.Create("EM_CSFX_" + key, num14, (int)num2, num3, false); val.SetData(array2, 0); return val; } private static string FourCC(BinaryReader reader) { return Encoding.ASCII.GetString(reader.ReadBytes(4)); } } internal static class KnownEnemies { public const string BunkerSpider = "Bunker Spider"; public const string Flowerman = "Flowerman"; public const string SandSpider = "SandSpider"; public const string Maneater = "Maneater"; } public static class Utility { public const float KgToLb = 2.2046227f; public static string ToStringObj(this object obj, string prefix = "") { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(prefix + obj.GetType().FullName + ": {"); FieldInfo[] fields = obj.GetType().GetFields(); foreach (FieldInfo fieldInfo in fields) { object arg = fieldInfo.GetValue(obj) ?? null; stringBuilder.AppendLine(prefix + $"\t{fieldInfo.FieldType.Name} {fieldInfo.Name}: {arg}"); } stringBuilder.AppendLine(prefix + "}"); return stringBuilder.ToString(); } public static T EnsureComponent(this GameObject go) where T : Component { if (go == null) { throw new NullReferenceException("The gameObject is a null reference."); } T result = default(T); if (!go.TryGetComponent(ref result)) { return go.AddComponent(); } return result; } public static void AddRange(this IDictionary target, IEnumerable source, Func key, Func selector, bool set = true) { foreach (TI item in source) { K key2 = key(item); T value = selector(item); if (set) { target[key2] = value; } else { target.TryAdd(key(item), selector(item)); } } } public static void ProperConcat(this IDictionary target, IDictionary source) { foreach (KeyValuePair item in source) { if (!target.ContainsKey(item.Key)) { target.Add(item.Key, item.Value); } } } public static void RemoveComponentsInChildren(this GameObject go) where T : Component { T[] componentsInChildren = go.GetComponentsInChildren(); T[] array = componentsInChildren; foreach (T val in array) { Plugin.logger.LogDebug((object)("Destroying component " + ((object)val).GetType().Name + " on " + ((Object)(object)val).name + " (child of " + ((Object)go).name + ")")); Object.Destroy((Object)(object)val); } } internal static IEnumerable GetLoadableTypes(this Assembly assembly) { if (assembly == null) { throw new ArgumentNullException("assembly"); } try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type t) => t != null); } } } } namespace EnhancedMonsters.Patches { [HarmonyPatch(typeof(EnemyAI))] public class EnemyAI_Patches { [HarmonyPrefix] [HarmonyPatch(typeof(EnemyAI), "Start")] private static void Start(EnemyAI __instance) { if (__instance.enemyType == null) { return; } SyncedConfig syncedConfig = (LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance : SyncedConfig.Default); if (!syncedConfig.EnemiesData.TryGetValue(__instance.enemyType.enemyName, out var value)) { Plugin.logger.LogWarning((object)("Enemy " + __instance.enemyType.enemyName + " is not registered in the enemies data. Registering it now.")); value = new EnemyData(pickupable: true, 80, 250, 50f, "E", null); EnemiesDataManager.RegisterEnemy(__instance.enemyType.enemyName, value); } if (!(value.Rank == string.Empty)) { ScanNodeProperties componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.subText = "Rank " + value.Rank; } } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAI), "KillEnemy")] private static void KillEnemy(EnemyAI __instance, bool destroy) { //IL_017a: 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) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.enemyType == (Object)null) { return; } Plugin.logger.LogDebug((object)("Mob " + __instance.enemyType.enemyName + " died.")); if (destroy) { return; } if (!SyncedConfig.Instance.EnemiesData.ContainsKey(__instance.enemyType.enemyName)) { EnemiesDataManager.RegisterEnemy(__instance.enemyType.enemyName, new EnemyData(pickupable: true, 80, 250, 50f, "E", null)); Plugin.logger.LogInfo((object)("Mob was not registered. Registered it with name '" + __instance.enemyType.enemyName + "'")); } if (!NetworkManager.Singleton.IsServer) { return; } Plugin.logger.LogDebug((object)("Spawning EnemyScrap for enemy " + __instance.enemyType.enemyName + ".")); if (!EnemiesDataManager.Enemies2Props.TryGetValue(__instance.enemyType.enemyName, out GameObject value)) { Plugin.logger.LogWarning((object)("Mob " + __instance.enemyType.enemyName + " has no enemy2prop prefab.")); return; } GameObject val = Object.Instantiate(value); ((Object)val).hideFlags = (HideFlags)0; val.transform.position = ((Component)__instance).transform.position; val.GetComponent().Spawn(false); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(-10000f, -10000f, -10000f); ((Component)__instance).transform.position = val2; __instance.serverPosition = val2; NetworkObject component = ((Component)__instance).GetComponent(); EnhancedMonstersNetworkHandler instance = EnhancedMonstersNetworkHandler.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)component != (Object)null) { instance.HideOriginalEnemyBodyClientRpc(NetworkObjectReference.op_Implicit(component), val2); } else { Plugin.logger.LogWarning((object)"Network handler or enemy NetworkObject unavailable; falling back to SyncPositionToClients()"); __instance.SyncPositionToClients(); } Plugin.logger.LogDebug((object)"Mob should now be grabbable for all users."); } } [HarmonyPatch(typeof(GameNetworkManager))] internal class GameNetworkManager_Patches { [HarmonyPostfix] [HarmonyPatch("StartDisconnect")] public static void StartDisconnect() { SyncedConfig.RevertSync(); } } [HarmonyPatch(typeof(MenuManager))] public class MenuManager_Patches { [HarmonyPostfix] [HarmonyPatch(typeof(MenuManager), "Start")] private static void Start(MenuManager __instance) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)__instance)) { Plugin.logger.LogError((object)"MenuManager instance is null. Something might have booted too early."); return; } if (__instance.versionNumberText == null) { Plugin.logger.LogWarning((object)"It seems like the Version Number Text of main menu is missing, it's probably the first main menu iteration. Skipping this one."); return; } TextMeshProUGUI versionNumberText = __instance.versionNumberText; ((TMP_Text)versionNumberText).text = ((TMP_Text)versionNumberText).text + "\nEnhanced Monsters v1.4.0"; ((Component)__instance.versionNumberText).gameObject.GetComponent().sizeDelta = new Vector2(500f, 50f); EnemiesDataManager.ScanAndRegisterUnknownEnemies(); EnemiesDataManager.EnsureEnemy2PropPrefabs(); Plugin.logger.LogInfo((object)"All enemies have been patched correctly."); } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerB_Patches { [HarmonyPrefix] [HarmonyPatch("ConnectClientToPlayerObject")] public static void InitializeLocalPlayerPrefabs() { EnemiesDataManager.ScanAndRegisterUnknownEnemies(); EnemiesDataManager.EnsureEnemy2PropPrefabs(); } [HarmonyPostfix] [HarmonyPatch("ConnectClientToPlayerObject")] public static void InitializeLocalPlayer() { if (SyncedConfig.IsHost) { Plugin.logger.LogInfo((object)"Local player is host, no sync request needed"); } else { SyncedConfig.RequestSync(); } } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRound_Patches { [HarmonyPostfix] [HarmonyPatch("Start")] public static void StartPatch() { EnemiesDataManager.ScanAndRegisterUnknownEnemies(); EnemiesDataManager.EnsureEnemy2PropPrefabs(); if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && (Object)(object)Plugin.NetworkHandlerPrefab != (Object)null) { GameObject val = Object.Instantiate(Plugin.NetworkHandlerPrefab); val.GetComponent().Spawn(true); Plugin.logger.LogInfo((object)"EnhancedMonstersNetworkHandler spawned by server in StartOfRound"); } } } } namespace EnhancedMonsters.Networking { public class EnhancedMonstersNetworkHandler : NetworkBehaviour { public static EnhancedMonstersNetworkHandler Instance { get; private set; } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); Instance = this; if (((NetworkBehaviour)this).IsServer) { ConfigSyncService.Synced = true; } Plugin.logger.LogInfo((object)("EnhancedMonstersNetworkHandler spawned (" + (((NetworkBehaviour)this).IsServer ? "server" : "client") + ")")); } public override void OnNetworkDespawn() { ((NetworkBehaviour)this).OnNetworkDespawn(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } Plugin.logger.LogInfo((object)"EnhancedMonstersNetworkHandler despawned"); } [ServerRpc(RequireOwnership = false)] public void RequestConfigSyncServerRpc(ServerRpcParams serverRpcParams = default(ServerRpcParams)) { //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) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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_0153: 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)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3276370873u, serverRpcParams, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 3276370873u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (((NetworkBehaviour)this).IsServer) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; Plugin.logger.LogDebug((object)$"ConfigSync request received from client {senderClientId}"); byte[] array = ConfigSyncService.SerializeCurrent(); if (array.Length == 0) { Plugin.logger.LogError((object)"Aborting sync response: empty payload"); return; } ClientRpcParams val2 = default(ClientRpcParams); val2.Send = new ClientRpcSendParams { TargetClientIds = new ulong[1] { senderClientId } }; ClientRpcParams clientRpcParams = val2; ReceiveConfigSyncClientRpc(array, clientRpcParams); } } [ClientRpc] public void ReceiveConfigSyncClientRpc(byte[] data, ClientRpcParams clientRpcParams = default(ClientRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0088: 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) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00b2: 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)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2833577898u, clientRpcParams, (RpcDelivery)0); bool flag = data != null; ((FastBufferWriter)(ref val)).WriteValueSafe(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(data, default(ForPrimitives)); } ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2833577898u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; if (!((NetworkBehaviour)this).IsServer) { Plugin.logger.LogInfo((object)$"Received config sync via ClientRpc, {((data != null) ? data.Length : 0)} bytes"); ConfigSyncService.ApplyReceivedSync(data); } } } [ClientRpc] public void BroadcastConfigSyncClientRpc(byte[] data) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0088: 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) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00b2: 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)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(149726897u, val, (RpcDelivery)0); bool flag = data != null; ((FastBufferWriter)(ref val2)).WriteValueSafe(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(data, default(ForPrimitives)); } ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 149726897u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; if (!((NetworkBehaviour)this).IsServer) { Plugin.logger.LogInfo((object)$"Received config broadcast via ClientRpc, {((data != null) ? data.Length : 0)} bytes"); ConfigSyncService.ApplyReceivedSync(data); } } } [ClientRpc] public void HideOriginalEnemyBodyClientRpc(NetworkObjectReference originalEnemyRef, Vector3 hidePosition) { //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_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_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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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_0143: 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)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1086037223u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref originalEnemyRef, default(ForNetworkSerializable)); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref hidePosition); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1086037223u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (((NetworkBehaviour)this).IsServer) { return; } NetworkObject val3 = default(NetworkObject); if (!((NetworkObjectReference)(ref originalEnemyRef)).TryGet(ref val3, (NetworkManager)null)) { Plugin.logger.LogWarning((object)"HideOriginalEnemyBodyClientRpc: could not resolve enemy NetworkObject; skipping client-side teleport"); return; } ((Component)val3).transform.position = hidePosition; EnemyAI component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null) { component.serverPosition = hidePosition; } Plugin.logger.LogDebug((object)$"Hid original enemy body '{((Object)((Component)val3).gameObject).name}' at {hidePosition}"); } protected override void __initializeVariables() { ((NetworkBehaviour)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 ((NetworkBehaviour)this).__registerRpc(3276370873u, new RpcReceiveHandler(__rpc_handler_3276370873), "RequestConfigSyncServerRpc"); ((NetworkBehaviour)this).__registerRpc(2833577898u, new RpcReceiveHandler(__rpc_handler_2833577898), "ReceiveConfigSyncClientRpc"); ((NetworkBehaviour)this).__registerRpc(149726897u, new RpcReceiveHandler(__rpc_handler_149726897), "BroadcastConfigSyncClientRpc"); ((NetworkBehaviour)this).__registerRpc(1086037223u, new RpcReceiveHandler(__rpc_handler_1086037223), "HideOriginalEnemyBodyClientRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_3276370873(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_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_003e: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((EnhancedMonstersNetworkHandler)(object)target).RequestConfigSyncServerRpc(server); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2833577898(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_0068: 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) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); byte[] data = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref data, default(ForPrimitives)); } ClientRpcParams client = rpcParams.Client; target.__rpc_exec_stage = (__RpcExecStage)1; ((EnhancedMonstersNetworkHandler)(object)target).ReceiveConfigSyncClientRpc(data, client); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_149726897(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_006e: 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_0058: 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) { bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); byte[] data = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref data, default(ForPrimitives)); } target.__rpc_exec_stage = (__RpcExecStage)1; ((EnhancedMonstersNetworkHandler)(object)target).BroadcastConfigSyncClientRpc(data); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1086037223(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_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_0060: 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) { NetworkObjectReference originalEnemyRef = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadValueSafe(ref originalEnemyRef, default(ForNetworkSerializable)); Vector3 hidePosition = default(Vector3); ((FastBufferReader)(ref reader)).ReadValueSafe(ref hidePosition); target.__rpc_exec_stage = (__RpcExecStage)1; ((EnhancedMonstersNetworkHandler)(object)target).HideOriginalEnemyBodyClientRpc(originalEnemyRef, hidePosition); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "EnhancedMonstersNetworkHandler"; } } } namespace EnhancedMonsters.Monobehaviours { public class EnemyScrap : GrabbableObject { [CompilerGenerated] private sealed class d__22 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public EnemyScrap <>4__this; private AnimatorClipInfo[] 5__1; private float 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0074: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: { <>1__state = -1; 5__1 = <>4__this.EnemyAnimator.GetCurrentAnimatorClipInfo(0); if (5__1.Length < 1) { return false; } 5__2 = ((AnimatorClipInfo)(ref 5__1[0])).clip.length; AnimatorStateInfo currentAnimatorStateInfo = <>4__this.EnemyAnimator.GetCurrentAnimatorStateInfo(0); 5__3 = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime; break; } case 1: <>1__state = -1; break; } if (5__3 < 5__2) { <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; } ((Behaviour)<>4__this.EnemyAnimator).enabled = false; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public EnemyType enemyType; private readonly NetworkVariable _syncedScrapValue = new NetworkVariable(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); public Animator EnemyAnimator { get; private set; } public ScanNodeProperties ScanNode { get; private set; } public GameObject EnemyGameObject { get; set; } public EnemyData EnemyData => LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance.EnemiesData[enemyType.enemyName] : SyncedConfig.Default.EnemiesData[enemyType.enemyName]; public int SyncedScrapValue { get { return _syncedScrapValue.Value; } set { _syncedScrapValue.Value = value; } } private void Awake() { EnemyAnimator = ((Component)this).gameObject.GetComponentInChildren(); if ((Object)(object)EnemyAnimator == (Object)null) { Plugin.logger.LogWarning((object)("So somehow, the monster " + ((Object)((Component)this).gameObject).name + " does not have any Animator. Will work anyway but might have its animations glitched")); } ScanNode = ((Component)this).gameObject.GetComponentInChildren(); if ((Object)(object)ScanNode == (Object)null) { Plugin.logger.LogWarning((object)("No ScanNode found in " + ((Object)((Component)this).gameObject).name + ". That's a weird enemy...")); } if (!base.itemProperties.saveItemVariable) { Plugin.logger.LogError((object)("Error: Enemy corpse saving was set to false for " + enemyType.enemyName)); } } public override void Start() { ((GrabbableObject)this).Start(); if (((NetworkBehaviour)this).IsServer) { Plugin.logger.LogInfo((object)"Synchronizing the mob data and scrap values and positions with clients..."); EnemyData enemyData = SyncedConfig.Instance.EnemiesData[enemyType.enemyName]; if (GameNetworkManager.Instance.gameHasStarted || base.scrapValue == 0) { int syncedScrapValue = new Random().Next(enemyData.MinValue, enemyData.MaxValue); SyncedScrapValue = syncedScrapValue; } else { SyncedScrapValue = base.scrapValue; } } Plugin.logger.LogInfo((object)("Mob scrap " + enemyType.enemyName + " has spawned !")); if ((Object)(object)EnemyAnimator != (Object)null) { if (!EnemyData.Metadata.AnimateOnDeath) { ((Behaviour)EnemyAnimator).enabled = false; } try { EnemyAnimator.SetLayerWeight(2, 0f); } catch (Exception arg) { Plugin.logger.LogWarning((object)$"Failed to set layer 2's weight to 0 (bracken fix?). Error: {arg}"); ((Behaviour)EnemyAnimator).enabled = false; } try { EnemyAnimator.SetBool("Stunned", false); EnemyAnimator.SetBool("stunned", false); EnemyAnimator.SetBool("stun", false); EnemyAnimator.SetTrigger("KillEnemy"); EnemyAnimator.SetBool("Dead", true); ((MonoBehaviour)this).StartCoroutine(DisableAnimatorOnAnimationEnd()); } catch (Exception arg2) { Plugin.logger.LogError((object)$"Failed to set the enemy {((Object)((Component)this).gameObject).name} mob mesh animator to dead state. Maybe the animator doesn't have a dead state ? Error: {arg2}"); ((Behaviour)EnemyAnimator).enabled = false; } if (enemyType.enemyName == "Flowerman") { ((Component)EnemyAnimator).gameObject.SetActive(false); ((Component)EnemyAnimator).gameObject.SetActive(true); ((Behaviour)EnemyAnimator).enabled = false; } } if (Object.op_Implicit((Object)(object)ScanNode)) { EnemyData enemyData2 = (LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance.EnemiesData[enemyType.enemyName] : SyncedConfig.Default.EnemiesData[enemyType.enemyName]); ScanNodeProperties component = ((Component)ScanNode).GetComponent(); component.scrapValue = SyncedScrapValue; component.subText = $"Rank:{enemyData2.Rank}\nValue: ${SyncedScrapValue}"; } else { Plugin.logger.LogError((object)("Enemy corpse " + base.itemProperties.itemName + " is missing a ScanNode !")); } } public void SetScrapValue(int value) { Plugin.logger.LogInfo((object)$"Setting scrap value for {base.itemProperties.itemName}: {value}"); base.scrapValue = value; ScanNode.scrapValue = value; EnemyData enemyData = (LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance.EnemiesData[enemyType.enemyName] : SyncedConfig.Default.EnemiesData[enemyType.enemyName]); ScanNode.subText = $"Rank: {enemyData.Rank}\nValue: {value}"; } [IteratorStateMachine(typeof(d__22))] public IEnumerator DisableAnimatorOnAnimationEnd() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(0) { <>4__this = this }; } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); ((NetworkVariableBase)_syncedScrapValue).Initialize((NetworkBehaviour)(object)this); NetworkVariable syncedScrapValue = _syncedScrapValue; syncedScrapValue.OnValueChanged = (OnValueChangedDelegate)(object)Delegate.Combine((Delegate?)(object)syncedScrapValue.OnValueChanged, (Delegate?)(object)(OnValueChangedDelegate)delegate(int oldVal, int newVal) { SetScrapValue(newVal); }); } public override int GetItemDataToSave() { Plugin.logger.LogInfo((object)("GetItemData: Trying to save enemy scrap for " + base.itemProperties.itemName + ".")); return 0; } protected override void __initializeVariables() { if (_syncedScrapValue == null) { throw new Exception("EnemyScrap._syncedScrapValue cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_syncedScrapValue).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_syncedScrapValue, "_syncedScrapValue"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_syncedScrapValue); ((GrabbableObject)this).__initializeVariables(); } protected override void __initializeRpcs() { ((GrabbableObject)this).__initializeRpcs(); } protected internal override string __getTypeName() { return "EnemyScrap"; } } public class SpiderArachnophobiaToggle : MonoBehaviour { private MeshRenderer _safeMesh; private SkinnedMeshRenderer _normalMesh; private bool _renderersResolved; private void Start() { ResolveRenderers(); ApplyArachnophobeMode(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode); } private void LateUpdate() { ApplyArachnophobeMode(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode); } public void ApplyArachnophobeMode(bool arachnophobeEnabled) { if (!_renderersResolved) { ResolveRenderers(); } if (!((Object)(object)_safeMesh == (Object)null) && !((Object)(object)_normalMesh == (Object)null)) { if (((Renderer)_safeMesh).enabled != arachnophobeEnabled) { ((Renderer)_safeMesh).enabled = arachnophobeEnabled; } if (((Renderer)_normalMesh).enabled != !arachnophobeEnabled) { ((Renderer)_normalMesh).enabled = !arachnophobeEnabled; } } } private void ResolveRenderers() { if (((Component)this).transform.childCount == 0) { return; } Transform child = ((Component)this).transform.GetChild(0); Transform obj = child.Find("MeshContainer"); object obj2; if (obj == null) { obj2 = null; } else { Transform obj3 = obj.Find("AnimContainer"); if (obj3 == null) { obj2 = null; } else { Transform obj4 = obj3.Find("Armature"); if (obj4 == null) { obj2 = null; } else { Transform obj5 = obj4.Find("Abdomen"); obj2 = ((obj5 != null) ? obj5.Find("SpiderText") : null); } } } Transform val = (Transform)obj2; Transform obj6 = child.Find("MeshContainer"); Transform val2 = ((obj6 != null) ? obj6.Find("MeshRenderer") : null); _safeMesh = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); _normalMesh = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null); if ((Object)(object)_safeMesh == (Object)null || (Object)(object)_normalMesh == (Object)null) { Plugin.logger.LogError((object)"This Spider mesh doesn't have a normal mesh or an arachnophobe mesh."); } else { _renderersResolved = true; } } } } namespace EnhancedMonsters.Config { internal static class ConfigSyncService { [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0099: 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) switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = 0f; break; case 1: <>1__state = -1; 5__1 += 0.25f; break; } if ((Object)(object)EnhancedMonstersNetworkHandler.Instance == (Object)null && 5__1 < 10f) { <>2__current = (object)new WaitForSeconds(0.25f); <>1__state = 1; return true; } if ((Object)(object)EnhancedMonstersNetworkHandler.Instance != (Object)null) { EnhancedMonstersNetworkHandler.Instance.RequestConfigSyncServerRpc(); Plugin.logger.LogInfo((object)$"Config sync request sent after {5__1:0.00}s wait"); } else { Plugin.logger.LogWarning((object)$"Config sync handler did not appear within {10f}s, giving up"); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static SyncedConfig Default { get; private set; } public static SyncedConfig Instance { get; private set; } public static bool Synced { get; internal set; } public static bool IsHost { get { NetworkManager singleton = NetworkManager.Singleton; return singleton != null && singleton.IsHost; } } public static bool IsClient { get { NetworkManager singleton = NetworkManager.Singleton; return singleton != null && singleton.IsClient; } } public static void Initialize(SyncedConfig defaults) { Default = defaults; Instance = defaults; Synced = false; } public static void RevertSync() { Instance = Default; Synced = false; Plugin.logger.LogInfo((object)"Reverting sync, Instance=Default, Synced=false"); } public static void RequestSync() { //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) if (!IsClient || IsHost) { return; } if ((Object)(object)EnhancedMonstersNetworkHandler.Instance != (Object)null) { EnhancedMonstersNetworkHandler.Instance.RequestConfigSyncServerRpc(); Plugin.logger.LogInfo((object)"Requesting config sync via ServerRpc"); return; } Plugin.logger.LogInfo((object)"EnhancedMonstersNetworkHandler not yet spawned, scheduling retry"); StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(WaitForHandlerAndRequest()); } else { Plugin.logger.LogWarning((object)"StartOfRound.Instance is null, cannot schedule sync retry"); } } [IteratorStateMachine(typeof(d__19))] private static IEnumerator WaitForHandlerAndRequest() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0); } public static void BroadcastSync() { if (!IsHost) { return; } EnhancedMonstersNetworkHandler instance = EnhancedMonstersNetworkHandler.Instance; if ((Object)(object)instance == (Object)null) { Plugin.logger.LogDebug((object)"BroadcastSync: handler not spawned yet, skipping"); return; } byte[] array = SerializeCurrent(); if (array.Length != 0) { instance.BroadcastConfigSyncClientRpc(array); Plugin.logger.LogInfo((object)$"Host broadcast config sync, {array.Length} bytes"); } } public static byte[] SerializeCurrent() { if (Instance == null) { Plugin.logger.LogError((object)"SerializeCurrent: Instance is null"); return Array.Empty(); } try { string s = JsonConvert.SerializeObject((object)Instance.EnemiesData); return Encoding.UTF8.GetBytes(s); } catch (Exception arg) { Plugin.logger.LogError((object)$"Failed to serialize sync payload: {arg}"); return Array.Empty(); } } public static void ApplyReceivedSync(byte[] data) { if (data == null || data.Length == 0) { Plugin.logger.LogError((object)"ApplyReceivedSync: empty payload"); return; } if (Instance == null) { Plugin.logger.LogError((object)"ApplyReceivedSync: Instance is null, cannot apply"); return; } try { string @string = Encoding.UTF8.GetString(data); Dictionary dictionary = JsonConvert.DeserializeObject>(@string); if (dictionary == null) { Plugin.logger.LogError((object)"ApplyReceivedSync: deserialization returned null"); return; } EnemiesDataManager.EnemiesData.Clear(); foreach (KeyValuePair item in dictionary) { EnemiesDataManager.EnemiesData[item.Key] = item.Value; } Synced = true; Plugin.logger.LogInfo((object)$"Applied sync, {dictionary.Count} entries, Synced=true"); } catch (Exception arg) { Plugin.logger.LogError((object)$"Failed to apply sync payload: {arg}"); } } } internal static class LethalConfigSupport { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static CanModifyDelegate <>9__3_1; public static GenericButtonHandler <>9__3_0; internal CanModifyResult b__3_1() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) return CanModifyResult.op_Implicit(!GameNetworkManager.Instance.gameHasStarted || !NetworkManager.Singleton.IsListening); } internal void b__3_0() { GUIUtility.systemCopyBuffer = EnemiesDataManager.EnemiesDataFile; } } private static bool? lethalConfigLoaded; public static bool LethalConfigLoaded { get { bool valueOrDefault = lethalConfigLoaded.GetValueOrDefault(); if (!lethalConfigLoaded.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"); lethalConfigLoaded = valueOrDefault; } return lethalConfigLoaded.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void RegisterLethalConfig(LocalConfig config) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_004c: 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: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown LethalConfigManager.SetModDescription("Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements."); ConfigEntry synchronizeRanks = config.synchronizeRanks; BoolCheckBoxOptions val = new BoolCheckBoxOptions { Name = "Synchronize Ranks", Section = "General", RequiresRestart = false }; object obj = <>c.<>9__3_1; if (obj == null) { CanModifyDelegate val2 = () => CanModifyResult.op_Implicit(!GameNetworkManager.Instance.gameHasStarted || !NetworkManager.Singleton.IsListening); <>c.<>9__3_1 = val2; obj = (object)val2; } ((BaseOptions)val).CanModifyCallback = (CanModifyDelegate)obj; BoolCheckBoxConfigItem val3 = new BoolCheckBoxConfigItem(synchronizeRanks, val); object obj2 = <>c.<>9__3_0; if (obj2 == null) { GenericButtonHandler val4 = delegate { GUIUtility.systemCopyBuffer = EnemiesDataManager.EnemiesDataFile; }; <>c.<>9__3_0 = val4; obj2 = (object)val4; } GenericButtonConfigItem val5 = new GenericButtonConfigItem("General", "Enemies Data", "All the enemies data are stored inside the file. You have a few rules to follow when editing the file or it will not work. Look at the github or thunderstore page for more info.", "Copy path", (GenericButtonHandler)obj2); LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val3); LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val5); } } internal static class LethalSettingsSupport { private static bool? lethalSettingsLoaded; public static bool LethalSettingsLoaded { get { bool valueOrDefault = lethalSettingsLoaded.GetValueOrDefault(); if (!lethalSettingsLoaded.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.willis.lc.lethalsettings"); lethalSettingsLoaded = valueOrDefault; } return lethalSettingsLoaded.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void RegisterLethalSettings(LocalConfig config) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_003f: 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_0066: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown LocalConfig config2 = config; Plugin.logger.LogInfo((object)"Registering lsSyncRank"); ToggleComponent val = new ToggleComponent { Enabled = true, Text = "Synchronize Ranks", Value = true, OnValueChanged = delegate(ToggleComponent comp, bool value) { config2.synchronizeRanks.Value = value; }, OnInitialize = delegate(ToggleComponent comp) { comp.Value = config2.synchronizeRanks.Value; comp.Enabled = !GameNetworkManager.Instance.gameHasStarted || !NetworkManager.Singleton.IsListening; } }; Plugin.logger.LogInfo((object)"Registering lsAccessEnemiesDataFile"); ButtonComponent val2 = new ButtonComponent { Enabled = true, ShowCaret = true, Text = "Copy path to Enemies Data file", OnClick = delegate { GUIUtility.systemCopyBuffer = EnemiesDataManager.EnemiesDataFile; } }; Plugin.logger.LogInfo((object)"Registering mod info"); ModSettingsConfig val3 = new ModSettingsConfig(); val3.Id = "com.velddev.enhancedmonsters"; val3.Name = "Enhanced Monsters"; val3.Version = "1.4.0"; val3.Description = "Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements."; val3.MenuComponents = (MenuComponent[])(object)new MenuComponent[2] { (MenuComponent)val, (MenuComponent)val2 }; ModMenu.RegisterMod(val3); Plugin.logger.LogInfo((object)"Registered Mod Info"); } } public class LocalConfig { internal const string ModDesc = "Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements."; public readonly ConfigEntry synchronizeRanks; public static LocalConfig Singleton { get; private set; } public LocalConfig(ConfigFile cfg) { Singleton = this; synchronizeRanks = cfg.Bind("General", "Synchronize Ranks", true, "Wether or not to synchronize ranks of enemies from host's configs. It is recommended to keep it enabled. [NOTE: This setting can only be edited from the main menu.]"); if (LethalConfigSupport.LethalConfigLoaded) { Plugin.logger.LogInfo((object)"Loading LethalConfig settings"); LethalConfigSupport.RegisterLethalConfig(this); } if (LethalSettingsSupport.LethalSettingsLoaded) { Plugin.logger.LogInfo((object)"Loading LethalSettings settings"); LethalSettingsSupport.RegisterLethalSettings(this); } Plugin.logger.LogInfo((object)"Registering all settings."); } } public class SyncedConfig { public Dictionary EnemiesData; public ConfigFile BepInConfigs; public static SyncedConfig Default => ConfigSyncService.Default; public static SyncedConfig Instance => ConfigSyncService.Instance; public static bool Synced => ConfigSyncService.Synced; public static bool IsHost => ConfigSyncService.IsHost; public static bool IsClient => ConfigSyncService.IsClient; public SyncedConfig(ConfigFile cfg) { BepInConfigs = cfg; EnemiesData = EnemiesDataManager.EnemiesData; ConfigSyncService.Initialize(this); } public static void BroadcastSync() { ConfigSyncService.BroadcastSync(); } public static void RequestSync() { ConfigSyncService.RequestSync(); } public static void RevertSync() { ConfigSyncService.RevertSync(); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace EnhancedMonsters.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }