using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;
[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.0.5")]
public class SelfSacrificePlugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(PlayerHealthGrab), "Update")]
public class PlayerHealthGrabUpdatePatch
{
private static bool Prefix(PlayerHealthGrab __instance, ref float ___grabbingTimer)
{
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
if (!PhotonNetwork.IsMasterClient)
{
return true;
}
if (isTumblingRef.Invoke(__instance.playerAvatar) || SemiFunc.RunIsShop() || SemiFunc.RunIsArena())
{
return true;
}
if (hideLerpRef.Invoke(__instance) > 0f)
{
colliderActiveRef.Invoke(__instance) = false;
}
else if (!isDisabledRef.Invoke(__instance.playerAvatar))
{
colliderActiveRef.Invoke(__instance) = true;
}
physColliderRef.Invoke(__instance).enabled = colliderActiveRef.Invoke(__instance);
((Component)__instance).transform.position = __instance.followTransform.position;
((Component)__instance).transform.rotation = __instance.followTransform.rotation;
if (colliderActiveRef.Invoke(__instance) && staticGrabObjectRef.Invoke(__instance).playerGrabbing.Count > 0)
{
___grabbingTimer += Time.deltaTime;
if (___grabbingTimer >= 1f)
{
foreach (PhysGrabber item in staticGrabObjectRef.Invoke(__instance).playerGrabbing.ToList())
{
if ((Object)(object)item == (Object)null || (Object)(object)item.playerAvatar == (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)"Self Sacrifice: skipping null grabber or grabber with no avatar");
continue;
}
PlayerAvatar playerAvatar = item.playerAvatar;
PlayerHealth playerHealth = playerAvatar.playerHealth;
PlayerHealth playerHealth2 = __instance.playerAvatar.playerHealth;
int num = healthRef.Invoke(playerHealth);
int num2 = healthRef.Invoke(playerHealth2);
int num3 = maxHealthRef.Invoke(playerHealth2);
if (num2 >= num3 || num <= 0)
{
continue;
}
playerHealth.HurtOther(10, Vector3.zero, false, -1);
playerAvatar.HealedOther();
if (num <= 10)
{
float num4 = Random.Range(0f, 1f);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Self Sacrifice: RNG roll = {num4:F4}");
if (num4 <= 0.01f)
{
playerHealth.HealOther(999, true);
playerHealth2.HealOther(999, true);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self Sacrifice: the gods smile on you! both donor and recipient were healed to full health");
}
else if (num4 <= 0.16f)
{
playerHealth2.HurtOther(999, Vector3.zero, false, -1);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self Sacrifice: donor sacrificed themselves to heal their friend, but the recipient was struck down. F in the chat");
}
else if (num4 <= 0.26f)
{
string text = steamIDRef.Invoke(__instance.playerAvatar);
switch (Random.Range(0, 5))
{
case 0:
PunManager.instance.UpgradePlayerHealth(text);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self Sacrifice: recipient granted bonus MAX HEALTH");
break;
case 1:
PunManager.instance.UpgradePlayerEnergy(text);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self Sacrifice: recipient granted bonus STAMINA");
break;
case 2:
PunManager.instance.UpgradePlayerSprintSpeed(text);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self Sacrifice: recipient granted bonus SPRINT SPEED");
break;
case 3:
PunManager.instance.UpgradePlayerExtraJump(text);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self Sacrifice: recipient granted bonus EXTRA JUMP");
break;
case 4:
PunManager.instance.UpgradePlayerGrabStrength(text);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self Sacrifice: recipient granted bonus GRAB STRENGTH");
break;
}
}
else
{
playerHealth2.HealOther(25, true);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: donor sacrificed themselves and healed the recipient successfully");
}
}
else
{
playerHealth2.HealOther(10, true);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: regular heal occurred (no sacrifice)");
}
}
___grabbingTimer = 0f;
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: grabbingTimer1 reset to 0");
}
}
else
{
if (___grabbingTimer != 0f)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Self-Sacrifice: grabbingTimer2 reset to 0");
}
___grabbingTimer = 0f;
}
return false;
}
}
private static readonly FieldRef<PlayerHealthGrab, bool> colliderActiveRef = AccessTools.FieldRefAccess<PlayerHealthGrab, bool>("colliderActive");
private static readonly FieldRef<PlayerHealthGrab, StaticGrabObject> staticGrabObjectRef = AccessTools.FieldRefAccess<PlayerHealthGrab, StaticGrabObject>("staticGrabObject");
private static readonly FieldRef<PlayerHealthGrab, float> hideLerpRef = AccessTools.FieldRefAccess<PlayerHealthGrab, float>("hideLerp");
private static readonly FieldRef<PlayerHealthGrab, Collider> physColliderRef = AccessTools.FieldRefAccess<PlayerHealthGrab, Collider>("physCollider");
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<PlayerAvatar, bool> isTumblingRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isTumbling");
private static readonly FieldRef<PlayerAvatar, bool> isDisabledRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");
private static readonly FieldRef<PlayerAvatar, string> steamIDRef = AccessTools.FieldRefAccess<PlayerAvatar, string>("steamID");
public static SelfSacrificePlugin Instance { get; private set; }
private void Awake()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
new Harmony("mod.selfsacrifice").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"SelfSacrifice 1.0.5 loaded");
}
}