111 lines
3.6 KiB
C#
111 lines
3.6 KiB
C#
using System;
|
|
using DevourClient.Network;
|
|
using MelonLoader;
|
|
using UnityEngine;
|
|
|
|
namespace DevourClient.Helpers
|
|
{
|
|
/// <summary>
|
|
/// Shared revive utilities. When running as host we mirror DevourX's revive flow.
|
|
/// </summary>
|
|
public static class ReviveHelper
|
|
{
|
|
private static readonly Vector3 HostFallbackPosition = new Vector3(0f, -150f, 0f);
|
|
|
|
/// <summary>
|
|
/// Try to revive the provided NolanBehaviour using host-specific logic first,
|
|
/// then fall back to the standard interactable flow.
|
|
/// </summary>
|
|
public static bool TryRevive(Il2Cpp.NolanBehaviour target)
|
|
{
|
|
if (target == null || target.gameObject == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (TryHostRevive(target))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return TryInteractRevive(target);
|
|
}
|
|
|
|
private static bool TryHostRevive(Il2Cpp.NolanBehaviour target)
|
|
{
|
|
if (!NetworkHelper.IsHost() || !Player.IsInGame())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!target.IsCrawling())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
Il2Cpp.SurvivalReviveInteractable interactable = UnityEngine.Object.FindObjectOfType<Il2Cpp.SurvivalReviveInteractable>();
|
|
if (interactable == null)
|
|
{
|
|
target.TeleportTo(HostFallbackPosition, Quaternion.identity);
|
|
MelonLogger.Msg("[ReviveHelper] Host fallback teleport executed (no interactable found).");
|
|
return true;
|
|
}
|
|
|
|
interactable.Interact(target.gameObject);
|
|
MelonLogger.Msg("[ReviveHelper] Host revive interactable triggered.");
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MelonLogger.Warning($"[ReviveHelper] Host revive flow failed: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static bool TryInteractRevive(Il2Cpp.NolanBehaviour target)
|
|
{
|
|
try
|
|
{
|
|
Il2Cpp.SurvivalReviveInteractable interactable = UnityEngine.Object.FindObjectOfType<Il2Cpp.SurvivalReviveInteractable>();
|
|
if (interactable == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (interactable.CanInteract(target.gameObject))
|
|
{
|
|
interactable.Interact(target.gameObject);
|
|
return true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MelonLogger.Warning($"[ReviveHelper] Interact revive failed: {ex.Message}");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Legacy revive method migrated from StateHelper.BasePlayer.Revive().
|
|
/// This method preserves the original implementation from StateHelper.
|
|
/// </summary>
|
|
/// <param name="targetGameObject">The GameObject of the player to revive</param>
|
|
public static void ReviveLegacy(GameObject targetGameObject)
|
|
{
|
|
if (targetGameObject == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Il2Cpp.NolanBehaviour nb = targetGameObject.GetComponent<Il2Cpp.NolanBehaviour>();
|
|
Il2Cpp.SurvivalReviveInteractable _reviveInteractable = UnityEngine.Object.FindObjectOfType<Il2Cpp.SurvivalReviveInteractable>();
|
|
|
|
if (_reviveInteractable.CanInteract(nb.gameObject) == true) { _reviveInteractable.Interact(nb.gameObject); }
|
|
}
|
|
}
|
|
}
|
|
|