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 NoTerrainPenalty v1.0.2
NoTerrainPenalty.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("NoTerrainPenalty")] [assembly: AssemblyDescription("Only creatures count toward the melee multi-hit damage penalty in Valheim")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.2.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; } } } namespace NoTerrainPenalty { [HarmonyPatch(typeof(Attack), "DoMeleeAttack")] public static class MeleePatch { [HarmonyTranspiler] public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); FieldInfo fieldInfo = AccessTools.Field(typeof(HitPoint), "go"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(Attack), "m_lowerDamagePerHit"); MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(List<HitPoint>), "Count"); MethodInfo methodInfo2 = AccessTools.Method(typeof(MeleePatch), "CountForPenalty", (Type[])null, (Type[])null); CodeInstruction val = null; int num = -1; for (int i = 0; i < list.Count - 1; i++) { if (num >= 0) { break; } if (CodeInstructionExtensions.LoadsField(list[i], fieldInfo, false) && CodeInstructionExtensions.IsStloc(list[i + 1], (LocalBuilder)null)) { val = list[i + 1]; } if (CodeInstructionExtensions.LoadsField(list[i], fieldInfo2, false)) { num = i; } } List<int> list2 = new List<int>(); int num2 = num + 1; while (num >= 0 && num2 < list.Count && list2.Count < 2) { if (CodeInstructionExtensions.Calls(list[num2], methodInfo)) { list2.Add(num2); } num2++; } if (val == null || list2.Count != 2 || list2[1] - num > 12) { Plugin.Log.LogError((object)"could not find the multi-hit penalty in Attack.DoMeleeAttack (game update?), mod inactive"); return list; } int[] array = new int[2] { list2[1], list2[0] }; foreach (int index in array) { CodeInstruction val2 = CodeInstructionExtensions.MoveLabelsFrom(LoadLocal(val), list[index]); list[index] = new CodeInstruction(OpCodes.Call, (object)methodInfo2); list.InsertRange(index, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2] { val2, new CodeInstruction(OpCodes.Ldarg_0, (object)null) }); } Plugin.Log.LogInfo((object)"patched the multi-hit penalty in Attack.DoMeleeAttack"); return list; } public static int CountForPenalty(List<HitPoint> hits, GameObject hitObject, Attack attack) { if (!IsCreature(hitObject) || !Plugin.Applies(attack)) { return hits.Count; } return hits.Count((HitPoint h) => IsCreature(h.go)); } private static bool IsCreature(GameObject go) { if ((Object)(object)go != (Object)null) { return (Object)(object)go.GetComponent<Character>() != (Object)null; } return false; } private static CodeInstruction LoadLocal(CodeInstruction store) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown if (!(store.opcode == OpCodes.Stloc_0)) { if (!(store.opcode == OpCodes.Stloc_1)) { if (!(store.opcode == OpCodes.Stloc_2)) { if (!(store.opcode == OpCodes.Stloc_3)) { return new CodeInstruction(OpCodes.Ldloc, store.operand); } return new CodeInstruction(OpCodes.Ldloc_3, (object)null); } return new CodeInstruction(OpCodes.Ldloc_2, (object)null); } return new CodeInstruction(OpCodes.Ldloc_1, (object)null); } return new CodeInstruction(OpCodes.Ldloc_0, (object)null); } } [BepInPlugin("onononoki.NoTerrainPenalty", "NoTerrainPenalty", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string ModGuid = "onononoki.NoTerrainPenalty"; public const string ModName = "NoTerrainPenalty"; public const string ModVersion = "1.0.2"; internal static ManualLogSource Log; private static ConfigEntry<bool> _enabled; private static ConfigEntry<bool> _primary; private static ConfigEntry<bool> _secondary; private static ConfigEntry<string> _excludedSkills; private static ConfigEntry<string> _excludedItems; private static HashSet<string> _skipSkills = new HashSet<string>(); private static HashSet<string> _skipItems = new HashSet<string>(); private static readonly HashSet<ItemType> WeaponTypes = new HashSet<ItemType> { (ItemType)3, (ItemType)14, (ItemType)22 }; private static readonly FieldRef<Attack, Humanoid> AttackCharacter = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character"); private static readonly FieldRef<Attack, ItemData> AttackWeapon = AccessTools.FieldRefAccess<Attack, ItemData>("m_weapon"); private static readonly FieldRef<Humanoid, bool> CurrentAttackIsSecondary = AccessTools.FieldRefAccess<Humanoid, bool>("m_currentAttackIsSecondary"); private void Awake() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = true }; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, new ConfigDescription("Only creatures (players, mobs, bosses) count toward the melee multi-hit damage penalty. Ground, walls, rocks, trees and building pieces no longer lower damage to creatures.", (AcceptableValueBase)null, new object[1] { val })); _primary = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PrimaryAttack", true, new ConfigDescription("Apply to primary attacks.", (AcceptableValueBase)null, new object[1] { val })); _secondary = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SecondaryAttack", true, new ConfigDescription("Apply to secondary attacks.", (AcceptableValueBase)null, new object[1] { val })); _excludedSkills = ((BaseUnityPlugin)this).Config.Bind<string>("Filters", "ExcludedSkills", "", new ConfigDescription("Comma separated weapon skill types to leave vanilla (Swords, Knives, Clubs, Polearms, Spears, Axes, Pickaxes).", (AcceptableValueBase)null, new object[1] { val })); _excludedItems = ((BaseUnityPlugin)this).Config.Bind<string>("Filters", "ExcludedItems", "", new ConfigDescription("Comma separated item prefab names to leave vanilla (example: THSwordKrom, SwordIron).", (AcceptableValueBase)null, new object[1] { val })); ParseFilters(); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { ParseFilters(); }; Harmony.CreateAndPatchAll(typeof(MeleePatch), "onononoki.NoTerrainPenalty"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"NoTerrainPenalty 1.0.2 loaded"); } private static void ParseFilters() { _skipSkills = ParseList(_excludedSkills.Value); _skipItems = ParseList(_excludedItems.Value); } private static HashSet<string> ParseList(string value) { return new HashSet<string>(from s in (value ?? "").Split(new char[1] { ',' }) select s.Trim() into s where s.Length > 0 select s, StringComparer.OrdinalIgnoreCase); } internal static bool Applies(Attack attack) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!_enabled.Value) { return false; } Humanoid obj = AttackCharacter.Invoke(attack); Player val = (Player)(object)((obj is Player) ? obj : null); if (val == null) { return false; } ItemData val2 = AttackWeapon.Invoke(attack); if (val2?.m_shared == null || !WeaponTypes.Contains(val2.m_shared.m_itemType)) { return false; } if (!(CurrentAttackIsSecondary.Invoke((Humanoid)(object)val) ? _secondary.Value : _primary.Value)) { return false; } if (_skipSkills.Contains(((object)Unsafe.As<SkillType, SkillType>(ref val2.m_shared.m_skillType)/*cast due to .constrained prefix*/).ToString())) { return false; } if (_skipItems.Count == 0) { return true; } GameObject dropPrefab = val2.m_dropPrefab; if (!((Object)(object)dropPrefab == (Object)null)) { return !_skipItems.Contains(((Object)dropPrefab).name); } return true; } } }