Decompiled source of VikingFoes v0.1.1

VikingFoes.dll

Decompiled 3 days ago
using 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());
			}
		}
	}
}