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 DeathPenalty v1.1.4
DeathPenalty.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("DeathPenalty")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Crystal")] [assembly: AssemblyProduct("DeathPenalty")] [assembly: AssemblyCopyright("Copyright © 2023 Crystal Ferrai")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f35b4ef7-5ab1-40f7-864f-09be2f9fcc8c")] [assembly: AssemblyFileVersion("1.1.4.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.1.4.0")] namespace DeathPenalty; [BepInPlugin("dev.crystal.deathpenalty", "Death Penalty", "1.1.4.0")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class DeathPenaltyPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Skills))] private static class Skills_Level_Patches { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Awake_Postfix(Skills __instance) { __instance.m_DeathLowerFactor = SkillLossPercent.Value * 0.01f; } } [HarmonyPatch(typeof(Skills))] private static class Skills_Accumulator_Patches { private enum TranspilerState { Searching, Updating, Finishing } [CompilerGenerated] private sealed class <LowerAllSkills_Transpiler>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private TranspilerState <state>5__2; private CodeInstruction <previousInstruction>5__3; private IEnumerator<CodeInstruction> <>7__wrap3; private CodeInstruction <instruction>5__5; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LowerAllSkills_Transpiler>d__1(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 3u) { try { } finally { <>m__Finally1(); } } <previousInstruction>5__3 = null; <>7__wrap3 = null; <instruction>5__5 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <state>5__2 = TranspilerState.Searching; <previousInstruction>5__3 = null; <>7__wrap3 = instructions.GetEnumerator(); <>1__state = -3; goto IL_01af; case 1: <>1__state = -3; goto IL_01a8; case 2: <>1__state = -3; <>2__current = <instruction>5__5; <>1__state = 3; return true; case 3: <>1__state = -3; <state>5__2 = TranspilerState.Searching; goto IL_0180; case 4: { <>1__state = -3; goto IL_01a8; } IL_01af: if (<>7__wrap3.MoveNext()) { <instruction>5__5 = <>7__wrap3.Current; switch (<state>5__2) { case TranspilerState.Searching: break; case TranspilerState.Updating: goto IL_00f7; case TranspilerState.Finishing: <>2__current = <instruction>5__5; <>1__state = 4; return true; default: goto IL_01a8; } if (<instruction>5__5.opcode == OpCodes.Ldc_R4 && (float)<instruction>5__5.operand == 0f) { <previousInstruction>5__3 = <instruction>5__5; <state>5__2 = TranspilerState.Updating; goto IL_01a8; } <>2__current = <instruction>5__5; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap3 = null; return false; IL_0180: <previousInstruction>5__3 = null; goto IL_01a8; IL_00f7: if (<instruction>5__5.opcode == OpCodes.Stfld && ((FieldInfo)<instruction>5__5.operand).Name == "m_accumulator") { <state>5__2 = TranspilerState.Finishing; goto IL_0180; } <>2__current = <previousInstruction>5__3; <>1__state = 2; return true; IL_01a8: <instruction>5__5 = null; goto IL_01af; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <LowerAllSkills_Transpiler>d__1 <LowerAllSkills_Transpiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <LowerAllSkills_Transpiler>d__ = this; } else { <LowerAllSkills_Transpiler>d__ = new <LowerAllSkills_Transpiler>d__1(0); } <LowerAllSkills_Transpiler>d__.instructions = <>3__instructions; return <LowerAllSkills_Transpiler>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<LowerAllSkills_Transpiler>d__1))] [HarmonyPatch("LowerAllSkills")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> LowerAllSkills_Transpiler(IEnumerable<CodeInstruction> instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LowerAllSkills_Transpiler>d__1(-2) { <>3__instructions = instructions }; } } [HarmonyPatch(typeof(Player))] private static class Player_Patches { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Awake_Postfix(Player __instance) { __instance.m_hardDeathCooldown = MercyEffectDuration.Value; sPlayers.Add(__instance); } [HarmonyPatch("OnDestroy")] [HarmonyPrefix] private static void OnDestroy_Prefix(Player __instance) { sPlayers.Remove(__instance); } } [HarmonyPatch(typeof(TombStone))] private static class TombStone_Patches { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Awake_Postfix(TombStone __instance) { __instance.m_lootStatusEffect.m_ttl = SafetyEffectDuration.Value; sTombStones.Add(__instance); } [HarmonyPatch("UpdateDespawn")] [HarmonyPostfix] private static void UpdateDespawn_Postfix(TombStone __instance) { sTombStones.Remove(__instance); } } public const string ModId = "dev.crystal.deathpenalty"; public static ConfigEntry<float> SkillLossPercent; public static ConfigEntry<bool> ResetLevelProgress; public static ConfigEntry<float> MercyEffectDuration; public static ConfigEntry<float> SafetyEffectDuration; private static Harmony sSkillsLevelHarmony; private static Harmony sSkillsAccumulatorHarmony; private static Harmony sPlayerHarmony; private static Harmony sTombStoneHarmony; private static readonly List<Player> sPlayers; private static readonly List<TombStone> sTombStones; static DeathPenaltyPlugin() { sPlayers = new List<Player>(); sTombStones = new List<TombStone>(); } private void Awake() { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown SkillLossPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Death", "SkillLossPercent", 5f, "The percent loss suffered to the level of all skills when the player dies. Range 0-100. 0 disables skill loss. 50 reduces all skills by half. 100 resets all skills to 0. Game default is 5."); SkillLossPercent.SettingChanged += SkillLossPercent_SettingChanged; ResetLevelProgress = ((BaseUnityPlugin)this).Config.Bind<bool>("Death", "ResetLevelProgress", true, "Whether to reset progress towards the next level for all skills when the player dies. This is independent of the loss of skill levels. Game default is true."); ResetLevelProgress.SettingChanged += ResetLevelProgress_SettingChanged; MercyEffectDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Death", "MercyEffectDuration", 600f, "The duration, in seconds, of the \"No Skill Loss\" status effect that is granted on death which prevents further loss of skills via subsequent deaths. Game default is 600."); MercyEffectDuration.SettingChanged += MercyEffectDuration_SettingChanged; SafetyEffectDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Death", "SafetyEffectDuration", 50f, "The duration, in seconds, of the \"Corpse Run\" status effect that is granted upon looting a tombstone which boosts regen and other stats. Game default is 50."); SafetyEffectDuration.SettingChanged += SafetyEffectDuration_SettingChanged; ClampConfig(); sSkillsLevelHarmony = new Harmony("dev.crystal.deathpenalty_Skills_Level"); sSkillsAccumulatorHarmony = new Harmony("dev.crystal.deathpenalty_Skills_Accumulator"); sPlayerHarmony = new Harmony("dev.crystal.deathpenalty_Player"); sTombStoneHarmony = new Harmony("dev.crystal.deathpenalty_TombStone"); sSkillsLevelHarmony.PatchAll(typeof(Skills_Level_Patches)); sPlayerHarmony.PatchAll(typeof(Player_Patches)); sTombStoneHarmony.PatchAll(typeof(TombStone_Patches)); if (!ResetLevelProgress.Value) { sSkillsAccumulatorHarmony.PatchAll(typeof(Skills_Accumulator_Patches)); } } private void OnDestroy() { sSkillsLevelHarmony.UnpatchSelf(); sSkillsAccumulatorHarmony.UnpatchSelf(); sPlayerHarmony.UnpatchSelf(); sTombStoneHarmony.UnpatchSelf(); } private void SkillLossPercent_SettingChanged(object sender, EventArgs e) { ClampConfig(); foreach (Player sPlayer in sPlayers) { ((Character)sPlayer).GetSkills().m_DeathLowerFactor = SkillLossPercent.Value * 0.01f; } } private void ResetLevelProgress_SettingChanged(object sender, EventArgs e) { if (ResetLevelProgress.Value) { sSkillsAccumulatorHarmony.UnpatchSelf(); } else { sSkillsAccumulatorHarmony.PatchAll(typeof(Skills_Accumulator_Patches)); } } private void MercyEffectDuration_SettingChanged(object sender, EventArgs e) { ClampConfig(); foreach (Player sPlayer in sPlayers) { sPlayer.m_hardDeathCooldown = MercyEffectDuration.Value; } } private void SafetyEffectDuration_SettingChanged(object sender, EventArgs e) { ClampConfig(); foreach (TombStone sTombStone in sTombStones) { sTombStone.m_lootStatusEffect.m_ttl = SafetyEffectDuration.Value; } } private static void ClampConfig() { if (SkillLossPercent.Value < 0f) { SkillLossPercent.Value = 0f; } if (SkillLossPercent.Value > 100f) { SkillLossPercent.Value = 100f; } if (MercyEffectDuration.Value < 0f) { MercyEffectDuration.Value = 0f; } if (float.IsPositiveInfinity(MercyEffectDuration.Value)) { MercyEffectDuration.Value = float.MaxValue; } if (SafetyEffectDuration.Value < 0f) { SafetyEffectDuration.Value = 0f; } if (float.IsPositiveInfinity(SafetyEffectDuration.Value)) { SafetyEffectDuration.Value = float.MaxValue; } } }