using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace RemoveCampfireRestriction;
[BepInPlugin("com.peak.manhunt.racing", "PEAK Manhunt/Racing Mod", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "com.peak.manhunt.racing";
public const string PluginName = "PEAK Manhunt/Racing Mod";
public const string PluginVersion = "1.0.0";
internal static ManualLogSource Log;
internal static bool SuppressNextFogOriginReset;
private void Awake()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
try
{
new Harmony("com.peak.manhunt.racing").PatchAll(typeof(Plugin).Assembly);
Log.LogInfo((object)"Updated campfire patches applied.");
}
catch (Exception ex)
{
Log.LogError((object)("Failed to apply Harmony patches: " + ex));
}
}
}
[HarmonyPatch]
internal static class CampfireEveryoneInRangeFloatPatch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(Campfire), "EveryoneInRange", new Type[1] { typeof(float) }, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(ref bool __result)
{
__result = true;
return false;
}
}
[HarmonyPatch]
internal static class CampfireEveryoneInRangeMessagePatch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(Campfire), "EveryoneInRange", new Type[2]
{
typeof(string).MakeByRefType(),
typeof(float)
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(Campfire __instance, ref string printout, ref bool __result)
{
try
{
printout = BuildMissingPlayersText(__instance);
__result = true;
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error in CampfireEveryoneInRangePatch: " + ex));
return true;
}
}
internal static string BuildMissingPlayersText(Campfire campfire)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
string text = string.Empty;
Vector3 position = ((Component)campfire).transform.position;
foreach (Character allPlayerCharacter in PlayerHandler.GetAllPlayerCharacters())
{
if (!((Object)(object)allPlayerCharacter == (Object)null) && !((Object)(object)allPlayerCharacter.data == (Object)null) && !allPlayerCharacter.data.dead)
{
float num = Vector3.Distance(position, allPlayerCharacter.Center);
if (!(num <= 15f))
{
Player val = (((Object)(object)((MonoBehaviourPun)allPlayerCharacter).photonView != (Object)null) ? ((MonoBehaviourPun)allPlayerCharacter).photonView.Owner : null);
string text2 = ((val != null) ? val.NickName : "Unknown");
int num2 = Mathf.RoundToInt(num * CharacterStats.unitsToMeters);
object obj = text;
text = string.Concat(obj, "\n", text2, " ", num2, "m");
}
}
}
return string.IsNullOrEmpty(text) ? string.Empty : ("other players location:" + text);
}
}
[HarmonyPatch(typeof(Campfire), "GetInteractionText")]
internal static class CampfireGetInteractionTextPatch
{
[HarmonyPrefix]
private static bool Prefix(Campfire __instance, ref string __result)
{
try
{
if (!__instance.Lit)
{
string text = CampfireEveryoneInRangeMessagePatch.BuildMissingPlayersText(__instance);
__result = (string.IsNullOrEmpty(text) ? LocalizedText.GetText("LIGHT", true) : (LocalizedText.GetText("LIGHT", true) + "\n" + text));
return false;
}
__result = LocalizedText.GetText("COOK", true);
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error in CampfireGetInteractionTextPatch: " + ex));
return true;
}
}
}
[HarmonyPatch(typeof(Campfire), "Interact_CastFinished")]
internal static class CampfireInteractCastFinishedPatch
{
private static readonly FieldInfo CurrentCookingItemField = AccessTools.Field(typeof(Campfire), "currentlyCookingItem");
private static readonly FieldInfo ViewField = AccessTools.Field(typeof(Campfire), "view");
private static readonly FieldInfo AdvanceToSegmentField = AccessTools.Field(typeof(Campfire), "advanceToSegment");
[HarmonyPrefix]
private static bool Prefix(Campfire __instance)
{
try
{
if (__instance.Lit)
{
Item val = (Item)((CurrentCookingItemField != null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val != (Object)null)
{
((Component)val).GetComponent<ItemCooking>().FinishCooking();
}
return false;
}
PhotonView val2 = (PhotonView)((ViewField != null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val2 == (Object)null)
{
Plugin.Log.LogWarning((object)"Campfire view was missing, falling back to original interaction.");
return true;
}
object obj = ((AdvanceToSegmentField != null) ? AdvanceToSegmentField.GetValue(__instance) : null);
Plugin.Log.LogInfo((object)"Lighting campfire with normal segment advance path.");
Plugin.Log.LogInfo((object)("Advance segment: " + (obj ?? "null")));
Plugin.SuppressNextFogOriginReset = true;
val2.RPC("Light_Rpc", (RpcTarget)0, new object[1] { true });
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error in CampfireInteractCastFinishedPatch: " + ex));
return true;
}
}
}
[HarmonyPatch]
internal static class MapHandlerKeepPreviousSegmentPatch
{
private static readonly FieldInfo StateMachineDisplayClassField = AccessTools.Field(typeof(MapHandler).Assembly.GetType("MapHandler+<>c__DisplayClass49_0+<<GoToSegment>g__ShowNextSegmentCoroutine|0>d"), "<>4__this");
private static readonly FieldInfo DisplayClassMapHandlerField = AccessTools.Field(typeof(MapHandler).Assembly.GetType("MapHandler+<>c__DisplayClass49_0"), "<>4__this");
private static readonly FieldInfo MapHandlerSegmentsField = AccessTools.Field(typeof(MapHandler), "segments");
private static readonly FieldInfo MapHandlerCurrentSegmentField = AccessTools.Field(typeof(MapHandler), "currentSegment");
private static readonly FieldInfo MapSegmentWallNextField = AccessTools.Field(typeof(MapSegment), "wallNext");
private static readonly FieldInfo MapSegmentWallPreviousField = AccessTools.Field(typeof(MapSegment), "wallPrevious");
private static MethodBase TargetMethod()
{
Type type = AccessTools.Inner(typeof(MapHandler), "<>c__DisplayClass49_0");
if (type == null)
{
return null;
}
Type type2 = AccessTools.Inner(type, "<<GoToSegment>g__ShowNextSegmentCoroutine|0>d");
return (type2 != null) ? AccessTools.Method(type2, "MoveNext", (Type[])null, (Type[])null) : null;
}
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
MethodInfo methodInfo = AccessTools.Method(typeof(GameObject), "SetActive", new Type[1] { typeof(bool) }, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(OrbFogHandler), "SetFogOrigin", new Type[1] { typeof(int) }, (Type[])null);
bool flag = false;
bool flag2 = false;
bool flag3 = false;
FieldInfo objB = AccessTools.Field(typeof(MapSegment), "wallPrevious");
for (int i = 0; i < list.Count; i++)
{
MethodInfo methodInfo3 = list[i].operand as MethodInfo;
if (!flag3 && list[i].opcode.Equals(OpCodes.Callvirt) && methodInfo3 == methodInfo2)
{
list[i].opcode = OpCodes.Pop;
list[i].operand = null;
list.Insert(i + 1, new CodeInstruction(OpCodes.Pop, (object)null));
flag3 = true;
i++;
}
else
{
if (i >= list.Count - 1)
{
continue;
}
MethodInfo methodInfo4 = list[i + 1].operand as MethodInfo;
if (list[i + 1].opcode.Equals(OpCodes.Callvirt) && !(methodInfo4 != methodInfo))
{
if (!flag && list[i].opcode.Equals(OpCodes.Ldc_I4_0))
{
list[i].opcode = OpCodes.Ldc_I4_1;
flag = true;
}
else if (!flag2 && list[i].opcode.Equals(OpCodes.Ldc_I4_1) && i >= 1 && object.Equals(list[i - 1].operand as FieldInfo, objB))
{
list[i].opcode = OpCodes.Ldc_I4_0;
flag2 = true;
}
}
}
}
if (!flag)
{
Plugin.Log.LogWarning((object)"KeepPreviousSegment patch could not find the old-segment deactivation call.");
}
if (!flag2)
{
Plugin.Log.LogWarning((object)"KeepPreviousSegment patch could not find the previous-wall activation call.");
}
if (!flag3)
{
Plugin.Log.LogWarning((object)"KeepPreviousSegment patch could not find the fog-origin reset call.");
}
return list;
}
[HarmonyPostfix]
private static void Postfix(object __instance, bool __result)
{
try
{
if (__result)
{
return;
}
object obj = ((StateMachineDisplayClassField != null) ? StateMachineDisplayClassField.GetValue(__instance) : null);
MapHandler val = (MapHandler)((obj != null && DisplayClassMapHandlerField != null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val == (Object)null || MapHandlerSegmentsField == null || MapHandlerCurrentSegmentField == null)
{
return;
}
Array array = MapHandlerSegmentsField.GetValue(val) as Array;
int num = (int)MapHandlerCurrentSegmentField.GetValue(val);
if (array != null && num >= 0 && num < array.Length)
{
DisableWall(array.GetValue(num), MapSegmentWallPreviousField);
if (num > 0)
{
DisableWall(array.GetValue(num - 1), MapSegmentWallNextField);
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error in KeepPreviousSegment postfix: " + ex));
}
}
private static void DisableWall(object mapSegment, FieldInfo wallField)
{
if (mapSegment != null && !(wallField == null))
{
object? value = wallField.GetValue(mapSegment);
GameObject val = (GameObject)((value is GameObject) ? value : null);
if ((Object)(object)val != (Object)null)
{
val.SetActive(false);
}
}
}
}
[HarmonyPatch(typeof(OrbFogHandler), "SetFogOrigin")]
internal static class OrbFogHandlerSetFogOriginPatch
{
[HarmonyPrefix]
private static bool Prefix(int index)
{
if (!Plugin.SuppressNextFogOriginReset)
{
return true;
}
Plugin.SuppressNextFogOriginReset = false;
Plugin.Log.LogInfo((object)("Skipping fog-origin reset after campfire reveal. Requested index: " + index));
return false;
}
}