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 Mob Cap v0.3.0
FrizzQOL.MobCap.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("FrizzQOL.MobCap")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+308f41cc0acc4fc298b87ad844c3d2059b13aa0c")] [assembly: AssemblyProduct("FrizzQOL.MobCap")] [assembly: AssemblyTitle("FrizzQOL.MobCap")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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; } } } public static class MobCapRules { public sealed class Row { public int Day { get; } public int MaxStars { get; } public int MaxWorldLevel { get; } public Row(int day, int maxStars, int maxWorldLevel) { Day = day; MaxStars = maxStars; MaxWorldLevel = maxWorldLevel; } } public static bool IsLegacy(string text) { if (string.IsNullOrWhiteSpace(text)) { return false; } if (text.IndexOf(':') >= 0) { return text.IndexOf("day", StringComparison.OrdinalIgnoreCase) < 0; } return false; } public static string Format(IReadOnlyList<Row> rows) { if (rows == null || rows.Count == 0) { return ""; } List<string> list = new List<string>(); for (int i = 0; i < rows.Count; i++) { Row row = rows[i]; string text = ((row.MaxStars == 1) ? "star" : "stars"); list.Add("day " + row.Day + " = " + row.MaxStars + " " + text + " and world " + row.MaxWorldLevel); } return string.Join("; ", list); } public static List<Row> Parse(string text, Action<string> warn) { List<Row> list = new List<Row>(); if (string.IsNullOrWhiteSpace(text)) { return list; } bool flag = text.IndexOf("day", StringComparison.OrdinalIgnoreCase) >= 0; string[] array = (flag ? text.Split(new char[1] { ';' }) : text.Split(new char[1] { ',' })); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length != 0) { if (!TryReadRow(text2, flag, out var day, out var maxStars, out var maxWorldLevel)) { warn?.Invoke("Skipped '" + text2 + "'. Write: day 100 = 1 star and world 2"); } else { list.Add(new Row(day, maxStars, maxWorldLevel)); } } } return list; } private static bool TryReadRow(string segment, bool words, out int day, out int maxStars, out int maxWorldLevel) { day = 0; maxStars = 0; maxWorldLevel = 0; if (!words) { string[] array = segment.Split(new char[1] { ':' }); if (array.Length == 3 && int.TryParse(array[0].Trim(), out day) && int.TryParse(array[1].Trim(), out maxStars) && int.TryParse(array[2].Trim(), out maxWorldLevel) && day >= 0 && maxStars >= 0) { return maxWorldLevel >= 0; } return false; } List<int> list = new List<int>(); int i = 0; while (i < segment.Length) { if (segment[i] == '-' && i + 1 < segment.Length && char.IsDigit(segment[i + 1])) { return false; } if (char.IsDigit(segment[i])) { int num = i; for (; i < segment.Length && char.IsDigit(segment[i]); i++) { } if (!int.TryParse(segment.Substring(num, i - num), out var result)) { return false; } list.Add(result); } else { i++; } } if (list.Count != 3) { return false; } day = list[0]; maxStars = list[1]; maxWorldLevel = list[2]; return true; } public static bool TryActive(IReadOnlyList<Row> rows, int day, out int maxStars, out int maxWorldLevel) { maxStars = 0; maxWorldLevel = 0; Row row = null; if (rows != null) { for (int i = 0; i < rows.Count; i++) { Row row2 = rows[i]; if (row2.Day <= day && (row == null || row2.Day >= row.Day)) { row = row2; } } } if (row == null) { return false; } maxStars = row.MaxStars; maxWorldLevel = row.MaxWorldLevel; return true; } public static int CappedCreatureLevel(int rolledLevel, int maxStars) { if (rolledLevel < 1) { return 1; } if (maxStars < 0) { maxStars = 0; } int num = 1 + maxStars; if (rolledLevel < num) { return rolledLevel; } return num; } public static int StarsForDay(int day, int twoStarsAfterDay, int maxStars) { if (maxStars < 0) { maxStars = 0; } if (twoStarsAfterDay > 0 && day < twoStarsAfterDay && maxStars > 1) { return 1; } return maxStars; } public static int EffectiveWorldLevel(int actualWorldLevel, int maxWorldLevel) { if (actualWorldLevel < 0) { actualWorldLevel = 0; } if (maxWorldLevel < 0) { maxWorldLevel = 0; } if (actualWorldLevel < maxWorldLevel) { return actualWorldLevel; } return maxWorldLevel; } public static float HealthBase(float creatureBaseHealth, int worldLevel, float hpMultiplier) { if (worldLevel <= 0) { return creatureBaseHealth; } return creatureBaseHealth * (float)worldLevel * hpMultiplier; } public static float TotalDamage(float rawDamage, int worldLevel, int damagePerWorldLevel, bool creatureAttacker) { if (!creatureAttacker || worldLevel <= 0) { return rawDamage; } return rawDamage + (float)(worldLevel * damagePerWorldLevel); } } namespace MobCap { [HarmonyPatch(typeof(Character), "SetLevel")] internal static class SetLevelPatch { private static void Postfix(Character __instance, int level) { if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer() && level >= 1) { int maxStars = ((MobCapState.MaxStars != null) ? MobCapState.MaxStars.Value : 2); int twoStarsAfterDay = ((MobCapState.TwoStarsAfterDay != null) ? MobCapState.TwoStarsAfterDay.Value : 0); int day = 0; if ((Object)(object)EnvMan.instance != (Object)null) { day = EnvMan.instance.GetDay(); } maxStars = MobCapRules.StarsForDay(day, twoStarsAfterDay, maxStars); int num = MobCapRules.CappedCreatureLevel(level, maxStars); if (num != level) { __instance.SetLevel(num); } } } } [BepInPlugin("com.frizzqol.mobcap", "FrizzQOL Mob Cap", "0.3.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.frizzqol.mobcap"; public const string PluginName = "FrizzQOL Mob Cap"; public const string PluginVersion = "0.3.0"; private Harmony _harmony; private ConfigEntry<int> _maxStars; private ConfigEntry<int> _twoStarsAfterDay; internal static Plugin Instance { get; private set; } private void Awake() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown Instance = this; _maxStars = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxStars", 2, "Most stars a new creature can spawn with once 2 stars are allowed. 2 is the normal Valheim maximum. Creatures already alive keep their stars."); _twoStarsAfterDay = ((BaseUnityPlugin)this).Config.Bind<int>("General", "TwoStarsAfterDay", 0, "2 star creatures cannot spawn before this day. 0 means 2 stars are allowed from day 0. Example: 100 blocks 2 stars on days 0 through 99."); MobCapState.MaxStars = _maxStars; MobCapState.TwoStarsAfterDay = _twoStarsAfterDay; _harmony = new Harmony("com.frizzqol.mobcap"); try { _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"FrizzQOL Mob Cap 0.3.0 loaded"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Harmony patch failed: " + ex.Message)); } } internal static void LogInfo(string message) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)message); } } internal static void LogWarning(string message) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)message); } } } internal static class MobCapState { internal static ConfigEntry<int> MaxStars; internal static ConfigEntry<int> TwoStarsAfterDay; } }