Please disclose if any significant portion of your mod was created 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 VikingFoes v0.1.1
VikingFoes.dll
Decompiled 3 days agousing System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; using VikingFoes.Commands; using VikingFoes.Configuration; using VikingFoes.Core; using VikingFoes.Integration; using VikingFoes.Registries; using VikingLib.Combat; using VikingLib.Combat.Defense; using VikingLib.Combat.Stagger; using VikingLib.Combat.Telemetry; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DigitalVikings")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Library of enemy stat overhauls, calibrated armor curves, and smooth biome progression for Valheim and VikingLib.")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1+2d3cc9ea60906e85ba29581bb3e30e7e90abca3c")] [assembly: AssemblyProduct("VikingFoes")] [assembly: AssemblyTitle("VikingFoes")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VikingFoes { [BepInPlugin("com.digitalvikings.vikingfoes", "VikingFoes", "0.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class VikingFoesPlugin : BaseUnityPlugin { public const string ModGuid = "com.digitalvikings.vikingfoes"; public const string ModName = "VikingFoes"; public const string ModVersion = "0.1.1"; internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"VikingFoes v0.1.1 initializing..."); ModConfig.Init(((BaseUnityPlugin)this).Config); FoeRegistry.Init(); VikingLibIntegration.Init(); _harmony = new Harmony("com.digitalvikings.vikingfoes"); _harmony.PatchAll(); if (Chainloader.PluginInfos.ContainsKey("com.jotunn.jotunn")) { RegisterCommands(); HookJotunnSync(); } Log.LogInfo((object)"VikingFoes v0.1.1 loaded successfully."); } [MethodImpl(MethodImplOptions.NoInlining)] private void RegisterCommands() { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new FoeInfoConsoleCommand()); } [MethodImpl(MethodImplOptions.NoInlining)] private void HookJotunnSync() { SynchronizationManager.OnConfigurationSynchronized += delegate { Log.LogInfo((object)"Server configuration synchronized successfully."); }; } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace VikingFoes.Registries { public static class FoeRegistry { private static readonly ConcurrentDictionary<string, FoeDefinition> _definitions; private static readonly ConcurrentDictionary<string, string> _aliases; static FoeRegistry() { _definitions = new ConcurrentDictionary<string, FoeDefinition>(StringComparer.OrdinalIgnoreCase); _aliases = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase) { ["GreydwarfBrute"] = "Greydwarf_Elite", ["Greydwarf_Brute"] = "Greydwarf_Elite", ["SeaSerpent"] = "Serpent" }; InitDefaults(); } public static void Init() { } public static void Register(FoeDefinition definition) { if (definition != null) { string key = CleanPrefabName(definition.PrefabName); _definitions[key] = definition; } } public static bool TryGet(string prefabName, out FoeDefinition definition) { if (string.IsNullOrWhiteSpace(prefabName)) { definition = null; return false; } string key = CleanPrefabName(prefabName); if (_aliases.TryGetValue(key, out string value)) { key = value; } return _definitions.TryGetValue(key, out definition); } public static IEnumerable<FoeDefinition> GetAll() { return _definitions.Values; } public static string GetCleanPrefabName(Character? character) { if ((Object)(object)character == (Object)null) { return string.Empty; } string text = string.Empty; try { if ((Object)(object)((Component)character).gameObject != (Object)null) { text = Utils.GetPrefabName(((Component)character).gameObject); } } catch { } if (string.IsNullOrEmpty(text)) { text = character.m_name; } if (string.IsNullOrEmpty(text)) { try { text = ((Object)character).name; } catch { } } return CleanPrefabName(text ?? string.Empty); } public static string CleanPrefabName(string rawName) { if (string.IsNullOrWhiteSpace(rawName)) { return string.Empty; } string text = rawName; int num = text.IndexOf("(Clone)", StringComparison.OrdinalIgnoreCase); if (num >= 0) { text = text.Substring(0, num); } return text.Trim(); } private static void InitDefaults() { Register(new FoeDefinition("Boar").SetBaseHealth(13f).SetPhysicalDamageType((DamageType)1).SetResistance((DamageType)2, 1.25f) .SetPoiseThreshold(18f) .AddOnHitAffliction("SE_Bleed", 4f, 4f, 0.25f)); Register(new FoeDefinition("Greydwarf").SetResistance((DamageType)2, 0.8f)); Register(new FoeDefinition("Greydwarf_Shaman").SetResistance((DamageType)2, 0.8f)); Register(new FoeDefinition("Greydwarf_Elite").SetPhysicalDamageType((DamageType)0).SetResistance((DamageType)2, 0.8f).SetPoiseThreshold(85f)); Register(new FoeDefinition("Serpent").SetPhysicalDamageType((DamageType)2).SetResistance((DamageType)7, 1.25f).SetPoiseThreshold(120f) .AddOnHitAffliction("SE_Bleed", 12f, 6f, 0.75f)); Register(new FoeDefinition("Wolf").SetResistance((DamageType)6, 0.75f).SetPoiseThreshold(38f).AddOnHitAffliction("SE_Bleed", 8f, 5f, 0.5f)); } } } namespace VikingFoes.Patches { [HarmonyPatch(typeof(Attack))] public static class AttackDamagePatches { [HarmonyPatch("ModifyDamage")] [HarmonyPostfix] public static void ModifyDamage_Postfix(Humanoid ___m_character, HitData hitData) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected I4, but got Unknown if ((Object)(object)___m_character == (Object)null || hitData == null || ((Character)___m_character).IsPlayer() || !ModConfig.ModEnabled.Value || !ModConfig.EnableThematicDamageTypes.Value || !FoeRegistry.TryGet(FoeRegistry.GetCleanPrefabName((Character?)(object)___m_character), out FoeDefinition definition) || !definition.PhysicalDamageOverride.HasValue) { return; } float blunt = hitData.m_damage.m_blunt; float slash = hitData.m_damage.m_slash; float pierce = hitData.m_damage.m_pierce; float num = blunt + slash + pierce; if (!(num <= 0.001f)) { hitData.m_damage.m_blunt = 0f; hitData.m_damage.m_slash = 0f; hitData.m_damage.m_pierce = 0f; DamageType value = definition.PhysicalDamageOverride.Value; switch ((int)value) { case 0: hitData.m_damage.m_blunt = num; break; case 1: hitData.m_damage.m_slash = num; break; case 2: hitData.m_damage.m_pierce = num; break; } } } } [HarmonyPatch(typeof(Character))] public static class CharacterHealthPatches { [HarmonyPatch("GetMaxHealthBase")] [HarmonyPostfix] public static void GetMaxHealthBase_Postfix(Character __instance, ref float __result) { if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer() && (ModConfig.ModEnabled == null || (ModConfig.ModEnabled.Value && ModConfig.EnableHealthOverrides.Value)) && FoeRegistry.TryGet(FoeRegistry.GetCleanPrefabName(__instance), out FoeDefinition definition) && definition.OverrideBaseHealth.HasValue) { __result = definition.OverrideBaseHealth.Value; } } [HarmonyPatch("GetDamageModifiers", new Type[] { typeof(WeakSpot) })] [HarmonyPostfix] public static void GetDamageModifiers_Postfix(Character __instance, WeakSpot weakspot, ref DamageModifiers __result) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected I4, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || (ModConfig.ModEnabled != null && (!ModConfig.ModEnabled.Value || !ModConfig.EnableResistanceOverrides.Value)) || !FoeRegistry.TryGet(FoeRegistry.GetCleanPrefabName(__instance), out FoeDefinition definition) || definition.Resistances.Count == 0) { return; } foreach (KeyValuePair<DamageType, float> resistance in definition.Resistances) { DamageModifier val = EntityDefenseRegistry.ToVanillaModifier(resistance.Value); DamageType key = resistance.Key; switch ((int)key) { case 0: __result.m_blunt = val; break; case 1: __result.m_slash = val; break; case 2: __result.m_pierce = val; break; case 3: __result.m_chop = val; break; case 4: __result.m_pickaxe = val; break; case 5: __result.m_fire = val; break; case 6: __result.m_frost = val; break; case 7: __result.m_lightning = val; break; case 8: __result.m_poison = val; break; case 9: __result.m_spirit = val; break; } } } } } namespace VikingFoes.Integration { public static class VikingLibIntegration { [CompilerGenerated] private static class <>O { public static DamagePhaseHandler <0>__HandleMonsterAttackerModifier; public static DamagePhaseHandler <1>__HandleMonsterPostHitProcs; } private static bool _initialized; public static void Init() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0052: 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: Expected O, but got Unknown if (!_initialized) { _initialized = true; RegisterDefenses(); RegisterBloodlessObjects(); RegisterPoiseProfiles(); object obj = <>O.<0>__HandleMonsterAttackerModifier; if (obj == null) { DamagePhaseHandler val = HandleMonsterAttackerModifier; <>O.<0>__HandleMonsterAttackerModifier = val; obj = (object)val; } DamagePipeline.RegisterAttackerModifier(100, (DamagePhaseHandler)obj); object obj2 = <>O.<1>__HandleMonsterPostHitProcs; if (obj2 == null) { DamagePhaseHandler val2 = HandleMonsterPostHitProcs; <>O.<1>__HandleMonsterPostHitProcs = val2; obj2 = (object)val2; } DamagePipeline.RegisterHandler((DamagePhase)6, 50, (DamagePhaseHandler)obj2); ManualLogSource log = VikingFoesPlugin.Log; if (log != null) { log.LogInfo((object)"[VikingFoes] Successfully hooked VikingLib DamagePipeline, EntityDefenseRegistry, and CreatureStaggerTable."); } } } private static void RegisterDefenses() { foreach (FoeDefinition item in FoeRegistry.GetAll()) { if (item.Resistances.Count > 0 || item.PhysicalArmor > 0f || item.MagicArmor > 0f) { EntityDefenseRegistry.Register(item.PrefabName, item.ToEntityDefenseData()); ManualLogSource log = VikingFoesPlugin.Log; if (log != null) { log.LogDebug((object)$"[VikingFoes] Registered defense profile for '{item.PrefabName}' with {item.Resistances.Count} resistances."); } } } } private static void RegisterBloodlessObjects() { string[] array = new string[4] { "Greydwarf_spawner", "Spawner_GreydwarfNest", "BonePileSpawner", "Spawner_BonePile" }; string[] array2 = array; for (int i = 0; i < array2.Length; i++) { EntityDefenseRegistry.RegisterBloodless(array2[i]); } ManualLogSource log = VikingFoesPlugin.Log; if (log != null) { log.LogDebug((object)$"[VikingFoes] Registered {array.Length} inanimate spawner prefabs as bloodless entities."); } } private static void RegisterPoiseProfiles() { foreach (FoeDefinition item in FoeRegistry.GetAll()) { if (item.PoiseThreshold.HasValue) { CreatureStaggerTable.Register(item.PrefabName, item.PoiseThreshold.Value, item.StaggerDurationMultiplier, item.HasNativeAnimation); ManualLogSource log = VikingFoesPlugin.Log; if (log != null) { log.LogDebug((object)$"[VikingFoes] Registered poise profile for '{item.PrefabName}': Poise={item.PoiseThreshold.Value}, DurationMult={item.StaggerDurationMultiplier}x, NativeAnim={item.HasNativeAnimation}"); } } } } private static void HandleMonsterAttackerModifier(DamageContext ctx) { //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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((ModConfig.ModEnabled != null && (!ModConfig.ModEnabled.Value || !ModConfig.EnableThematicDamageTypes.Value)) || (Object)(object)ctx.Attacker == (Object)null || ctx.Attacker.IsPlayer()) { return; } string cleanPrefabName = FoeRegistry.GetCleanPrefabName(ctx.Attacker); if (!FoeRegistry.TryGet(cleanPrefabName, out FoeDefinition definition) || !definition.PhysicalDamageOverride.HasValue) { return; } DamageType value = definition.PhysicalDamageOverride.Value; DamageType[] array = (DamageType[])(object)new DamageType[3] { default(DamageType), (DamageType)1, (DamageType)2 }; foreach (DamageType val in array) { if (val != value && ctx.GetDamage(val) > 0.001f) { ctx.ConvertDamage(val, value, 1f, $"{cleanPrefabName} {value} Strike"); } } } private static void HandleMonsterPostHitProcs(DamageContext ctx) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if ((ModConfig.ModEnabled != null && !ModConfig.ModEnabled.Value) || ctx.IsCancelled || ctx.IsPreview || (Object)(object)ctx.Attacker == (Object)null || ctx.Attacker.IsPlayer() || (Object)(object)ctx.Target == (Object)null) { return; } string cleanPrefabName = FoeRegistry.GetCleanPrefabName(ctx.Attacker); if (!FoeRegistry.TryGet(cleanPrefabName, out FoeDefinition definition) || definition.OnHitAfflictions.Count == 0) { return; } foreach (FoeStatusAffliction onHitAffliction in definition.OnHitAfflictions) { if ((!(onHitAffliction.Chance < 1f) || !(Random.value > onHitAffliction.Chance)) && DamagePipeline.ApplyOnHitStatus(ctx.Target, onHitAffliction.EffectNameOrId, onHitAffliction.Value, onHitAffliction.Duration, ctx.Attacker)) { DamageTrace trace = ctx.Trace; if (trace != null) { trace.RecordStep(ctx.CurrentPhase, "VikingFoes", $"{cleanPrefabName} inflicted {onHitAffliction.EffectNameOrId} ({onHitAffliction.Duration:F1}s)", onHitAffliction.Value, ""); } } } } } } namespace VikingFoes.Core { public class FoeDefinition { public string PrefabName { get; } public float? OverrideBaseHealth { get; set; } public DamageType? PhysicalDamageOverride { get; set; } public Dictionary<DamageType, float> Resistances { get; } = new Dictionary<DamageType, float>(); public float PhysicalArmor { get; set; } public float MagicArmor { get; set; } public float? PoiseThreshold { get; set; } public float StaggerDurationMultiplier { get; set; } = 1f; public bool HasNativeAnimation { get; set; } = true; public List<FoeStatusAffliction> OnHitAfflictions { get; } = new List<FoeStatusAffliction>(); public FoeDefinition(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { throw new ArgumentException("PrefabName cannot be null or whitespace", "prefabName"); } PrefabName = prefabName.Trim(); } public FoeDefinition SetBaseHealth(float health) { OverrideBaseHealth = health; return this; } public FoeDefinition SetPhysicalDamageType(DamageType type) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhysicalDamageOverride = type; return this; } public FoeDefinition SetResistance(DamageType type, float multiplier) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Resistances[type] = multiplier; return this; } public FoeDefinition SetPoiseThreshold(float threshold, float durationMultiplier = 1f, bool hasNativeAnimation = true) { PoiseThreshold = threshold; StaggerDurationMultiplier = durationMultiplier; HasNativeAnimation = hasNativeAnimation; return this; } public FoeDefinition AddOnHitAffliction(string effectNameOrId, float value, float duration, float chance = 1f) { OnHitAfflictions.Add(new FoeStatusAffliction(effectNameOrId, value, duration, chance)); return this; } public EntityDefenseData ToEntityDefenseData() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) EntityDefenseData val = new EntityDefenseData(PhysicalArmor, MagicArmor); foreach (KeyValuePair<DamageType, float> resistance in Resistances) { val.Resistances[resistance.Key] = resistance.Value; } return val; } } public class FoeStatusAffliction { public string EffectNameOrId { get; } public float Value { get; } public float Duration { get; } public float Chance { get; } public FoeStatusAffliction(string effectNameOrId, float value, float duration, float chance = 1f) { if (string.IsNullOrWhiteSpace(effectNameOrId)) { throw new ArgumentException("EffectNameOrId cannot be null or whitespace", "effectNameOrId"); } EffectNameOrId = effectNameOrId.Trim(); Value = value; Duration = duration; Chance = Math.Max(0f, Math.Min(1f, chance)); } } } namespace VikingFoes.Configuration { public class ConfigurationManagerAttributes { public bool? Browsable; public string? Category; public bool? DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string? Description; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public bool? IsAdminOnly; } public static class ModConfig { public static ConfigEntry<bool> ModEnabled { get; private set; } public static ConfigEntry<bool> EnableThematicDamageTypes { get; private set; } public static ConfigEntry<bool> EnableResistanceOverrides { get; private set; } public static ConfigEntry<bool> EnableHealthOverrides { get; private set; } public static void Init(ConfigFile config) { ModEnabled = Bind(config, "1 - General", "Enabled", defaultValue: true, "Master switch to enable or disable all features of VikingFoes.", 100, null, isAdminOnly: true); EnableThematicDamageTypes = Bind(config, "2 - Features", "EnableThematicDamageTypes", defaultValue: true, "Enables thematic physical damage type overrides (e.g. Boar deals Slashing, Greydwarf Brute deals Bludgeoning, Serpent deals Piercing).", 90, null, isAdminOnly: true); EnableResistanceOverrides = Bind(config, "2 - Features", "EnableResistanceOverrides", defaultValue: true, "Enables continuous resistance overrides registered into VikingLib (e.g. Boar is 1.25x weak to Pierce).", 80, null, isAdminOnly: true); EnableHealthOverrides = Bind(config, "2 - Features", "EnableHealthOverrides", defaultValue: true, "Enables creature base health overrides (e.g. Boar base HP increased from 10 to 13).", 70, null, isAdminOnly: true); } private static ConfigEntry<T> Bind<T>(ConfigFile config, string section, string key, T defaultValue, string description, int order = 0, AcceptableValueBase? acceptableValues = null, bool isAdminOnly = false) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { Order = order, Category = section, IsAdminOnly = isAdminOnly }; ConfigDescription val = new ConfigDescription(description, acceptableValues, new object[1] { configurationManagerAttributes }); return config.Bind<T>(section, key, defaultValue, val); } } } namespace VikingFoes.Commands { public class FoeInfoConsoleCommand : ConsoleCommand { public override string Name => "vf_info"; public override string Help => "Inspects a creature's VikingFoes profile. Usage: vf_info <prefabName>"; public override void Run(string[] args) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) if (args.Length == 0) { Console instance = Console.instance; if (instance != null) { instance.Print("[VikingFoes] Usage: vf_info <prefabName> (e.g. vf_info Boar, vf_info Greydwarf_Elite, vf_info Serpent)"); } return; } string text = args[0].Trim(); if (!FoeRegistry.TryGet(text, out FoeDefinition definition)) { Console instance2 = Console.instance; if (instance2 != null) { instance2.Print("[VikingFoes] No creature definition found for '" + text + "'."); } return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("[VikingFoes] Profile: " + definition.PrefabName); stringBuilder.AppendLine(" - Base Health Override: " + (definition.OverrideBaseHealth.HasValue ? definition.OverrideBaseHealth.Value.ToString("F0") : "Vanilla Default")); stringBuilder.AppendLine(" - Physical Damage Type: " + (definition.PhysicalDamageOverride.HasValue ? ((object)definition.PhysicalDamageOverride.Value/*cast due to .constrained prefix*/).ToString() : "Vanilla Default")); if (definition.Resistances.Count > 0) { stringBuilder.AppendLine(" - Continuous Resistances:"); foreach (KeyValuePair<DamageType, float> resistance in definition.Resistances) { string arg = ((resistance.Value > 1f) ? $"Weak ({resistance.Value:F2}x)" : ((resistance.Value < 1f) ? $"Resistant ({resistance.Value:F2}x)" : "Normal (1.0x)")); stringBuilder.AppendLine($" {resistance.Key}: {arg}"); } } else { stringBuilder.AppendLine(" - Continuous Resistances: None (Vanilla default)"); } Console instance3 = Console.instance; if (instance3 != null) { instance3.Print(stringBuilder.ToString().TrimEnd()); } } } }