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 NoRainDamage v1.3.2
BepInEx/plugins/Jowleth/NoRainDamage.dll
Decompiled a day agousing System; 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyCompany("NoRainDamage")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c4ccf3b6ff7a7b3d8c3fc4a836851696fe695e26")] [assembly: AssemblyProduct("NoRainDamage")] [assembly: AssemblyTitle("NoRainDamage")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace NoRainDamage { [BepInPlugin("uk.co.oliapps.valheim.noraindamage", "No Rain Damage", "1.3.1")] public class NoRainDamage : BaseUnityPlugin { private enum DamageFilter { ALL, INCLUSIVE, EXCLUSIVE } private static readonly ManualLogSource MyLogger = Logger.CreateLogSource("NoRainDamage"); 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 ConfigEntry<bool> debugLogsEnabled; 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."); debugLogsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debugging", "Enabled", false, "Enable debug logging"); ((BaseUnityPlugin)this).Config.Save(); if (modEnabled.Value) { Harmony.CreateAndPatchAll(typeof(NoRainDamage), (string)null); minHealths = new Dictionary<int, float>(); Log($"Config loaded: damageFilter={damageFilter.Value}, damagePerMinute={damagePerMinute.Value}, damageFilterValues={damageFilterValues.Value}, maxRainDamagePercentage={maxRainDamagePercentage.Value}"); } } private static void Log(string message) { if (debugLogsEnabled.Value) { MyLogger.LogDebug((object)message); } } [HarmonyPatch(typeof(WearNTear), "Awake")] [HarmonyPostfix] public static void WearNTear_Awake(ref WearNTear __instance) { minHealthPercentage = 1f - Mathf.Clamp(maxRainDamagePercentage.Value, 0f, 1f); minHealths[((Object)__instance).GetInstanceID()] = __instance.m_health * minHealthPercentage; } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] [HarmonyPrefix] [HarmonyPriority(0)] public static bool Prefix(WearNTear __instance, float time, ZNetView ___m_nview, ref int ___m_shieldChangeID, ref bool ___m_rainWet, ref bool ___m_haveRoof, bool ___m_noRoofWear, GameObject ___m_wet, ref float ___m_rainTimer, bool ___m_noSupportWear, string ___m_requiredPersistentEvent, bool ___m_takeDamageIfInsideEvent, float ___m_eventDamage, float ___m_eventDamageDeviation, ref Biome ___m_biome, ref bool ___m_heavySnow, ref bool ___m_addPreSnow, ref float ___m_snowBuildup, bool ___m_snowDamageImmune, ref float ___m_lastSupportColorValue, ref float ___m_snowDamageTimer, ref bool ___m_inAshlands, bool ___m_ashDamageImmune, bool ___m_haveAshRoof, bool ___m_ashDamageResist, ref float ___m_ashTimer, bool ___m_staticPosition, ref float ___m_lavaValue, Heightmap ___m_heightmap, float ___m_groundDist, ref float ___m_lavaTimer, Biome ___m_requiredBiome, float ___m_outsideRequiredBiomeDamage, ref float ___m_ashDamageTime, GameObject ___m_snow) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0623: Unknown result type (might be due to invalid IL or missing references) //IL_0627: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) if (!OverrideWearNTear(ref __instance)) { return true; } if (!Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsValid()) { return false; } ZDO zDO = ___m_nview.GetZDO(); float currentHealth = ((zDO != null) ? zDO.GetFloat(ZDOVars.s_health, __instance.m_health) : __instance.m_health); if (___m_nview.IsOwner() && __instance.ShouldUpdate(time)) { Vector3 position = ((Component)__instance).transform.position; if (ZNetScene.instance.OutsideActiveArea(position)) { float maxSupport = __instance.GetMaxSupport(); if (__instance.m_support.Equals(maxSupport)) { return false; } ___m_nview.GetZDO().Set(ZDOVars.s_support, maxSupport); return false; } bool flag = ShieldGenerator.IsInsideShieldCached(position, ref ___m_shieldChangeID); float num = 0f; ___m_rainWet = !flag && !___m_haveRoof && ___m_noRoofWear && EnvMan.IsWet(); if (Object.op_Implicit((Object)(object)___m_wet)) { ___m_wet.SetActive(___m_rainWet); } if (___m_noRoofWear && !flag && (double)__instance.GetHealthPercentage() > 0.5) { if (__instance.IsWet()) { Log(((Object)((Component)__instance).gameObject).name + " is wet"); if ((double)___m_rainTimer == 0.0) { ___m_rainTimer = time; } else if ((double)time - (double)___m_rainTimer > 60.0) { ___m_rainTimer = time; num += damagePerMinute.Value; if (IsTooMuchDamage(ref __instance, currentHealth, num)) { float num2 = HowMuchIsTooMuch(ref __instance, currentHealth, num); Log($"{((Object)((Component)__instance).gameObject).name}: incoming rain damage ({num}) reduced by ({num2}"); num -= num2; } } } else { ___m_rainTimer = 0f; } } if (___m_noSupportWear) { __instance.UpdateSupport(); if (!__instance.HaveSupport()) { num = 100f; } } if (!string.IsNullOrEmpty(___m_requiredPersistentEvent)) { PersistentEvent activeEvent = PersistentEventSystem.instance.GetActiveEvent(position); if (___m_takeDamageIfInsideEvent && activeEvent != null && activeEvent.internalName == ___m_requiredPersistentEvent) { num += ___m_eventDamage + Random.Range(0f - ___m_eventDamageDeviation, ___m_eventDamageDeviation); } else if ((activeEvent != null && activeEvent.internalName != ___m_requiredPersistentEvent) || activeEvent == null) { num += ___m_eventDamage + Random.Range(0f - ___m_eventDamageDeviation, ___m_eventDamageDeviation); } } bool flag2 = false; __instance.UpdateBiome(); if ((int)___m_biome == 64) { bool flag3 = __instance.CanHaveSnow(flag); if (flag3 && (double)___m_snowBuildup < 1.0) { ___m_heavySnow = false; float num3 = (___m_addPreSnow ? 1f : EnvMan.instance.GetSnowBuildup()); if ((double)num3 > 0.0) { if (___m_addPreSnow) { ___m_snowBuildup = 1f; ___m_addPreSnow = false; ___m_nview.GetZDO().Set(ZDOVars.s_preSnow, false); } else { ___m_snowBuildup += num3 * Time.deltaTime * Game.instance.m_snowBuildupSpeed; } ___m_nview.GetZDO().Set(ZDOVars.s_snow, ___m_snowBuildup); } } else if ((!___m_snowDamageImmune || ZoneSystem.instance.GetGlobalKey((GlobalKeys)39)) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)38)) { ___m_heavySnow = flag3; if (___m_heavySnow) { ___m_lastSupportColorValue = __instance.GetSupportColorValue(); if ((double)___m_lastSupportColorValue != -1.0 && (double)___m_lastSupportColorValue < (double)Game.instance.m_snowSupportLevel) { ___m_heavySnow = true; num += Game.instance.m_snowDamage; if (ZNet.instance.GetTimeSeconds() >= (double)___m_snowDamageTimer) { ___m_snowDamageTimer = (float)ZNet.instance.GetTimeSeconds() + Random.Range(Game.instance.m_snowDamageEffectIntervalRange.x, Game.instance.m_snowDamageEffectIntervalRange.y); Game.instance.m_snowDamageEffect.Create(position, Quaternion.identity, ((Component)__instance).transform, 1f, -1, default(ZDOID)); } } } } } if ((int)___m_biome == 32) { ___m_inAshlands = true; if ((double)Game.instance.m_ashDamage > 0.0 && !flag && !___m_ashDamageImmune) { flag2 = !___m_haveAshRoof && (!___m_ashDamageResist || (double)__instance.GetHealthPercentage() > 0.1); if (flag2) { if ((double)___m_ashTimer == 0.0) { ___m_ashTimer = time; } else if ((double)time - (double)___m_ashTimer > 5.0) { ___m_ashTimer = time; num += Game.instance.m_ashDamage; } } else { ___m_ashTimer = 0f; } } if (!___m_staticPosition && (Object)(object)___m_heightmap != (Object)null) { ___m_lavaValue = ___m_heightmap.GetLava(position); } if ((double)___m_lavaValue > 0.2 && (double)___m_groundDist < 1.5 && !___m_ashDamageImmune) { if ((double)___m_lavaTimer == 0.0) { ___m_lavaTimer = time; } else if ((double)time - (double)___m_lavaTimer > 2.0) { ___m_lavaTimer = time; float num4 = (flag ? 30f : 70f) * ___m_lavaValue; num += num4 * (___m_ashDamageResist ? 0.33f : 1f); } } else { ___m_lavaTimer = 0f; } } if ((int)___m_requiredBiome != 0 && !((Enum)___m_requiredBiome).HasFlag((Enum)(object)___m_biome)) { num += ___m_outsideRequiredBiomeDamage; } ___m_ashDamageTime = (flag2 ? 5f : 0f); if ((double)num > 0.0 && !__instance.CanBeRemoved()) { num = 0f; } if ((double)num > 0.0) { float num5 = num / 100f * __instance.m_health; if (!ZoneSystem.instance.GetGlobalKey((GlobalKeys)37)) { __instance.ApplyDamage(num5, (HitData)null); } } } if (Object.op_Implicit((Object)(object)___m_snow) && ___m_nview.IsValid()) { ___m_snowBuildup = ___m_nview.GetZDO().GetFloat(ZDOVars.s_snow, 0f); } __instance.UpdateVisual(true); return false; } private static bool OverrideWearNTear(ref WearNTear instance) { if (DamageFilter.ALL.Equals(damageFilter.Value)) { return true; } string[] array = damageFilterValues.Value.Split(new char[1] { ',' }); string[] array2 = array; foreach (string text in array2) { string value = text.Trim(); if (!string.IsNullOrEmpty(value) && ((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 currentHealth, float damage) { int instanceID = ((Object)instance).GetInstanceID(); if (!minHealths.TryGetValue(instanceID, out var value)) { minHealthPercentage = 1f - Mathf.Clamp(maxRainDamagePercentage.Value, 0f, 1f); value = instance.m_health * minHealthPercentage; minHealths[instanceID] = value; } float num = currentHealth - damage / 100f * instance.m_health; return num < value; } private static float HowMuchIsTooMuch(ref WearNTear instance, float currentHealth, float damage) { int instanceID = ((Object)instance).GetInstanceID(); if (!minHealths.TryGetValue(instanceID, out var value)) { minHealthPercentage = 1f - Mathf.Clamp(maxRainDamagePercentage.Value, 0f, 1f); value = instance.m_health * minHealthPercentage; minHealths[instanceID] = value; } float num = currentHealth - damage / 100f * instance.m_health; float num2 = Mathf.Abs(value - num); return num2 / instance.m_health * 100f; } [HarmonyPatch(typeof(WearNTear), "OnDestroy")] [HarmonyPostfix] public static void WearNTear_OnDestroy(ref WearNTear __instance) { minHealths.Remove(((Object)__instance).GetInstanceID()); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }