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 SelfSacrifice v1.1.6
self-sacrifice.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Photon.Pun; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("self-sacrifice")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("self-sacrifice")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ae45a597-8fb9-40e6-99b2-7864179fb0c1")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace SelfSacrifice; [BepInPlugin("mod.selfsacrifice", "SelfSacrifice", "1.1.6")] public class SelfSacrificePlugin : BaseUnityPlugin { [HarmonyPatch(typeof(PlayerAvatar), "Start")] public class PlayerAvatarStartPatch { private static void Postfix(PlayerAvatar __instance) { if ((Object)(object)((Component)__instance).GetComponent<PossessChatHandler>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<PossessChatHandler>(); } } } public class PossessChatHandler : MonoBehaviourPun { [PunRPC] public void ForcePossessChat(string message, float typingSpeed, float delay) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ChatManager.instance != (Object)null) { ChatManager.instance.PossessChatScheduleStart(2); ChatManager.instance.PossessChat((PossessChatID)3, message, typingSpeed, Color.yellow, delay, true, 2, (UnityEvent)null); ChatManager.instance.PossessChatScheduleEnd(); } } } [HarmonyPatch(typeof(PlayerHealthGrab), "Update")] public class PlayerHealthGrabPatch { private static void Postfix(PlayerHealthGrab __instance) { //IL_0598: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } List<PhysGrabber> list = staticGrabObjectRef.Invoke(__instance).playerGrabbing.ToList(); float num = grabbingTimerRef.Invoke(__instance); if (list == null || list.Count == 0) { if (num != 0f) { grabbingTimerRef.Invoke(__instance) = 0f; } return; } grabbingTimerRef.Invoke(__instance) = num + Time.deltaTime; if (grabbingTimerRef.Invoke(__instance) < 1f) { return; } foreach (PhysGrabber item in list) { if ((Object)(object)item == (Object)null || (Object)(object)item.playerAvatar == (Object)null || (Object)(object)item.playerAvatar.playerHealth == (Object)null) { continue; } PlayerAvatar playerAvatar = item.playerAvatar; PlayerHealth playerHealth = playerAvatar.playerHealth; PlayerHealth playerHealth2 = __instance.playerAvatar.playerHealth; PlayerAvatar playerAvatar2 = __instance.playerAvatar; int num2 = healthRef.Invoke(playerHealth); int num3 = healthRef.Invoke(playerHealth2); int num4 = maxHealthRef.Invoke(playerHealth2); if (num3 >= num4) { continue; } if (num2 <= 10) { float num5 = Random.Range(0f, 1f); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Self-Sacrifice: RNG roll = {num5:F4}"); if (num5 <= 0.01f) { playerHealth2.HealOther(999, true); playerHealth.HealOther(999, true); playerAvatar.HealedOther(); string text = RareHealChats[Random.Range(0, RareHealChats.Count)]; ((Component)playerAvatar2).GetComponent<PhotonView>().RPC("ForcePossessChat", ((Component)playerAvatar2).GetComponent<PhotonView>().Owner, new object[3] { text, 3f, 0f }); playerAvatar2.OverridePupilSize(3f, 4, 1f, 1f, 15f, 0.3f, 3f); playerAvatar2.playerHealth.EyeMaterialOverride((EyeOverrideState)3, 5f, 10); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: super-rare RNG roll achieved, both players healed to full"); } else if (num5 <= 0.21f) { playerHealth.HurtOther(10, Vector3.zero, false, -1); ((MonoBehaviour)playerAvatar2).StartCoroutine(Instance.DelayedKill(playerAvatar2, 5f)); string text2 = FailedHealChats[Random.Range(0, FailedHealChats.Count)]; ((Component)playerAvatar2).GetComponent<PhotonView>().RPC("ForcePossessChat", ((Component)playerAvatar2).GetComponent<PhotonView>().Owner, new object[3] { text2, 3f, 0f }); playerAvatar2.OverridePupilSize(4f, 4, 1f, 1f, 15f, 0.3f, 3f); playerAvatar2.playerHealth.EyeMaterialOverride((EyeOverrideState)1, 5f, 10); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: recipient struck down during sacrifice. F in chat"); } else if (num5 <= 0.31f) { string text3 = steamIDRef.Invoke(playerAvatar2); int num6 = Random.Range(0, 6); string text4 = ""; switch (num6) { case 0: PunManager.instance.UpgradePlayerHealth(text3); text4 = "I feel healthy as a horse"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: recipient granted bonus MAX HEALTH"); break; case 1: PunManager.instance.UpgradePlayerEnergy(text3); text4 = "I could run a marathon right now"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: recipient granted bonus STAMINA"); break; case 2: PunManager.instance.UpgradePlayerSprintSpeed(text3); text4 = "I am speeeeeeeeeeed"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: recipient granted bonus SPRINT SPEED"); break; case 3: PunManager.instance.UpgradePlayerExtraJump(text3); text4 = "boing boing"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: recipient granted bonus EXTRA JUMP"); break; case 4: PunManager.instance.UpgradePlayerGrabStrength(text3); text4 = "strength blessing activate"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: recipient granted bonus GRAB STRENGTH"); break; case 5: PunManager.instance.UpgradePlayerTumbleLaunch(text3); text4 = "launch blessing activate"; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: recipient granted bonus TUMBLE LAUNCH"); break; } playerHealth.HurtOther(10, Vector3.zero, false, -1); ((Component)playerAvatar2).GetComponent<PhotonView>().RPC("ForcePossessChat", ((Component)playerAvatar2).GetComponent<PhotonView>().Owner, new object[3] { text4, 3f, 0f }); playerAvatar2.OverridePupilSize(3f, 4, 1f, 1f, 15f, 0.3f, 3f); playerAvatar2.playerHealth.EyeMaterialOverride((EyeOverrideState)3, 5f, 10); } else { playerHealth2.HealOther(25, true); playerHealth.HurtOther(10, Vector3.zero, false, -1); playerAvatar.HealedOther(); string text5 = SuccessfulHealChats[Random.Range(0, SuccessfulHealChats.Count)]; ((Component)playerAvatar2).GetComponent<PhotonView>().RPC("ForcePossessChat", ((Component)playerAvatar2).GetComponent<PhotonView>().Owner, new object[3] { text5, 3f, 0f }); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: donor healed recipient successfully"); } } else { playerHealth2.HealOther(10, true); playerHealth.HurtOther(10, Vector3.zero, false, -1); playerAvatar.HealedOther(); } } grabbingTimerRef.Invoke(__instance) = 0f; } } [CompilerGenerated] private sealed class <DelayedKill>d__18 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public PlayerAvatar recipient; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedKill>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; recipient.playerHealth.HurtOther(999, Vector3.zero, false, -1); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly FieldRef<PlayerHealthGrab, StaticGrabObject> staticGrabObjectRef = AccessTools.FieldRefAccess<PlayerHealthGrab, StaticGrabObject>("staticGrabObject"); private static readonly FieldRef<PlayerHealth, int> healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health"); private static readonly FieldRef<PlayerHealth, int> maxHealthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("maxHealth"); private static readonly FieldRef<PlayerHealthGrab, float> grabbingTimerRef = AccessTools.FieldRefAccess<PlayerHealthGrab, float>("grabbingTimer"); private static readonly FieldRef<PlayerAvatar, string> steamIDRef = AccessTools.FieldRefAccess<PlayerAvatar, string>("steamID"); private static List<string> SuccessfulHealChats = new List<string>(); private static List<string> FailedHealChats = new List<string>(); private static List<string> RareHealChats = new List<string>(); public static SelfSacrificePlugin Instance { get; private set; } public static ManualLogSource LogInstance { get; private set; } private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Instance = this; LogInstance = ((BaseUnityPlugin)this).Logger; new Harmony("mod.selfsacrifice").PatchAll(); LoadHealMessages(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"SelfSacrifice 1.1.5 loaded"); } private void LoadHealMessages() { SuccessfulHealChats = new List<string>(); FailedHealChats = new List<string>(); RareHealChats = new List<string>(); try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith("HealChats.txt")); if (text == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"HealChats.txt embedded resource not found"); return; } using (Stream stream = executingAssembly.GetManifestResourceStream(text)) { using StreamReader streamReader = new StreamReader(stream); List<string> list = SuccessfulHealChats; while (!streamReader.EndOfStream) { string text2 = streamReader.ReadLine().Trim(); if (string.IsNullOrEmpty(text2)) { continue; } if (text2.StartsWith("#")) { if (text2.Contains("SuccessfulHealChats")) { list = SuccessfulHealChats; } else if (text2.Contains("FailedHealChats")) { list = FailedHealChats; } else if (text2.Contains("RareHealChats")) { list = RareHealChats; } } else { list.Add(text2); } } } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"loaded {SuccessfulHealChats.Count} successful chats, {FailedHealChats.Count} failed chats, {RareHealChats.Count} rare chats"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("failed to load HealChats.txt: " + ex.Message)); } } [IteratorStateMachine(typeof(<DelayedKill>d__18))] public IEnumerator DelayedKill(PlayerAvatar recipient, float delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedKill>d__18(0) { recipient = recipient, delay = delay }; } }