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 NoRainDamage v1.2.2
BepInEx/plugins/Jowleth/NoRainDamage.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("NoRainDamage")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("NoRainDamage")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("65825995-ebff-4e7e-81c3-6254d9832f19")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace NoRainDamage; [BepInPlugin("uk.co.oliapps.valheim.noraindamage", "No Rain Damage", "1.2.2")] public class NoRainDamage : BaseUnityPlugin { private enum DamageFilter { ALL, INCLUSIVE, EXCLUSIVE } private static ConfigEntry<float> damagePerMinute; private static ConfigEntry<float> maxRainDamagePercentage; private static ConfigEntry<DamageFilter> damageFilter; private static ConfigEntry<string> damageFilterValues; private static ConfigEntry<bool> modEnabled; private static Dictionary<int, float> minHealths; private static float minHealthPercentage; public void Awake() { modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Set whether the mod is enabled"); maxRainDamagePercentage = ((BaseUnityPlugin)this).Config.Bind<float>("Rain Damage", "Max Damage", 0f, "Maximum damage rain can do to uncovered structures between 0.0 and 1.0"); damagePerMinute = ((BaseUnityPlugin)this).Config.Bind<float>("Rain Damage", "Damage Per Minute", 5f, "Damage per minute rain deals to uncovered structures"); damageFilter = ((BaseUnityPlugin)this).Config.Bind<DamageFilter>("Damage Filter", "Filter Type", DamageFilter.ALL, "Set whether everything should be protected (ALL), certain things should be protected (INCLUSIVE) or certain things should not be protected (EXCLUSIVE)"); damageFilterValues = ((BaseUnityPlugin)this).Config.Bind<string>("Damage Filter", "Filter List", "", "If Filter type is INCLUSIVE or EXCLUSIVE, this list of comma-separated values will be used as a filter (will protect or damage if piece name contains value). Piece list included in mod download."); ((BaseUnityPlugin)this).Config.Save(); if (modEnabled.Value) { Harmony.CreateAndPatchAll(typeof(NoRainDamage), (string)null); minHealths = new Dictionary<int, float>(); } } [HarmonyPatch(typeof(WearNTear), "Awake")] [HarmonyPostfix] public static void WearNTear_Awake(ref WearNTear __instance) { minHealthPercentage = 1f - Mathf.Clamp(maxRainDamagePercentage.Value, 0f, 1f); minHealths.Add(((Object)__instance).GetInstanceID(), __instance.m_health * minHealthPercentage); } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] [HarmonyPrefix] [HarmonyPriority(0)] public static bool WearNTear_UpdateWear(ref WearNTear __instance) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (OverrideWearNTear(ref __instance)) { ZNetView val = (ZNetView)AccessTools.Field(typeof(WearNTear), "m_nview").GetValue(__instance); if ((Object)(object)val == (Object)null || !val.IsValid()) { return false; } bool flag = (bool)AccessTools.Method(typeof(WearNTear), "ShouldUpdate", (Type[])null, (Type[])null).Invoke(__instance, new object[0]); if (val.IsOwner() && flag) { if (ZNetScene.instance.OutsideActiveArea(((Component)__instance).transform.position)) { float num = (float)AccessTools.Method(typeof(WearNTear), "GetMaxSupport", (Type[])null, (Type[])null).Invoke(__instance, new object[0]); AccessTools.Field(typeof(WearNTear), "m_support").SetValue(__instance, num); val.GetZDO().Set("support", num); return false; } float num2 = 0f; bool flag2 = (bool)AccessTools.Method(typeof(WearNTear), "HaveRoof", (Type[])null, (Type[])null).Invoke(__instance, new object[0]); bool flag3 = EnvMan.IsWet() && !flag2; if (Object.op_Implicit((Object)(object)__instance.m_wet)) { __instance.m_wet.SetActive(flag3); } if (__instance.m_noRoofWear && (double)__instance.GetHealthPercentage() > (double)minHealthPercentage) { bool flag4 = (bool)AccessTools.Method(typeof(WearNTear), "IsUnderWater", (Type[])null, (Type[])null).Invoke(__instance, new object[0]); float num3 = (float)AccessTools.Field(typeof(WearNTear), "m_rainTimer").GetValue(__instance); float @float = val.GetZDO().GetFloat("health", __instance.m_health); if (flag3 || flag4) { if ((double)num3 == 0.0) { num3 = Time.time; } else if ((double)Time.time - (double)num3 > 60.0) { num3 = Time.time; num2 += damagePerMinute.Value; if (IsTooMuchDamage(ref __instance, @float, num2)) { float num4 = HowMuchIsTooMuch(ref __instance, @float, num2); num2 -= num4; } } } else { num3 = 0f; } AccessTools.Field(typeof(WearNTear), "m_rainTimer").SetValue(__instance, num3); } if (__instance.m_noSupportWear) { AccessTools.Method(typeof(WearNTear), "UpdateSupport", (Type[])null, (Type[])null).Invoke(__instance, new object[0]); if (!(bool)AccessTools.Method(typeof(WearNTear), "HaveSupport", (Type[])null, (Type[])null).Invoke(__instance, new object[0])) { num2 = 100f; } } bool flag5 = (bool)AccessTools.Method(typeof(WearNTear), "CanBeRemoved", (Type[])null, (Type[])null).Invoke(__instance, new object[0]); if ((double)num2 > 0.0 && !flag5) { num2 = 0f; } if ((double)num2 > 0.0) { __instance.ApplyDamage(num2 / 100f * __instance.m_health, (HitData)null); } } AccessTools.Method(typeof(WearNTear), "UpdateVisual", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { true }); return false; } return true; } private static bool OverrideWearNTear(ref WearNTear instance) { if (DamageFilter.ALL.Equals(damageFilter.Value)) { return true; } string[] array = damageFilterValues.Value.Split(new char[1] { ',' }); foreach (string value in array) { if (((Object)((Component)instance).gameObject).name.Contains(value)) { return damageFilter.Value switch { DamageFilter.INCLUSIVE => true, DamageFilter.EXCLUSIVE => false, _ => true, }; } } return DamageFilter.EXCLUSIVE.Equals(damageFilter.Value); } private static bool IsTooMuchDamage(ref WearNTear instance, float health, float damage) { return health - damage / 100f * instance.m_health < minHealths[((Object)instance).GetInstanceID()]; } private static float HowMuchIsTooMuch(ref WearNTear instance, float health, float damage) { float num = health - damage / 100f * instance.m_health; return Mathf.Abs(minHealths[((Object)instance).GetInstanceID()] - num) / instance.m_health * 100f; } private static void Log(string message) { ZLog.Log((object)("[No Rain Damage] " + message)); } [HarmonyPatch(typeof(WearNTear), "OnDestroy")] [HarmonyPostfix] public static void WearNTear_OnDestroy(ref WearNTear __instance) { minHealths.Remove(((Object)__instance).GetInstanceID()); } }