using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("UltimateReviveV2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UltimateReviveV2")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0d2eba79-6bd9-4061-be29-64ecb89fadd3")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UltimateRevive;
[BepInPlugin("Maze.UltimateRevive", "REPO Ultimate Revive", "2.2.1")]
public class UltimateRevive : BaseUnityPlugin
{
public static UltimateRevive Instance;
public static ManualLogSource Log;
private Harmony harmony;
private void Awake()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
ConfigManager.Init(((BaseUnityPlugin)this).Config);
harmony = new Harmony("Maze.UltimateRevive");
harmony.PatchAll();
Log.LogInfo((object)"UltimateRevive Maze Edition loaded (Percent HP Cost / MP / Head Revive)");
Log.LogInfo((object)"Based on the original mod by Quilt, adapted and extended for this version.");
}
}
public static class ConfigManager
{
public static ConfigEntry<float> HpPercentCost;
public static ConfigEntry<string> ReviveKey;
public static void Init(ConfigFile config)
{
HpPercentCost = config.Bind<float>("General", "HP Percent Cost", 0.1f, "Percent of current HP lost when reviving (0.10 = 10%)");
ReviveKey = config.Bind<string>("Controls", "Revive Key", "H", "Key to revive player");
}
}
[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
public static class PlayerControllerPatch
{
public static PlayerDeathHead GrabbedHead;
public static PlayerAvatar GrabbedAvatar;
public static bool IsGrabbing;
private static void Postfix(PlayerController __instance)
{
IsGrabbing = false;
GrabbedHead = null;
GrabbedAvatar = null;
if (Object.op_Implicit((Object)(object)__instance) && __instance.physGrabActive && Object.op_Implicit((Object)(object)__instance.physGrabObject))
{
PlayerDeathHead component = __instance.physGrabObject.GetComponent<PlayerDeathHead>();
if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.playerAvatar))
{
GrabbedHead = component;
GrabbedAvatar = component.playerAvatar;
IsGrabbing = true;
}
}
}
}
[HarmonyPatch(typeof(PhysGrabCart), "Update")]
public static class PhysGrabCartPatch
{
private static void Postfix()
{
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
if (SemiFunc.RunIsShop() || !PlayerControllerPatch.IsGrabbing)
{
return;
}
PlayerAvatar grabbedAvatar = PlayerControllerPatch.GrabbedAvatar;
if (!Object.op_Implicit((Object)(object)grabbedAvatar))
{
return;
}
PlayerController instance = PlayerController.instance;
if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.playerAvatarScript))
{
return;
}
PlayerHealth playerHealth = instance.playerAvatarScript.playerHealth;
if (Object.op_Implicit((Object)(object)playerHealth))
{
int health = Helpers.GetHealth(playerHealth);
float num = Mathf.Clamp01(ConfigManager.HpPercentCost.Value);
int num2 = Mathf.Max(1, Mathf.CeilToInt((float)health * num));
string value = ConfigManager.ReviveKey.Value;
if (health <= num2)
{
ItemInfoExtraUI.instance.ItemInfoText("Not enough HP (need " + num2 + ")", new Color(1f, 0.2f, 0.2f));
return;
}
ItemInfoExtraUI.instance.ItemInfoText("Press [" + value + "] to revive " + ((Object)grabbedAvatar).name + " (-" + num2 + " HP / " + Mathf.RoundToInt(num * 100f) + "%)", new Color(0.2f, 1f, 0.2f));
}
}
}
public class ReviveManager : MonoBehaviourPun
{
private void Update()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
if (!Input.GetKeyDown(Helpers.ParseKey(ConfigManager.ReviveKey.Value)) || !PlayerControllerPatch.IsGrabbing)
{
return;
}
PlayerAvatar grabbedAvatar = PlayerControllerPatch.GrabbedAvatar;
if (!Object.op_Implicit((Object)(object)grabbedAvatar) || !Object.op_Implicit((Object)(object)grabbedAvatar.photonView))
{
return;
}
PlayerController instance = PlayerController.instance;
if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.playerAvatarScript))
{
return;
}
PlayerHealth playerHealth = instance.playerAvatarScript.playerHealth;
if (!Object.op_Implicit((Object)(object)playerHealth))
{
return;
}
int health = Helpers.GetHealth(playerHealth);
float num = Mathf.Clamp01(ConfigManager.HpPercentCost.Value);
int num2 = Mathf.Max(1, Mathf.CeilToInt((float)health * num));
if (health > num2)
{
PhotonView val = PhotonView.Get((Component)(object)this);
if (Object.op_Implicit((Object)(object)val))
{
int viewID = grabbedAvatar.photonView.ViewID;
UltimateRevive.Log.LogInfo((object)("Client requesting revive for " + ((Object)grabbedAvatar).name + " (ViewID " + viewID + ") | Cost " + num2 + " HP"));
val.RPC("HostRevive", (RpcTarget)2, new object[1] { viewID });
playerHealth.Hurt(num2, true, -1);
}
}
}
[PunRPC]
private void HostRevive(int viewID)
{
if (!PhotonNetwork.IsMasterClient)
{
return;
}
UltimateRevive.Log.LogInfo((object)("Master reviving ViewID " + viewID));
PhotonView val = PhotonView.Find(viewID);
if (Object.op_Implicit((Object)(object)val))
{
PlayerAvatar component = ((Component)val).GetComponent<PlayerAvatar>();
if (Object.op_Implicit((Object)(object)component))
{
component.Revive(false);
UltimateRevive.Log.LogInfo((object)"Revive completed by host");
}
}
}
}
[HarmonyPatch(typeof(PlayerController), "Awake")]
public static class InjectPatch
{
private static void Postfix(PlayerController __instance)
{
if (Object.op_Implicit((Object)(object)__instance) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<ReviveManager>()))
{
((Component)__instance).gameObject.AddComponent<ReviveManager>();
UltimateRevive.Log.LogInfo((object)"ReviveManager injected into PlayerController");
}
}
}
public static class Helpers
{
public static KeyCode ParseKey(string key)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrEmpty(key))
{
return (KeyCode)104;
}
try
{
return (KeyCode)Enum.Parse(typeof(KeyCode), key.ToUpperInvariant());
}
catch
{
return (KeyCode)104;
}
}
public static int GetHealth(PlayerHealth health)
{
FieldInfo fieldInfo = AccessTools.Field(((object)health).GetType(), "health");
if (fieldInfo != null)
{
return (int)fieldInfo.GetValue(health);
}
PropertyInfo propertyInfo = AccessTools.Property(((object)health).GetType(), "Health");
if (propertyInfo != null)
{
return (int)propertyInfo.GetValue(health, null);
}
return 0;
}
}