Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CreatureLevelAndLootControl PTBR v0.1.0
CreaturePTBR.dll
Decompiled 5 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using Splatform; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Guid("6363d416-d2b3-437d-8f72-ed0069245f86")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyCompany("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyProduct("CreatureLevelControl")] [assembly: AssemblyTitle("CreatureLevelControl")] [assembly: CompilationRelaxations(8)] [assembly: AssemblyDescription("https://valheim.thunderstore.io/package/Smoothbrain/CreatureLevelAndLootControl")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: <6c79ef52-1d18-4a52-b86b-be9360ea1262>RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<97c74bb4-9272-4b0e-a1bd-099c0a59de49>Embedded] internal sealed class <97c74bb4-9272-4b0e-a1bd-099c0a59de49>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [<97c74bb4-9272-4b0e-a1bd-099c0a59de49>Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <75b8e597-2006-46dc-8007-b4ba3b036dbf>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <75b8e597-2006-46dc-8007-b4ba3b036dbf>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <75b8e597-2006-46dc-8007-b4ba3b036dbf>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [<97c74bb4-9272-4b0e-a1bd-099c0a59de49>Embedded] [CompilerGenerated] internal sealed class <a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContextAttribute : Attribute { public readonly byte Flag; public <a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [<97c74bb4-9272-4b0e-a1bd-099c0a59de49>Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class <6c79ef52-1d18-4a52-b86b-be9360ea1262>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <6c79ef52-1d18-4a52-b86b-be9360ea1262>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CreatureLevelControl { public enum CreatureExtraEffect { None, Aggressive, Quick, Regenerating, Curious, Splitting, Armored } public enum CreatureInfusion { None, Lightning, Fire, Frost, Poison, Chaos, Spirit } public enum BossAffix { None, Reflective, Shielded, Mending, Summoner, Elementalist, Enraged, Twin } [PublicAPI] [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(1)] public static class API { public static bool IsEnabled() { return true; } public static bool IsInfusionEnabled() { return CreatureLevelControl.creatureInfusionEffects.GetToggle(); } public static bool IsExtraEffectEnabled() { return CreatureLevelControl.creatureSpecialEffects.GetToggle(); } public static bool IsAffixEnabled() { return CreatureLevelControl.bossSpecialEffects.GetToggle(); } public static int GetWorldLevel() { //IL_0066: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !Object.op_Implicit((Object)(object)Game.instance)) { return 0; } int result = CreatureLevelControl.worldLevels.Count; if (CreatureLevelControl.difficultySecondFactor.Value == CreatureLevelControl.DifficultySecondFactor.Distance) { Vector3 val = default(Vector3); ZoneSystem.instance.GetLocationIcon(Game.instance.m_StartLocation, ref val); Player localPlayer = Player.m_localPlayer; Vector3 val2 = (Vector3)((localPlayer != null) ? ((Component)localPlayer).transform.localPosition : default(Vector3)) - val; float num = Mathf.Sqrt(Mathf.Pow(val2.x, 2f) + Mathf.Pow(val2.z, 2f)); foreach (ConfigEntry<int> key in CreatureLevelControl.spawnDistance.Keys) { if (num < (float)key.Value) { result = CreatureLevelControl.spawnDistance[key]; break; } } } else if (CreatureLevelControl.difficultySecondFactor.Value != CreatureLevelControl.DifficultySecondFactor.Age_of_world) { result = ((CreatureLevelControl.difficultySecondFactor.Value != CreatureLevelControl.DifficultySecondFactor.BossesKilled) ? 3 : new string[6] { "eikthyr", "gdking", "bonemass", "dragon", "goblinking", "queen" }.Count([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (string boss) => ZoneSystem.instance.GetGlobalKey("defeated_" + boss))); } else { int day = EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds()); foreach (ConfigEntry<int> key2 in CreatureLevelControl.worldLevels.Keys) { if (day < key2.Value) { result = CreatureLevelControl.worldLevels[key2]; break; } } } return result; } internal static float[] zeroProbabilities(float[] p, int shift = 0) { float num = 100f; for (int i = 0; i < p.Length; i++) { num -= p[i]; if (num < 0f) { p[i] += num; num = 0f; } } float[] array = new float[shift + 1].Concat(p).ToArray(); array[shift] = num; return array; } public static float[] LevelProbabilities([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] Character character, int worldLevel, bool includeZoneBonusLevel) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) int num; if (!includeZoneBonusLevel) { num = 0; } else { object obj; if (character == null) { obj = null; } else { ZNetView component = ((Component)character).GetComponent<ZNetView>(); obj = ((component != null) ? component.GetZDO() : null); } num = ((obj == null) ? CreatureSector.sectorBonusLevel(((Component)Player.m_localPlayer).GetComponent<ZNetView>().GetZDO().GetSector()) : CreatureSector.sectorBonusLevel(character)); } int num2 = num; if ((Object)(object)character != (Object)null) { float[] array = Utils.ReadWithWorldLevelFromConfig(character, [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] (CreatureConfig c) => c.worldLevelToStars); if (array != null) { return zeroProbabilities(array, (!character.IsBoss()) ? num2 : 0); } } if (character != null && character.IsBoss() && !CreatureLevelControl.bossLevelUseCreatureLevel.GetToggle()) { return zeroProbabilities(Utils.ParseStringProbabilities(CreatureLevelControl.customBossLevelChances.Value)); } if (CreatureLevelControl.difficulty.Value == CreatureLevelControl.Difficulty.Custom) { return zeroProbabilities(Utils.ParseStringProbabilities(CreatureLevelControl.customLevelChances[worldLevel].Value), num2); } if (!CreatureLevelControl.levelConfig.TryGetValue(CreatureLevelControl.difficulty.Value, out var value)) { value = CreatureLevelControl.levelConfig[CreatureLevelControl.Difficulty.Medium]; } float[] source = zeroProbabilities(value[worldLevel], num2); int value2 = (int)CreatureLevelControl.minimumLevel.Value; int num3 = Math.Max(value2, (int)CreatureLevelControl.maximumLevel.Value); float num4 = source.Take(value2).Sum(); float num5 = source.Skip(1 + num3).Sum(); source = new float[value2].Concat(source.Skip(value2).Take(1 + num3 - value2)).ToArray(); source[value2] += num4; if (num5 > 0f) { source = source.Concat(new float[Mathf.Max(0, 1 + num3 - source.Length)]).ToArray(); source[num3] += num5; } return source; } public static int LevelRand(Character character) { return Utils.LevelFromProbabilities(LevelProbabilities(character, GetWorldLevel(), includeZoneBonusLevel: true)); } public static bool HasAffixBoss(Character character) { return HasExtraEffectCreature(character); } public static BossAffix GetAffixBoss(Character character) { ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (!CreatureLevelControl.bossSpecialEffects.GetToggle() || ((component != null) ? component.GetZDO() : null) == null) { return BossAffix.None; } return (BossAffix)component.GetZDO().GetInt("CL&LC effect", 0); } public static void SetAffixBoss(Character character, BossAffix affix) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: 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_021d: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) string[] source = new string[7] { "Eikthyr", "gd_king", "Bonemass", "Dragon", "GoblinKing", "SeekerQueen", "Fader" }; if (affix == BossAffix.Summoner && !source.Contains(((Object)character).name.Replace("(Clone)", ""))) { affix = BossAffix.None; } if (GetAffixBoss(character) == BossAffix.Twin) { if (affix != BossAffix.Twin) { Character twinBoss = GetTwinBoss(character); GameObject val = ((twinBoss != null) ? ((Component)twinBoss).gameObject : null); if (val != null) { ZNetScene.instance.Destroy(val); } } float num = Utils.ReadValueFromEnumWithWorldLevelAndStarsFromConfig(character, BossAffix.Twin, [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 2 })] (CreatureConfig c) => c.worldLevelToBossAffixFactor) ?? (CreatureLevelControl.bossAffixPowerTwin.Value / 100f); character.m_health /= num; character.SetupMaxHealth(); } else if (affix == BossAffix.Twin) { if (CreatureLevelControl.bossSpecialEffects.GetToggle()) { float num2 = Utils.ReadValueFromEnumWithWorldLevelAndStarsFromConfig(character, BossAffix.Twin, [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 2 })] (CreatureConfig c) => c.worldLevelToBossAffixFactor) ?? (CreatureLevelControl.bossAffixPowerTwin.Value / 100f); character.m_health *= num2; character.SetupMaxHealth(); setAffixBossZDO(character, affix); ZPackage val2 = new ZPackage(); character.m_nview.GetZDO().Serialize(val2); val2.SetPos(0); ZDO val3 = new ZDO(); val3.Init(); val3.m_uid = Utils.GenerateNewZDOID(); val3.Deserialize(val2); val3.SetRotation(Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); val3.SetPosition(((Component)character).transform.localPosition + Random.insideUnitSphere * 0.5f); val3.SetOwnerInternal(ZDOMan.GetSessionID()); ZDOMan.instance.m_objectsByID.Add(val3.m_uid, val3); Character component = ZNetScene.instance.CreateObject(val3).GetComponent<Character>(); Vector3 insideUnitSphere = Random.insideUnitSphere; if (insideUnitSphere.y < 0f) { insideUnitSphere.y = 0f - insideUnitSphere.y; } ((Component)component).GetComponent<Rigidbody>().AddForce(insideUnitSphere * 5f, (ForceMode)2); CreatureLevelControl.SetTwinBoss(character, component); } else { affix = BossAffix.None; } } setAffixBossZDO(character, affix); OriginalCharacterData component2 = ((Component)character).GetComponent<OriginalCharacterData>(); if (component2 != null) { component2.Awake(); } else { ((Component)character).gameObject.AddComponent<OriginalCharacterData>(); } CreatureLevelControl.ShowStar.NeedsUpdate.Remove(character); } private static void setAffixBossZDO(Character character, BossAffix affix) { ((Component)character).GetComponent<ZNetView>().GetZDO().Set("CL&LC effect", (int)affix); } public static bool HasExtraEffectCreature(Character character) { return ((Component)character).GetComponent<ZNetView>().GetZDO().GetInt("CL&LC effect", -1) != -1; } public static CreatureExtraEffect GetExtraEffectCreature(Character character) { ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (!CreatureLevelControl.creatureSpecialEffects.GetToggle() || ((component != null) ? component.GetZDO() : null) == null || character.GetLevel() <= 1) { return CreatureExtraEffect.None; } return (CreatureExtraEffect)component.GetZDO().GetInt("CL&LC effect", 0); } public static void SetExtraEffectCreature(Character character) { float rand; HashSet<CreatureExtraEffect> processedProbabilities; CreatureExtraEffect? creatureExtraEffect = Utils.RandomWithProbabilityFromConfig(character, [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 2 })] (CreatureConfig c) => c.worldLevelToCreatureEffect, out rand, out processedProbabilities); if (!creatureExtraEffect.HasValue) { creatureExtraEffect = CreatureExtraEffect.None; foreach (CreatureExtraEffect key in CreatureLevelControl.customCreatureAffixChances.Keys) { if (!processedProbabilities.Contains(key)) { rand -= CreatureLevelControl.customCreatureAffixChances[key].Value; if (rand < 0f) { creatureExtraEffect = key; break; } } } } SetExtraEffectCreature(character, creatureExtraEffect.Value); } public static void SetExtraEffectCreature(Character character, CreatureExtraEffect effect) { ((Component)character).GetComponent<ZNetView>().GetZDO().Set("CL&LC effect", (int)effect); CreatureLevelControl.SetPersistedCharacterAttributes(character); CreatureLevelControl.ShowStar.NeedsUpdate.Remove(character); } public static bool HasInfusionCreature(Character character) { return ((Component)character).GetComponent<ZNetView>().GetZDO().GetInt("CL&LC infusion", -1) != -1; } public static CreatureInfusion GetInfusionCreature(Character character) { ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (!CreatureLevelControl.creatureInfusionEffects.GetToggle() || ((component != null) ? component.GetZDO() : null) == null) { return CreatureInfusion.None; } return (CreatureInfusion)component.GetZDO().GetInt("CL&LC infusion", 0); } public static void SetInfusionCreature(Character character) { float rand; HashSet<CreatureInfusion> processedProbabilities; CreatureInfusion? creatureInfusion = Utils.RandomWithProbabilityFromConfig(character, [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 2 })] (CreatureConfig c) => c.worldLevelToInfusion, out rand, out processedProbabilities); CreatureInfusion infusion; if (creatureInfusion.HasValue) { infusion = creatureInfusion.GetValueOrDefault(); } else { infusion = CreatureInfusion.None; if (!CreatureLevelControl.infusionProbabilityModifiersByLevel.TryGetValue(character.GetLevel(), out var value)) { value = 1f; } if (Random.Range(0f, 1f) <= value) { foreach (CreatureInfusion key in CreatureLevelControl.customCreatureInfusionChances.Keys) { if (!processedProbabilities.Contains(key)) { rand -= CreatureLevelControl.customCreatureInfusionChances[key].Value; if (rand < 0f) { infusion = key; break; } } } } } SetInfusionCreature(character, infusion); } public static void SetInfusionCreature(Character character, CreatureInfusion infusion) { ((Component)character).GetComponent<ZNetView>().GetZDO().Set("CL&LC infusion", (int)infusion); OriginalCharacterData component = ((Component)character).GetComponent<OriginalCharacterData>(); if (component != null) { component.immutableExtra = true; } CreatureLevelControl.AttachInfusionFlames(character); CreatureLevelControl.ShowStar.NeedsUpdate.Remove(character); } [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] public static Character GetTwinBoss(Character boss) { //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_0020: Unknown result type (might be due to invalid IL or missing references) ZDOID zDOID = ((Component)boss).GetComponent<ZNetView>().GetZDO().GetZDOID("CL&LC twin boss"); if (ZDOMan.instance.m_objectsByID.TryGetValue(zDOID, out var value) && ZNetScene.s_instance.m_instances.TryGetValue(value, out var value2)) { return ((Component)value2).GetComponent<Character>(); } return null; } public static bool DropItemOnDeath(ItemData item) { bool? flag = Utils.ReadWithWorldLevelFromConfig(item, [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] (ItemConfig c) => c.worldLevelToItemLoss); if (!flag.HasValue) { if (!item.m_shared.m_questItem) { return !item.m_equipped; } return false; } return flag.GetValueOrDefault(); } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] public class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1 })] public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 1 })] public Func<object, string> ObjToStr; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 1 })] public Func<string, object> StrToObj; } [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(1)] public abstract class ConfigFile { public interface Loader { [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] ConfigFile ConfigFile { [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] get; [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] set; } string FilePattern { get; } string EditButtonName { get; } CustomSyncedValue<List<string>> FileData { get; } bool Enabled { get; } ConfigFile InstantiateConfig(); void ProcessConfig(); } [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] protected class Section : IDisposable { [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] private readonly Section lastSection; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] private readonly Dictionary<string, object> dict; public readonly string dictKey; private readonly HashSet<string> knownKeys = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase); private readonly ConfigFile configFile; public string Path => ((lastSection == null || lastSection.dictKey == "") ? "" : (lastSection.Path + ".")) + dictKey; public Section([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] Dictionary<string, object> dict, string key, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] Section lastSection, ConfigFile file) { this.dict = dict; dictKey = key; this.lastSection = lastSection; configFile = file; } [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] public object Get(string key) { knownKeys.Add(key); if (dict.TryGetValue(key, out var value) && value == null) { configFile.configErrors.Add(Path + "." + key + " cannot be empty"); } return value; } public IEnumerable<string> KeysWithPrefix(string prefix) { return dict.Keys.Where([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (string k) => k.StartsWith(prefix)); } public void Dispose() { IEnumerable<string> enumerable = dict.Keys.Where([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (string key) => !knownKeys.Contains(key)).ToArray(); if (enumerable.Any()) { configFile.configWarnings.Add(Path + " contains unknown keys " + string.Join(", ", enumerable)); } } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] protected delegate bool ParserDelegate<[<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] ref T target, Section sect, string key); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] private struct ParseResult<T> { [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] public T value; public string error; } public static readonly Loader[] loaders = new Loader[2] { new CreatureConfig.Loader(), new ItemConfig.Loader() }; public readonly List<string> configErrors = new List<string>(); public readonly List<string> configWarnings = new List<string>(); protected readonly Dictionary<string, List<string>> groups = new Dictionary<string, List<string>>(); public void DumpWarnings(string prefix) { if (configWarnings.Count > 0) { Debug.LogWarning((object)(prefix + ((configErrors.Count > 0) ? "" : " The config file was loaded, but may not yield expected results due to warnings:") + "\n" + string.Join("\n", configWarnings))); configWarnings.Clear(); } } protected void AssignConfig<[<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] T>(ref T newConfig, T inConfig) where T : class { if (newConfig == null) { newConfig = inConfig; } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] protected void AssignConfig<T>(ref T? newConfig, T? inConfig) where T : struct { T? val = newConfig; if (!val.HasValue) { newConfig = inConfig; } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] protected void AssignEnumConfig<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 1, 2 })] ref Dictionary<int, Dictionary<T, float[]>> newConfig, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 1, 2 })] Dictionary<int, Dictionary<T, float[]>> inConfig) { if (inConfig == null) { return; } if (newConfig == null) { newConfig = inConfig.ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<int, Dictionary<T, float[]>> kv) => kv.Key, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<int, Dictionary<T, float[]>> kv) => kv.Value.ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<T, float[]> k) => k.Key, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<T, float[]> k) => k.Value)); } foreach (KeyValuePair<int, Dictionary<T, float[]>> item in inConfig) { if (!newConfig.ContainsKey(item.Key)) { newConfig[item.Key] = item.Value; continue; } foreach (KeyValuePair<T, float[]> item2 in item.Value) { if (!newConfig[item.Key].ContainsKey(item2.Key)) { newConfig[item.Key][item2.Key] = item2.Value; } } } } protected void resolveGroupsForName(List<string> groupNames, string name) { foreach (KeyValuePair<string, List<string>> group in groups) { if (!groupNames.Contains(group.Key) && group.Value.Contains(name)) { groupNames.Add(group.Key); resolveGroupsForName(groupNames, group.Key); } } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] protected void fillWorldLevels<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1 })] Dictionary<int, T> config) { if (config == null) { return; } T value = default(T); int num = -1; for (int i = 0; i <= CreatureLevelControl.defaultWorldLevelDays.Length; i++) { if (config.TryGetValue(i, out var value2)) { value = value2; if (num == -1) { num = i; } } else if (num != -1) { config[i] = value; } } for (int j = 0; j < num; j++) { config[j] = config[num]; } } [PublicAPI] [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] protected static Dictionary<string, object> castDictToStringDict([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] Dictionary<object, object> dict) { return new Dictionary<string, object>(dict.ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<object, object> kv) => kv.Key.ToString(), [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<object, object> kv) => kv.Value), StringComparer.CurrentCultureIgnoreCase); } [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] protected Section section(Section parent, string key) { object obj = parent.Get(key); if (obj is Dictionary<object, object> dict) { return new Section(castDictToStringDict(dict), key, parent, this); } if (obj != null) { configWarnings.Add($"Expected a section containing further configuration values, got {obj.GetType()} for {parent.Path}.{key}"); } return null; } public void Parse(object configObj) { if (configObj is Dictionary<object, object> dict) { Dictionary<string, object> dictionary = castDictToStringDict(dict); foreach (KeyValuePair<string, object> item2 in dictionary) { if (item2.Key == "groups") { if (item2.Value is Dictionary<object, object> dictionary2) { foreach (KeyValuePair<object, object> item3 in dictionary2) { string text = item3.Key.ToString(); List<string> source; if (item3.Value is string item) { source = new List<string> { item }; } else { if (!(item3.Value is List<object> source2)) { configErrors.Add("groups." + text + " contains an invalid value (" + (item3.Value?.GetType().Name ?? "null") + ")"); continue; } source = source2.Where([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (object s) => s != null).Cast<string>().ToList(); } groups[text.ToLower()] = source.Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (string s) => s.ToLower()).ToList(); } } else { configErrors.Add("groups must contain a mapping from group to a list of group or creature names"); } } else { Section section = this.section(new Section(dictionary, "", null, this), item2.Key); if (section != null) { ParsePrimarySection(section); section.Dispose(); continue; } configErrors.Add("All top-level keys must be a mapping. Got unexpected " + (item2.Value?.GetType().ToString() ?? "null") + " for key '" + item2.Key + "'."); } } } Verify(); } protected virtual void Verify() { } protected abstract void ParsePrimarySection(Section primarySection); [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] private bool parseScalar<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] string input, out T output) where T : struct { if (typeof(int) == typeof(T)) { if (int.TryParse(input, out var result)) { output = (T)(object)result; return true; } } else if (typeof(float) == typeof(T)) { if (float.TryParse(input, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { output = (T)(object)result2; return true; } } else if (typeof(bool) == typeof(T) || typeof(T) == typeof(ItemConfig.Teleportable)) { string[] source = new string[12] { "0", "false", "off", "no", "nope", "nah", "-", "hell no", "pls dont", "lol no", "certainly not", "absolutely not" }; string[] source2 = new string[14] { "1", "true", "on", "yes", "yep", "yeah", "+", "hell yeah", "ok", "okay", "k", "yaaas", "certainly", "absolutely" }; if (source.Contains(input.ToLower())) { output = ((typeof(ItemConfig.Teleportable) == typeof(T)) ? ((T)(object)default(ItemConfig.Teleportable)) : ((T)(object)false)); return true; } if (source2.Contains(input.ToLower())) { output = ((typeof(ItemConfig.Teleportable) == typeof(T)) ? ((T)(object)new ItemConfig.Teleportable { amount = int.MaxValue }) : ((T)(object)true)); return true; } } output = default(T); return false; } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] protected bool ParseScalarFromObject<T>(ref T target, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] Section sect, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] string key) where T : struct { T? target2 = null; if (ParseScalarFromObject(ref target2, sect, key)) { target = target2.Value; return true; } return false; } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] protected bool ParseScalarFromObject<T>(ref T? target, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] Section sect, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] string key) where T : struct { object obj = sect.Get(key); if (obj != null) { if (obj is string input && parseScalar<T>(input, out var output)) { target = output; return true; } configErrors.Add(sect.Path + "." + key + " is not a " + typeof(T).Name + " describing a " + key + " multiplier"); } return false; } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] private bool parseStructFromDict<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] Dictionary<object, object> input, out T output, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] string path) where T : struct { output = default(T); if (!typeof(T).IsPrimitive && !typeof(T).IsEnum) { HashSet<string> hashSet = new HashSet<string>(); FieldInfo[] fields = typeof(T).GetFields(); foreach (FieldInfo fieldInfo in fields) { if (!input.TryGetValue(fieldInfo.Name, out var value)) { continue; } hashSet.Add(fieldInfo.Name); object[] array; if (fieldInfo.FieldType.IsPrimitive || fieldInfo.FieldType.IsEnum) { array = new object[2] { value, null }; if (!(bool)typeof(ConfigFile).GetMethod("parseScalar", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(fieldInfo.FieldType).Invoke(this, array)) { configErrors.Add(path + "." + fieldInfo.Name + " is not " + fieldInfo.FieldType.Name); continue; } } else { array = new object[3] { value, null, path + "." + fieldInfo.FieldType.Name }; typeof(ConfigFile).GetMethod("parseStructFromDict", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(fieldInfo.FieldType).Invoke(this, array); } fieldInfo.SetValue(output, array[1]); } foreach (object key in input.Keys) { if (!hashSet.Contains(key)) { configErrors.Add(string.Format("{0} contains invalid key '{1}'. Allowed keys are {2}.", path, key, string.Join(", ", from f in typeof(T).GetFields() select f.Name))); } } return true; } return false; } [PublicAPI] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] protected float[] ParseProbabilityMap([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] string path, object value) { if (value is List<object> list) { float[] array = new float[list.Count]; for (int i = 0; i < list.Count; i++) { if (list[i] is string s && float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { array[i] = result; } else { configErrors.Add($"{path}[{i}] is not a float denoting a probability"); } } return array; } return null; } protected bool ParseWorldlevelToSingleScalar<[<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 0 })] ref Dictionary<int, T?> target, Section sect, string key) where T : struct { string name = typeof(T).Name; object obj = sect.Get(key); if (obj != null) { T output; if (obj.ToString().ToLower() == "default") { target = Enumerable.Repeat<T?>(null, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T? v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else if (obj is string input && parseScalar<T>(input, out output)) { target = Enumerable.Repeat((T?)output, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T? v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else if (obj is Dictionary<object, object> dictionary) { target = new Dictionary<int, T?>(); bool flag = true; foreach (KeyValuePair<object, object> item in dictionary) { if (int.TryParse(item.Key.ToString(), out var result)) { if (item.Value?.ToString().ToLower() == "default") { target[result] = null; } else if (item.Value is string input2 && parseScalar<T>(input2, out output)) { target[result] = output; } else if (item.Value is Dictionary<object, object> input3 && parseStructFromDict<T>(input3, out output, $"{sect.Path}.{key}.{result}")) { target[result] = output; } else { configErrors.Add($"{sect.Path}.{key}.{result} is not 'default' nor {name}"); } } else { if (!flag && !typeof(T).IsPrimitive && !typeof(T).IsEnum && parseStructFromDict<T>(dictionary, out output, sect.Path + "." + key)) { target = Enumerable.Repeat((T?)output, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T? v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); break; } configErrors.Add($"{sect.Path}.{key} contains a non-integer key {item.Key}"); } flag = false; } } else { configErrors.Add(sect.Path + "." + key + " is not 'default', " + name + " nor Map"); } } return target != null; } protected bool ParseWorldlevelToFloatMap([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] ref Dictionary<int, float[]> target, Section sect, string key) { object obj = sect.Get(key); if (obj != null) { int result; float result2; if (obj.ToString().ToLower() == "default") { target = Enumerable.Repeat<float[]>(null, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (float[] v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else if (key == "stars" && obj is string s && int.TryParse(s, out result)) { float[] element = ((!(sect.dictKey != "sector")) ? ((result < 0) ? Array.Empty<float>() : new float[1] { -result }) : ((result <= 0) ? Array.Empty<float>() : Enumerable.Repeat(0f, result - 1).Concat(new float[1] { 100f }).ToArray())); target = Enumerable.Repeat(element, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (float[] v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else if (key != "stars" && obj is string s2 && float.TryParse(s2, NumberStyles.Float, CultureInfo.InvariantCulture, out result2)) { target = Enumerable.Repeat(new float[1] { result2 }, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (float[] v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else { float[] array = ParseProbabilityMap(sect.Path + "." + key, obj); if (array != null) { target = Enumerable.Repeat(array, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (float[] v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else if (obj is Dictionary<object, object> dictionary) { target = new Dictionary<int, float[]>(); foreach (KeyValuePair<object, object> item in dictionary) { if (int.TryParse(item.Key.ToString(), out var result3)) { if (item.Value?.ToString().ToLower() == "default") { target[result3] = null; continue; } if (key == "stars" && item.Value is string s3 && int.TryParse(s3, out result)) { if (sect.dictKey != "sector") { target[result3] = ((result <= 0) ? Array.Empty<float>() : Enumerable.Repeat(0f, result - 1).Concat(new float[1] { 100f }).ToArray()); } else { target[result3] = ((result < 0) ? Array.Empty<float>() : new float[1] { -result }); } continue; } if (key != "stars" && item.Value is string s4 && float.TryParse(s4, NumberStyles.Float, CultureInfo.InvariantCulture, out var result4)) { target[result3] = new float[1] { result4 }; continue; } float[] array2 = ParseProbabilityMap($"{sect.Path}.{key}.{result3}", item.Value); if (array2 != null) { target[result3] = array2; continue; } configErrors.Add(string.Format("{0}.{1}.{2} is not 'default', {3} nor List", sect.Path, key, result3, (key == "stars") ? "integer" : "float")); } else { configErrors.Add($"{sect.Path}.{key} contains a non-integer key {item.Key}"); } } } else { configErrors.Add(sect.Path + "." + key + " is not 'default', " + ((key == "stars") ? "integer" : "float") + " nor List nor Map"); } } } return target != null; } protected bool ParseEnumConfig<[<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 0, 2 })] ref Dictionary<int, Dictionary<T, float[]>> target, Section sect, string key) where T : struct, IConvertible { List<T> allEnumValues = ((T[])Enum.GetValues(typeof(T))).Where([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T t) => t.ToInt32(CultureInfo.InvariantCulture) != 0).ToList(); object obj = sect.Get(key); if (obj != null) { if (obj.ToString().ToLower() == "default") { target = Enumerable.Repeat(((IEnumerable<T>)allEnumValues).ToDictionary((Func<T, T>)([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T k) => k), (Func<T, float[]>)([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T _) => null)), CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (Dictionary<T, float[]> v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else if (obj is string text) { if (float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { target = Enumerable.Repeat(defaultEntryFromProbability(result), CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (Dictionary<T, float[]> v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else if (typeof(T) != typeof(CreatureLevelControl.ModifyDamage)) { ParseResult<T> parseResult = ParseEnum(text); if (parseResult.error == null) { target = Enumerable.Repeat(new Dictionary<T, float[]> { { parseResult.value, new float[1] { 100f } } }, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (Dictionary<T, float[]> v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); } else { configErrors.Add(sect.Path + "." + key + " contains invalid value " + text + ", expecting default, float, " + parseResult.error + " or dictionary"); } } } else { if (typeof(T) == typeof(CreatureLevelControl.ModifyDamage)) { float[] array = ParseProbabilityMap(sect.Path + "." + key, obj); if (array != null) { target = Enumerable.Repeat(new Dictionary<T, float[]> { { (T)(object)CreatureLevelControl.ModifyDamage.All, array } }, CreatureLevelControl.defaultWorldLevelDays.Length + 1).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (Dictionary<T, float[]> v, int i) => new { v, i }).ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.i, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] k => k.v); goto IL_0653; } } if (obj is Dictionary<object, object> dictionary) { target = new Dictionary<int, Dictionary<T, float[]>>(); if (dictionary.Count > 0) { if (int.TryParse(dictionary.Keys.First().ToString(), out var _)) { foreach (KeyValuePair<object, object> item in dictionary) { if (int.TryParse(item.Key.ToString(), out var result3)) { float result4; if (item.Value?.ToString().ToLower() == "default") { target[result3] = ((IEnumerable<T>)allEnumValues).ToDictionary((Func<T, T>)([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T k) => k), (Func<T, float[]>)([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T _) => null)); } else if (item.Value is string s && float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out result4)) { target[result3] = defaultEntryFromProbability(result4); } else if (item.Value is Dictionary<object, object> affixes2) { target[result3] = ParseAffixProbabilities($"{sect.Path}.{key}[{result3}]", affixes2); } else { configErrors.Add($"{sect.Path}.{key}[{result3}] is not a mapping from affix names to probabilities"); } } else { configErrors.Add(sect.Path + "." + key + " contains mixed world levels and affix names"); } } } else { Dictionary<T, float[]> value = ParseAffixProbabilities(sect.Path + "." + key, dictionary); for (int j = 0; j <= CreatureLevelControl.defaultWorldLevelDays.Length; j++) { target[j] = value; } } } } else { configErrors.Add(sect.Path + "." + key + " is not integer" + ((typeof(T) == typeof(CreatureLevelControl.ModifyDamage)) ? ", List" : "") + ", 'default' nor Map"); } } } goto IL_0653; IL_0653: return target != null; [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0, 2 })] Dictionary<T, float[]> ParseAffixProbabilities([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] string path, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] Dictionary<object, object> affixes) { Dictionary<T, float[]> affixProbabilities = new Dictionary<T, float[]>(); bool hasOther = false; float[] otherValue = null; foreach (KeyValuePair<object, object> affix in affixes) { bool isOther = affix.Key.ToString().ToLower() == "other"; ParseResult<T> result5 = ParseEnum(affix.Key.ToString()); if (isOther || result5.error == null) { float result6; if (affix.Value?.ToString().ToLower() == "default") { assign(null); } else if (affix.Value is string s2 && float.TryParse(s2, NumberStyles.Float, CultureInfo.InvariantCulture, out result6)) { assign(new float[1] { result6 }); } else { float[] array2 = ParseProbabilityMap($"{path}.{affix.Key}", affix.Value); if (array2 != null) { assign(array2); } else { configErrors.Add(string.Format("{0}.{1} (value '{2}') is not a float or list of floats denoting probabilities", path, affix.Key, (affix.Value is string) ? affix.Value : (affix.Value?.GetType().Name ?? "null"))); } } } else { configErrors.Add($"{path} contains unexpected affix key {affix.Key}, expecting either other, {result5.error}"); } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] void assign([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] float[] probabilityArray) { if (isOther) { hasOther = true; otherValue = probabilityArray; } else { affixProbabilities[result5.value] = probabilityArray; } } } if (hasOther) { int undefinedValueCount = allEnumValues.Count - affixProbabilities.Count; if (otherValue != null && undefinedValueCount > 0) { otherValue = otherValue.Select((float p) => p / (float)undefinedValueCount).ToArray(); } foreach (T item2 in allEnumValues) { if (!affixProbabilities.ContainsKey(item2)) { affixProbabilities[item2] = otherValue; } } } return affixProbabilities; } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] ParseResult<T> ParseEnum([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(1)] string name) { ParseResult<T> result8; if (!Enum.TryParse<T>(name, ignoreCase: true, out var result7)) { result8 = default(ParseResult<T>); result8.error = string.Join(", ", allEnumValues.Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T t) => t.ToString())); return result8; } result8 = default(ParseResult<T>); result8.value = result7; return result8; } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0, 2 })] Dictionary<T, float[]> defaultEntryFromProbability(float probability) { if (!(typeof(T) == typeof(CreatureLevelControl.ModifyDamage))) { return allEnumValues.ToDictionary([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T k) => k, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T _) => new float[1] { probability }); } return new Dictionary<T, float[]> { { (T)(object)CreatureLevelControl.ModifyDamage.All, new float[1] { probability } } }; } } } [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(1)] public class CreatureConfig { [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] [Flags] public enum CreatureMode { Default = 0, Tamed = 1, Day = 2, Night = 4, Dungeon = 8, Override = 0x10 } [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] public struct CreatureFilter : IComparable { public CreatureMode Mode; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1 })] public Dictionary<string, bool> GlobalKeys; private string globalKeys() { return "Globalkeys " + string.Join(", ", GlobalKeys.Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<string, bool> kv) => (kv.Value ? "" : "!") + kv.Key)); } public override string ToString() { if (Mode == CreatureMode.Default) { return globalKeys(); } if (GlobalKeys != null) { return $"{Mode}, {globalKeys()}"; } return Mode.ToString(); } public int CompareTo(object obj) { if (obj is CreatureFilter creatureFilter) { int num = 0; if ((Mode & CreatureMode.Override) == 0 == ((creatureFilter.Mode & CreatureMode.Override) == 0)) { if (GlobalKeys == null != (creatureFilter.GlobalKeys == null)) { if (GlobalKeys != null) { return -1; } return 1; } if (GlobalKeys != null && GlobalKeys.Count != creatureFilter.GlobalKeys.Count) { if (GlobalKeys.Count <= creatureFilter.GlobalKeys.Count) { return 1; } return -1; } } CreatureMode[] modePriorities = CreatureConfig.modePriorities; foreach (CreatureMode creatureMode in modePriorities) { if ((Mode & creatureMode) == 0 != ((creatureFilter.Mode & creatureMode) == 0)) { if ((Mode & creatureMode) != 0) { return -1; } return 1; } if (num == 0 && (Mode & creatureMode) != (creatureFilter.Mode & creatureMode)) { num = ((Mode >= creatureFilter.Mode) ? 1 : (-1)); } } if (num == 0 && GlobalKeys != null && creatureFilter.GlobalKeys != null) { List<KeyValuePair<string, bool>> list = GlobalKeys.OrderBy([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<string, bool> kv) => kv.Key).ToList(); List<KeyValuePair<string, bool>> list2 = creatureFilter.GlobalKeys.OrderBy([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<string, bool> kv) => kv.Key).ToList(); for (int j = 0; j < list.Count; j++) { int num2 = string.Compare(list[j].Key, list2[j].Key, StringComparison.Ordinal); if (num2 != 0) { return num2; } if (list[j].Value != list2[j].Value) { if (!list[j].Value) { return 1; } return -1; } } } return num; } return 1; } } [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] public class ConfigFile : global::CreatureLevelControl.ConfigFile { [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] private delegate void Assigner<[<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] T>(ref T current, T input); private readonly Dictionary<string, CreatureConfig> configs = new Dictionary<string, CreatureConfig>(); private static List<string> prefabLocalizations(Character prefab) { return new List<string> { ((Object)prefab).name.ToLower(), prefab.m_name.ToLower(), Localization.instance.Localize(prefab.m_name).ToLower(), CreatureLevelControl.englishLocalization.Localize(prefab.m_name).ToLower() }; } private static List<string> biomeLocalizations(Biome biome) { return new string[3] { ((object)(Biome)(ref biome)).ToString().ToLower(), Localization.instance.Localize("$biome_" + ((object)(Biome)(ref biome)).ToString().ToLower()).ToLower(), CreatureLevelControl.englishLocalization.Localize("$biome_" + ((object)(Biome)(ref biome)).ToString().ToLower()).ToLower() }.Distinct().ToList(); } public Dictionary<string, CreatureConfig> Process() { //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_00e8: 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_00f1: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, CreatureConfig> dictionary = new Dictionary<string, CreatureConfig>(); Biome[] array = new Biome[9]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Biome[] biomeOrder = (Biome[])(object)array; biomeOrder = biomeOrder.Concat(knownBiomes.Where((Biome b) => !biomeOrder.Contains(b))).ToArray(); Dictionary<Biome, List<GameObject>> dictionary2 = new Dictionary<Biome, List<GameObject>>(); foreach (IGrouping<string, SpawnData> item in ZNetScene.instance.GetPrefab("_ZoneCtrl").GetComponent<SpawnSystem>().m_spawnLists.SelectMany([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (SpawnSystemList s) => from p in s.m_spawners where p.m_requiredGlobalKey == "" && Object.op_Implicit((Object)(object)p.m_prefab.gameObject.GetComponent<Character>()) group p by ((Object)p.m_prefab).name)) { Biome val = item.Aggregate((Biome)0, [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (Biome a, SpawnData p) => (Biome)(a | p.m_biome)); Biome[] array2 = biomeOrder; foreach (Biome val2 in array2) { if (((Enum)val).HasFlag((Enum)(object)val2)) { if (!dictionary2.TryGetValue(val2, out var value)) { List<GameObject> list2 = (dictionary2[val2] = new List<GameObject>()); value = list2; } value.Add(item.First().m_prefab); break; } } } foreach (KeyValuePair<Biome, List<GameObject>> item2 in dictionary2) { List<string> value2 = item2.Value.SelectMany([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (GameObject prefab) => prefabLocalizations(prefab.GetComponent<Character>())).ToList(); foreach (string item3 in from biomeName in biomeLocalizations(item2.Key) where !groups.ContainsKey(biomeName) select biomeName) { groups[item3] = value2; } } foreach (Character item4 in from p in ZNetScene.instance.m_prefabs select p.GetComponent<Character>() into c where Object.op_Implicit((Object)(object)c) && !c.IsPlayer() select c) { List<string> list3 = prefabLocalizations(item4); string[] array3 = list3.ToArray(); foreach (string name in array3) { resolveGroupsForName(list3, name); } list3.Add(item4.IsBoss() ? "boss" : "creature"); list3.Add("all"); foreach (string item5 in list3) { if (configs.TryGetValue(item5, out var value3)) { if (!dictionary.TryGetValue(item4.m_name, out var value4)) { CreatureConfig creatureConfig2 = (dictionary[item4.m_name] = new CreatureConfig()); value4 = creatureConfig2; } AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.worldLevelToStars, value3.worldLevelToStars); AssignCreatureModeConfigStruct<float>(value4.sizeScalingFactor, value3.sizeScalingFactor); AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.baseHealth, value3.baseHealth); AssignCreatureModeConfig<Dictionary<int, float?>>(base.AssignConfig, value4.healthGainPerStar, value3.healthGainPerStar); AssignCreatureModeConfig<Dictionary<int, Dictionary<CreatureLevelControl.ModifyDamage, float[]>>>(base.AssignConfig, value4.baseDamage, value3.baseDamage); AssignCreatureModeConfig<Dictionary<int, float?>>(base.AssignConfig, value4.damageGainPerStar, value3.damageGainPerStar); AssignCreatureModeConfig<Dictionary<int, float?>>(base.AssignConfig, value4.attackSpeedGainPerStar, value3.attackSpeedGainPerStar); AssignCreatureModeConfig<Dictionary<int, float?>>(base.AssignConfig, value4.movementSpeedGainPerStar, value3.movementSpeedGainPerStar); AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.baseMovementSpeed, value3.baseMovementSpeed); AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.baseAttackSpeed, value3.baseAttackSpeed); AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.spawnAmount, value3.spawnAmount); AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.sectorCount, value3.sectorCount); AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.sectorStars, value3.sectorStars); AssignCreatureModeConfig<Dictionary<int, float[]>>(base.AssignConfig, value4.worldLevelToLootAmount, value3.worldLevelToLootAmount); AssignCreatureModeConfig<Dictionary<int, float?>>(base.AssignConfig, value4.worldLevelToLootPerStar, value3.worldLevelToLootPerStar); AssignCreatureModeConfig<Dictionary<int, Dictionary<CreatureExtraEffect, float[]>>>(base.AssignEnumConfig, value4.worldLevelToCreatureEffect, value3.worldLevelToCreatureEffect); AssignCreatureModeConfig<Dictionary<int, Dictionary<CreatureExtraEffect, float[]>>>(base.AssignEnumConfig, value4.worldLevelToCreatureEffectFactor, value3.worldLevelToCreatureEffectFactor); AssignEnumConfig(ref value4.worldLevelToBoss, value3.worldLevelToBoss); AssignEnumConfig(ref value4.worldLevelToBossAffixFactor, value3.worldLevelToBossAffixFactor); AssignCreatureModeConfig<Dictionary<int, Dictionary<CreatureInfusion, float[]>>>(base.AssignEnumConfig, value4.worldLevelToInfusion, value3.worldLevelToInfusion); AssignCreatureModeConfig<Dictionary<int, Dictionary<CreatureLevelControl.ModifyDamage, float[]>>>(base.AssignEnumConfig, value4.worldLevelToDamageTakenModifier, value3.worldLevelToDamageTakenModifier); } } if (dictionary.TryGetValue(item4.m_name, out var value5)) { fillModeWorldLevels<float[]>(value5.worldLevelToStars); fillModeWorldLevels<Dictionary<CreatureExtraEffect, float[]>>(value5.worldLevelToCreatureEffect); fillModeWorldLevels<Dictionary<CreatureExtraEffect, float[]>>(value5.worldLevelToCreatureEffectFactor); fillWorldLevels(value5.worldLevelToBoss); fillWorldLevels(value5.worldLevelToBossAffixFactor); fillModeWorldLevels<Dictionary<CreatureInfusion, float[]>>(value5.worldLevelToInfusion); fillModeWorldLevels<Dictionary<CreatureLevelControl.ModifyDamage, float[]>>(value5.worldLevelToDamageTakenModifier); fillModeWorldLevels<float[]>(value5.baseHealth); fillModeWorldLevels<float?>(value5.healthGainPerStar); fillModeWorldLevels<Dictionary<CreatureLevelControl.ModifyDamage, float[]>>(value5.baseDamage); fillModeWorldLevels<float?>(value5.damageGainPerStar); fillModeWorldLevels<float[]>(value5.baseMovementSpeed); fillModeWorldLevels<float?>(value5.movementSpeedGainPerStar); fillModeWorldLevels<float[]>(value5.baseAttackSpeed); fillModeWorldLevels<float?>(value5.attackSpeedGainPerStar); fillModeWorldLevels<float[]>(value5.spawnAmount); fillModeWorldLevels<float[]>(value5.sectorCount); fillModeWorldLevels<float[]>(value5.sectorStars); fillModeWorldLevels<float[]>(value5.worldLevelToLootAmount); fillModeWorldLevels<float?>(value5.worldLevelToLootPerStar); } } return dictionary; static void AssignCreatureModeConfig<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0 })] Assigner<T> assigner, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0 })] SortedDictionary<CreatureFilter, T> newConfig, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0 })] SortedDictionary<CreatureFilter, T> inConfig) where T : class { foreach (CreatureFilter item6 in newConfig.Keys.Concat(inConfig.Keys).ToList()) { T value9; if (!newConfig.TryGetValue(item6, out var value7)) { if (inConfig.TryGetValue(item6, out var value8)) { newConfig[item6] = value8; } } else if (inConfig.TryGetValue(item6, out value9)) { assigner(ref value7, value9); newConfig[item6] = value7; } } } static void AssignCreatureModeConfigStruct<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0 })] SortedDictionary<CreatureFilter, T> newConfig, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0 })] SortedDictionary<CreatureFilter, T> inConfig) where T : struct { foreach (CreatureFilter item7 in newConfig.Keys.Concat(inConfig.Keys).ToList()) { if (!newConfig.ContainsKey(item7) && inConfig.TryGetValue(item7, out var value6)) { newConfig[item7] = value6; } } } void fillModeWorldLevels<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 0 })] SortedDictionary<CreatureFilter, Dictionary<int, T>> config) { config.Values.ToList().ForEach(base.fillWorldLevels); } } private SortedDictionary<CreatureFilter, Section> getSections(Section parentSection) { //IL_00c2: 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) SortedDictionary<CreatureFilter, Section> sections = new SortedDictionary<CreatureFilter, Section> { { default(CreatureFilter), parentSection } }; foreach (CreatureMode item in ((CreatureMode[])Enum.GetValues(typeof(CreatureMode))).Where((CreatureMode v) => v != CreatureMode.Default)) { creatureModeSection(item, new string[1] { item.ToString().ToLower() }); } Biome[] knownBiomes = CreatureConfig.knownBiomes; foreach (Biome biome in knownBiomes) { creatureModeSection(biomeToCreatureMode(biome), biomeLocalizations(biome)); } readGlobalkeys("key_", present: true); readGlobalkeys("nokey_", present: false); return sections; void creatureModeSection(CreatureMode mode, IEnumerable<string> localizations) { Section section3 = localizations.Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (string localizedKey) => section(parentSection, localizedKey)).FirstOrDefault([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (Section section) => section != null); if (section3 != null) { foreach (KeyValuePair<CreatureFilter, Section> section4 in getSections(section3)) { CreatureFilter key2 = section4.Key; key2.Mode |= mode; sections[key2] = section4.Value; } } } void readGlobalkeys(string prefix, bool present) { foreach (string item2 in parentSection.KeysWithPrefix(prefix)) { Section section2 = section(parentSection, item2); if (section2 != null) { foreach (KeyValuePair<CreatureFilter, Section> section5 in getSections(section2)) { CreatureFilter key = section5.Key; key.GlobalKeys = ((key.GlobalKeys != null) ? new Dictionary<string, bool>(key.GlobalKeys) : new Dictionary<string, bool>()); key.GlobalKeys[item2.Substring(prefix.Length)] = present; sections[key] = section5.Value; } } } } } protected override void ParsePrimarySection(Section creatureSection) { string key = creatureSection.dictKey.ToLower(); if (!configs.TryGetValue(key, out var value)) { value = (configs[key] = new CreatureConfig()); } SortedDictionary<CreatureFilter, Section> sections = getSections(creatureSection); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.worldLevelToStars, sections, "stars"); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.worldLevelToLootAmount, sections, "loot"); AssignCreatureMode(base.ParseWorldlevelToSingleScalar, value.worldLevelToLootPerStar, sections, "loot per star"); AssignCreatureMode(base.ParseScalarFromObject, value.sizeScalingFactor, sections, "size"); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.baseHealth, sections, "health"); AssignCreatureMode(base.ParseWorldlevelToSingleScalar, value.healthGainPerStar, sections, "health per star"); AssignCreatureMode(base.ParseEnumConfig, value.baseDamage, sections, "damage"); AssignCreatureMode(base.ParseWorldlevelToSingleScalar, value.damageGainPerStar, sections, "damage per star"); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.baseAttackSpeed, sections, "attack speed"); AssignCreatureMode(base.ParseWorldlevelToSingleScalar, value.attackSpeedGainPerStar, sections, "attack speed per star"); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.baseMovementSpeed, sections, "movement speed"); AssignCreatureMode(base.ParseWorldlevelToSingleScalar, value.movementSpeedGainPerStar, sections, "movement speed per star"); AssignCreatureMode(base.ParseEnumConfig, value.worldLevelToDamageTakenModifier, sections, "damage taken"); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.spawnAmount, sections, "amount"); AssignCreatureMode(base.ParseEnumConfig, value.worldLevelToCreatureEffect, sections, "effect"); AssignCreatureMode(base.ParseEnumConfig, value.worldLevelToCreatureEffectFactor, sections, "effect power"); ParseEnumConfig(ref value.worldLevelToBoss, creatureSection, "affix"); ParseEnumConfig(ref value.worldLevelToBossAffixFactor, creatureSection, "affix power"); AssignCreatureMode(base.ParseEnumConfig, value.worldLevelToInfusion, sections, "infusion"); using Section section = base.section(creatureSection, "sector"); if (section != null) { SortedDictionary<CreatureFilter, Section> sections2 = getSections(section); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.sectorCount, sections2, "count"); AssignCreatureMode(base.ParseWorldlevelToFloatMap, value.sectorStars, sections2, "stars"); } sections.Remove(default(CreatureFilter)); foreach (Section value2 in sections.Values) { value2.Dispose(); } } private static void AssignCreatureMode<[<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] T>(ParserDelegate<T> parser, SortedDictionary<CreatureFilter, T> target, SortedDictionary<CreatureFilter, Section> sections, string key) { foreach (KeyValuePair<CreatureFilter, Section> section in sections) { target.TryGetValue(default(CreatureFilter), out var value); if (parser(ref value, section.Value, key)) { target[section.Key] = value; } } } protected override void Verify() { foreach (KeyValuePair<string, CreatureConfig> config in configs) { KeyValuePair<string, CreatureConfig> configKv = config; foreach (KeyValuePair<CreatureFilter, Dictionary<int, float[]>> worldLevelToStar in configKv.Value.worldLevelToStars) { float[] array = null; foreach (KeyValuePair<int, float[]> item in worldLevelToStar.Value) { float[] value = item.Value; if (value != null && value.Sum() > 100.0001f && (array == null || !array.SequenceEqual(item.Value))) { array = item.Value; configWarnings.Add(string.Format("{0}{1} has a sum of probabilities greater than 100% for its 'stars' setting at world level {2}. Note that the sum of probabilites for individual star levels MUST be equal or lower than 100%, otherwise probabilities exceeding 100% will be ignored.\nWith the current configuration this group would have the following base probabilities: {3}.", configKv.Key, worldLevelToStar.Key.Equals(default(CreatureFilter)) ? "" : $" in {worldLevelToStar.Key} mode", item.Key, string.Join(", ", API.zeroProbabilities(item.Value).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (float p, int i) => $"{i} stars: {p}%")))); } } } checkEffectProbabilities<CreatureExtraEffect>(configKv.Value.worldLevelToCreatureEffect, CreatureLevelControl.customCreatureAffixChances, "creature special effect"); checkEffectProbabilities<CreatureInfusion>(configKv.Value.worldLevelToInfusion, CreatureLevelControl.customCreatureInfusionChances, "creature infusion"); SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<BossAffix, float[]>>> sortedDictionary = new SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<BossAffix, float[]>>>(); if (configKv.Value.worldLevelToBoss != null) { sortedDictionary[default(CreatureFilter)] = configKv.Value.worldLevelToBoss; } checkEffectProbabilities<BossAffix>(sortedDictionary, CreatureLevelControl.customBossAffixChances, "boss affix"); void checkEffectProbabilities<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 0, 2 })] SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<T, float[]>>> dict, [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0, 1 })] Dictionary<T, ConfigEntry<float>> defaultsDict, string nameString) where T : struct, IConvertible { foreach (KeyValuePair<CreatureFilter, Dictionary<int, Dictionary<T, float[]>>> item2 in dict) { Dictionary<T, float> dictionary = null; foreach (KeyValuePair<int, Dictionary<T, float[]>> item3 in item2.Value) { int num = item3.Value.Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<T, float[]> v) => (v.Value ?? new float[1]).Length).DefaultIfEmpty(1).Max(); for (int j = 0; j < num; j++) { bool flag = false; Dictionary<T, float> dictionary2 = new Dictionary<T, float>(); Dictionary<T, float> dictionary3 = new Dictionary<T, float>(); foreach (T item4 in ((T[])Enum.GetValues(typeof(T))).Where([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (T e) => e.ToInt32(CultureInfo.InvariantCulture) != 0)) { float num3; if (item3.Value.TryGetValue(item4, out var value2) && value2 != null && value2.Length != 0) { num3 = (dictionary3[item4] = value2[(j < value2.Length) ? j : (value2.Length - 1)]); } else { num3 = defaultsDict[item4].Value; if (num3 > 0f) { flag = true; } } dictionary2[item4] = num3; } if (dictionary2.Values.Sum() > 101.1f && Mathf.Abs(dictionary3.Values.Sum() - 100f) > 1.1f && (dictionary == null || !dictionary.SequenceEqual(dictionary2))) { bool flag2 = dictionary3.Values.Sum() < 100f; dictionary = dictionary2; configWarnings.Add(string.Format("{0}{1} has a sum of {2} chances greater than 100% for {3} stars at world level {4}{5}. Some effects may not happen at all with the current configuration. Specified chances are: {6}.", configKv.Key, item2.Key.Equals(default(CreatureFilter)) ? "" : $" in configuration {item2.Key}", nameString, j, item3.Key, (flag && flag2) ? " (including default probabilities from config)" : "", string.Join(", ", (flag2 ? dictionary2 : dictionary3).Select([<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] (KeyValuePair<T, float> kv) => $"{kv.Key}: {kv.Value}%")))); } } } } } } } } [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] public class Loader : global::CreatureLevelControl.ConfigFile.Loader { [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(2)] public global::CreatureLevelControl.ConfigFile ConfigFile { [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] get { return CreatureLevelControl.creatureConfigFile; } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(2)] set { CreatureLevelControl.creatureConfigFile = (ConfigFile)value; } } public string FilePattern => "CreatureConfig*.yml"; public string EditButtonName => LocalizationWrapper.getTranslation("Edit Creature YAML config"); public CustomSyncedValue<List<string>> FileData => CreatureLevelControl.creatureConfigFileData; public bool Enabled => CreatureLevelControl.creatureConfigFileActive.GetToggle(); public global::CreatureLevelControl.ConfigFile InstantiateConfig() { return new ConfigFile(); } public void ProcessConfig() { CreatureLevelControl.PrefabConfig = CreatureLevelControl.creatureConfigFile.Process(); } } private const int BiomeOffset = 5; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> worldLevelToStars = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureExtraEffect, float[]>>> worldLevelToCreatureEffect = new SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureExtraEffect, float[]>>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureExtraEffect, float[]>>> worldLevelToCreatureEffectFactor = new SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureExtraEffect, float[]>>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureInfusion, float[]>>> worldLevelToInfusion = new SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureInfusion, float[]>>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 2 })] public Dictionary<int, Dictionary<BossAffix, float[]>> worldLevelToBoss; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 2, 1, 2 })] public Dictionary<int, Dictionary<BossAffix, float[]>> worldLevelToBossAffixFactor; public readonly SortedDictionary<CreatureFilter, float> sizeScalingFactor = new SortedDictionary<CreatureFilter, float>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> baseHealth = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); public readonly SortedDictionary<CreatureFilter, Dictionary<int, float?>> healthGainPerStar = new SortedDictionary<CreatureFilter, Dictionary<int, float?>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureLevelControl.ModifyDamage, float[]>>> baseDamage = new SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureLevelControl.ModifyDamage, float[]>>>(); public readonly SortedDictionary<CreatureFilter, Dictionary<int, float?>> damageGainPerStar = new SortedDictionary<CreatureFilter, Dictionary<int, float?>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> baseMovementSpeed = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); public readonly SortedDictionary<CreatureFilter, Dictionary<int, float?>> movementSpeedGainPerStar = new SortedDictionary<CreatureFilter, Dictionary<int, float?>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> baseAttackSpeed = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); public readonly SortedDictionary<CreatureFilter, Dictionary<int, float?>> attackSpeedGainPerStar = new SortedDictionary<CreatureFilter, Dictionary<int, float?>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> spawnAmount = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> sectorCount = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> sectorStars = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureLevelControl.ModifyDamage, float[]>>> worldLevelToDamageTakenModifier = new SortedDictionary<CreatureFilter, Dictionary<int, Dictionary<CreatureLevelControl.ModifyDamage, float[]>>>(); [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 1, 2 })] public readonly SortedDictionary<CreatureFilter, Dictionary<int, float[]>> worldLevelToLootAmount = new SortedDictionary<CreatureFilter, Dictionary<int, float[]>>(); public readonly SortedDictionary<CreatureFilter, Dictionary<int, float?>> worldLevelToLootPerStar = new SortedDictionary<CreatureFilter, Dictionary<int, float?>>(); private static Biome[] knownBiomes => ((Biome[])Enum.GetValues(typeof(Biome))).Where((Biome b) => (int)b > 0).ToArray(); private static CreatureMode[] modePriorities { get { CreatureMode[] obj = new CreatureMode[5] { CreatureMode.Override, CreatureMode.Tamed, CreatureMode.Dungeon, CreatureMode.Default, CreatureMode.Day | CreatureMode.Night }; obj[3] = knownBiomes.Aggregate(CreatureMode.Default, (CreatureMode a, Biome m) => a | biomeToCreatureMode(m)); return obj; } } public static CreatureMode biomeToCreatureMode(Biome biome) { //IL_0000: 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_0004: Expected I4, but got Unknown return (CreatureMode)(biome << 5); } } [BepInPlugin("org.bepinex.plugins.creaturelevelcontrol", "Creature Level & Loot Control", "4.6.4")] [BepInIncompatibility("org.bepinex.plugins.valheim_plus")] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(1)] [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class CreatureLevelControl : BaseUnityPlugin { [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] public enum Difficulty { [LocalizationWrapper.Localized(Difficulty.Custom)] Custom, [LocalizationWrapper.Localized(Difficulty.Very_easy)] Very_easy, [LocalizationWrapper.Localized(Difficulty.Easy)] Easy, [LocalizationWrapper.Localized(Difficulty.Medium)] Medium, [LocalizationWrapper.Localized(Difficulty.Hard)] Hard, [LocalizationWrapper.Localized(Difficulty.Very_hard)] Very_hard, [LocalizationWrapper.Localized(Difficulty.Insane)] Insane } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] public enum CreatureSectorAnnouncementScope { [LocalizationWrapper.Localized(CreatureSectorAnnouncementScope.Local)] Local, [LocalizationWrapper.Localized(CreatureSectorAnnouncementScope.Global)] Global, [LocalizationWrapper.Localized(CreatureSectorAnnouncementScope.Off)] Off } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] public enum LootSystem { [LocalizationWrapper.Localized(LootSystem.Vanilla)] Vanilla, [LocalizationWrapper.Localized(LootSystem.Linear)] Linear, [LocalizationWrapper.Localized(LootSystem.CalculateChance)] CalculateChance, [LocalizationWrapper.Localized(LootSystem.CalculateAmount)] CalculateAmount } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] private enum VisualLevelIndicator { [LocalizationWrapper.Localized(VisualLevelIndicator.Off)] Off, [LocalizationWrapper.Localized(VisualLevelIndicator.On)] On, [LocalizationWrapper.Localized(VisualLevelIndicator.BossesOff)] BossesOff, [LocalizationWrapper.Localized(VisualLevelIndicator.CreaturesOff)] CreaturesOff } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] private enum AllowedConsoleCommands { [LocalizationWrapper.Localized(AllowedConsoleCommands.CreatureCommands)] CreatureCommands, [LocalizationWrapper.Localized(AllowedConsoleCommands.InformationCommands)] InformationCommands, [LocalizationWrapper.Localized(AllowedConsoleCommands.None)] None } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] private enum VisualExtraEffectIndicator { [LocalizationWrapper.Localized(VisualExtraEffectIndicator.Color)] Color, [LocalizationWrapper.Localized(VisualExtraEffectIndicator.Text)] Text, [LocalizationWrapper.Localized(VisualExtraEffectIndicator.Both)] Both } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] public enum DifficultySecondFactor { [LocalizationWrapper.Localized(DifficultySecondFactor.None)] None, [LocalizationWrapper.Localized(DifficultySecondFactor.Age_of_world)] Age_of_world, [LocalizationWrapper.Localized(DifficultySecondFactor.Distance)] Distance, [LocalizationWrapper.Localized(DifficultySecondFactor.BossesKilled)] BossesKilled } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] public enum SpawnLevel { [LocalizationWrapper.Localized(SpawnLevel.None)] None, [LocalizationWrapper.Localized(SpawnLevel.One)] One, [LocalizationWrapper.Localized(SpawnLevel.Two)] Two, [LocalizationWrapper.Localized(SpawnLevel.Three)] Three, [LocalizationWrapper.Localized(SpawnLevel.Four)] Four, [LocalizationWrapper.Localized(SpawnLevel.Five)] Five } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] public enum CreatureSectorWorldLevel { [LocalizationWrapper.Localized(CreatureSectorWorldLevel.Disabled)] Disabled = -1, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.None)] None, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.One)] One, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.Two)] Two, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.Three)] Three, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.Four)] Four, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.Five)] Five, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.Six)] Six, [LocalizationWrapper.Localized(CreatureSectorWorldLevel.Seven)] Seven } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] public enum ModifyDamage { All, Fire, Frost, Poison, Lightning, Spirit, Elemental, Blunt, Slash, Pierce, Chop, Physical, Knives, Bows, Crossbows, ElementalMagic, BloodMagic, Swords, Spears, Pickaxes, Axes, Clubs, Polearms, Weapons, Unarmed } [HarmonyPatch(typeof(Game), "GetPlayerDifficulty")] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] private class PatchPlayerCount { [UsedImplicitly] private static void Postfix(ref int __result) { __result = Mathf.Min(maximumMultiplayerPlayerCount.Value, Mathf.Max(minimumMultiplayerPlayerCount.Value, additionalMultiplayerPlayerCount.Value + __result)); } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] [HarmonyPatch(typeof(Terminal), "TryRunCommand")] private class PatchTerminal { [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(1)] [UsedImplicitly] private static bool Prefix(Terminal __instance, string text) { //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) if (!text.ToLower().StartsWith("cllc")) { return true; } bool flag = true; string[] array = text.ToLower().Split(new char[1] { ' ' }); bool flag2 = !configSync.IsLocked; bool flag3 = false; if (array.Length > 1 && array[1] == "killhighstars") { flag = false; if (flag2 || allowedConsoleCommands.Value == AllowedConsoleCommands.CreatureCommands) { if (array.Length <= 2 || !int.TryParse(array[2], out var result)) { result = 6; } Character[] array2 = Object.FindObjectsOfType<Character>(); foreach (Character val in array2) { if (val.IsPlayer() || val.GetLevel() - 1 < result) { continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (component != null) { ZDO zDO = component.GetZDO(); if (zDO != null) { zDO.SetOwner(ZDOMan.instance.m_sessionID); } } Object.Destroy((Object)(object)((Component)val).GetComponent<CharacterDrop>()); ZNetScene.instance.Destroy(((Component)val).gameObject); } __instance.AddString("Removed all nearby creatures with at least " + result + " stars"); } else { flag3 = true; } } else if (array.Length > 1 && array[1] == "killall") { flag = false; if (flag2 || allowedConsoleCommands.Value == AllowedConsoleCommands.CreatureCommands) { Character[] array2 = Object.FindObjectsOfType<Character>(); foreach (Character val2 in array2) { if (val2.IsPlayer()) { continue; } ZNetView component2 = ((Component)val2).GetComponent<ZNetView>(); if (component2 != null) { ZDO zDO2 = component2.GetZDO(); if (zDO2 != null) { zDO2.SetOwner(ZDOMan.instance.m_sessionID); } } Object.Destroy((Object)(object)((Component)val2).GetComponent<CharacterDrop>()); ZNetScene.instance.Destroy(((Component)val2).gameObject); } __instance.AddString("Removed all nearby creatures"); } else { flag3 = true; } } else if (array.Length > 1 && array[1] == "worldlevel") { flag = false; if (flag2 || allowedConsoleCommands.Value != AllowedConsoleCommands.None) { __instance.AddString("Current world level: " + API.GetWorldLevel()); } else { flag3 = true; } } else if (array.Length > 1 && array[1] == "sectorkills") { flag = false; if (flag2 || allowedConsoleCommands.Value != AllowedConsoleCommands.None) { __instance.AddString("Kills in the current sector: " + (CreatureSector.currentSector(((Component)Player.m_localPlayer).GetComponent<ZNetView>())?.sectorKills ?? 0f)); } else { flag3 = true; } } else if (array.Length > 1 && array[1] == "resetsector") { flag = false; if (flag2 || allowedConsoleCommands.Value == AllowedConsoleCommands.CreatureCommands) { CreatureSector.resetSectorKills(((Component)Player.m_localPlayer).GetComponent<ZNetView>()); __instance.AddString("Reset all nearby creature sectors"); } else { flag3 = true; } } else if (array.Length > 1 && array[1] == "starchance") { flag = false; if (flag2 || allowedConsoleCommands.Value != AllowedConsoleCommands.None) { object obj; if (array.Length <= 2) { obj = null; } else { GameObject prefab = ZNetScene.instance.GetPrefab(text.Split(new char[1] { ' ' })[2]); obj = ((prefab != null) ? prefab.GetComponent<Character>() : null); } Character val3 = (Character)obj; int num = 0; __instance.AddString("Current star chances" + ((val3 == null) ? "" : (" for " + Localization.instance.Localize(val3.m_name))) + ":"); float[] array3 = API.LevelProbabilities(val3, API.GetWorldLevel(), includeZoneBonusLevel: true); foreach (float num2 in array3) { __instance.AddString(num++ + " star: " + num2.ToString(CultureInfo.InvariantCulture) + "%"); } } else { flag3 = true; } } else if (array.Length > 2 && array[1] == "spawn") { flag = false; if (flag2 || allowedConsoleCommands.Value == AllowedConsoleCommands.CreatureCommands) { string text2 = text.Split(new char[1] { ' ' })[2]; GameObject prefab2 = ZNetScene.instance.GetPrefab(text2); if ((Object)(object)prefab2 == (Object)null || !Object.op_Implicit((Object)(object)prefab2.GetComponent<Character>())) { __instance.AddString(text2 + " is not a creature"); return false; } ((Character)Player.m_localPlayer).Message((MessageType)1, "Spawning object " + ((Object)prefab2).name, 0, (Sprite)null); Transform transform = ((Component)Player.m_localPlayer).transform; Character character = Object.Instantiate<GameObject>(prefab2, transform.position + transform.forward * 2f + Vector3.up, Quaternion.identity).GetComponent<Character>(); foreach (string item in array.Skip(3)) { string effectName = item; if (int.TryParse(effectName, out var result2)) { character.SetLevel(result2); continue; } bool matched = false; if (character.IsBoss()) { loop<BossAffix>(delegate(BossAffix affix) { API.SetAffixBoss(character, affix); }); } else { loop<CreatureInfusion>(delegate(CreatureInfusion infusion) { API.SetInfusionCreature(character, infusion); }); loop<CreatureExtraEffect>(delegate(CreatureExtraEffect effect) { API.SetExtraEffectCreature(character, effect); }); } if (!matched) { __instance.AddString("Unknown effect " + effectName); } void loop<T>([<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 1, 0 })] Action<T> apply) { T[] array4 = (T[])Enum.GetValues(typeof(T)); for (int j = 0; j < array4.Length; j++) { T obj2 = array4[j]; if (string.Equals(obj2.ToString(), effectName, StringComparison.CurrentCultureIgnoreCase)) { apply(obj2); matched = true; } } } } } else { flag3 = true; } } if (flag) { __instance.AddString("CLLC console commands - use 'cllc' followed by one of the following options"); __instance.AddString("killhighstars [stars] - removes all nearby creatures with at least stars. Default stars is 6."); __instance.AddString("killall - removes all nearby creatures"); __instance.AddString("worldlevel - displays the current world level"); __instance.AddString("sectorkills - displays the creatures killed in the current sector"); __instance.AddString("resetsector - resets all nearby creature sectors"); __instance.AddString("starchance [creature] - displays the current star chances. Optionally for a specific creature."); __instance.AddString("spawn [creature] [level] [affix] [extraeffect] [infusion] - spawns a creature with the provided properties."); } if (flag3) { __instance.AddString("You are not allowed to use this command on this server."); } return false; } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] [HarmonyPatch(typeof(Game), "GetDifficultyDamageScalePlayer")] private class PatchDamageFactor { [UsedImplicitly] private static void Postfix(ref float __result) { __result = (float)((double)(__result - 1f) / 0.04 * (double)multiplayerDMGfactor.Value / 100.0) + 1f; } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] [HarmonyPatch(typeof(Game), "GetDifficultyDamageScaleEnemy")] private class PatchHealthFactor { [UsedImplicitly] private static void Postfix(ref float __result) { __result = 1f / ((float)((double)(1f / __result - 1f) / 0.4 * (double)multiplayerHPfactor.Value / 100.0) + 1f); } } [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(0)] [HarmonyPatch(typeof(Attack), "GetLevelDamageFactor")] private class PatchDamageStarFactor { [UsedImplicitly] [<a56b5d22-7ddd-46b2-a7eb-83a6facc76b7>NullableContext(1)] private static void Postfix(Attack __instance, ref float __result) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!((Character)(Humanoid)AccessTools.DeclaredField(typeof(Attack), "m_character").GetValue(__instance)).IsPlayer()) { __result = 1f; } } } [HarmonyPatch(typeof(Character), "SetupMaxHealth")] [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] private class PatchHealthStarFactor { [CompilerGenerated] private sealed class <Transpiler>d__2 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 0, 1 })] private IEnumerable<CodeInstruction> instructions; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 0, 1 })] public IEnumerable<CodeInstruction> <>3__instructions; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(new byte[] { 0, 1 })] private IEnumerator<CodeInstruction> <>7__wrap1; [<75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] private CodeInstruction <instruction>5__3; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] get { return <>2__current; } } [DebuggerHidden] public <Transpiler>d__2(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 2u) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = null; <instruction>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; if (<instruction>5__3.opcode == OpCodes.Conv_R4) { <>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null); <>1__state = 2; return true; } goto IL_00df; case 2: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)HealthFactorApplier); <>1__state = 3; return true; case 3: { <>1__state = -3; goto IL_00df; } IL_00df: <instruction>5__3 = null; break; } if (<>7__wrap1.MoveNext()) { <instruction>5__3 = <>7__wrap1.Current; <>2__current = <instruction>5__3; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <Transpiler>d__2 <Transpiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <Transpiler>d__ = this; } else { <Transpiler>d__ = new <Transpiler>d__2(0); } <Transpiler>d__.instructions = <>3__instructions; return <Transpiler>d__; } [DebuggerHidden] [return: <75b8e597-2006-46dc-8007-b4ba3b036dbf>Nullable(0)] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } private static readonly MethodInfo HealthFactorApplier = AccessTools.DeclaredMethod(typeof(PatchHealthStarFactor), "applyHealthFactor", (Type[])null, (Type[])null); private static float applyHealthFactor(float level, Character character) { int usedStars; float num = Utils.ReadWithWorldLevelAndStarsFromConfig