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 PeakManhuntRacing;
[BepInPlugin("com.peak.manhunt.racing", "PEAK Manhunt/Racing Mod", "1.1.2")]
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.1.2";
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)"Rebuilt PEAK Manhunt/Racing patches applied.");
}
catch (Exception ex)
{
Log.LogError((object)("Failed to apply rebuilt 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 missing, falling back to original interaction.");
return true;
}
Plugin.SuppressNextFogOriginReset = true;
Plugin.Log.LogInfo((object)"Lighting campfire with normal segment advance path.");
Plugin.Log.LogInfo((object)("Advance segment: " + ((AdvanceToSegmentField != null) ? AdvanceToSegmentField.GetValue(__instance) : "null")));
val2.RPC("Light_Rpc", (RpcTarget)0, new object[2] { true, 0f });
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error in CampfireInteractCastFinishedPatch: " + ex));
return true;
}
}
}
[HarmonyPatch(typeof(OrbFogHandler), "SetFogOrigin")]
internal static class OrbFogHandlerSetFogOriginPatch
{
[HarmonyPrefix]
private static bool Prefix(int id)
{
if (!Plugin.SuppressNextFogOriginReset)
{
return true;
}
Plugin.SuppressNextFogOriginReset = false;
Plugin.Log.LogInfo((object)("Skipping fog-origin reset after campfire reveal. Requested id: " + id));
return false;
}
}
[HarmonyPatch]
internal static class MapHandlerTransitionPatch
{
private static readonly FieldInfo MapHandlerSegmentsField = AccessTools.Field(typeof(MapHandler), "segments");
private static readonly FieldInfo MapHandlerCurrentSegmentField = AccessTools.Field(typeof(MapHandler), "currentSegment");
private static readonly FieldInfo MapSegmentParentField = AccessTools.Field(typeof(MapSegment), "_segmentParent");
private static readonly FieldInfo MapSegmentCampfireField = AccessTools.Field(typeof(MapSegment), "_segmentCampfire");
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[] nestedTypes = typeof(MapHandler).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
foreach (Type type in nestedTypes)
{
if (type.Name.IndexOf("DisplayClass", StringComparison.Ordinal) < 0)
{
continue;
}
Type[] nestedTypes2 = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
foreach (Type type2 in nestedTypes2)
{
if (type2.Name.IndexOf("ShowNextSegmentCoroutine", StringComparison.Ordinal) >= 0)
{
return AccessTools.Method(type2, "MoveNext", (Type[])null, (Type[])null);
}
}
}
return null;
}
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
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(MapSegment), "get_segmentCampfire", (Type[])null, (Type[])null);
bool flag = false;
bool flag2 = false;
for (int i = 0; i < list.Count - 1; i++)
{
MethodInfo methodInfo3 = list[i + 1].operand as MethodInfo;
if (list[i + 1].opcode.Equals(OpCodes.Callvirt) && !(methodInfo3 != methodInfo) && !flag && list[i].opcode.Equals(OpCodes.Ldc_I4_0))
{
list[i].opcode = OpCodes.Ldc_I4_1;
flag = true;
break;
}
}
for (int i = 0; i < list.Count - 1; i++)
{
MethodInfo methodInfo3 = list[i + 1].operand as MethodInfo;
if (!list[i + 1].opcode.Equals(OpCodes.Callvirt) || methodInfo3 != methodInfo || !list[i].opcode.Equals(OpCodes.Ldc_I4_0))
{
continue;
}
bool flag3 = false;
int num = i - 1;
while (num >= 0 && num >= i - 12)
{
MethodInfo methodInfo4 = list[num].operand as MethodInfo;
if ((list[num].opcode.Equals(OpCodes.Callvirt) || list[num].opcode.Equals(OpCodes.Call)) && methodInfo4 == methodInfo2)
{
flag3 = true;
break;
}
num--;
}
if (flag3)
{
list[i].opcode = OpCodes.Ldc_I4_1;
flag2 = true;
}
}
if (!flag)
{
Plugin.Log.LogWarning((object)"Could not find previous-segment deactivation call in transition coroutine.");
}
if (!flag2)
{
Plugin.Log.LogWarning((object)"Could not find previous campfire-area deactivation call in transition coroutine.");
}
return list;
}
[HarmonyPostfix]
private static void Postfix(object __instance, bool __result)
{
try
{
if (__result)
{
return;
}
MapHandler mapHandlerFromStateMachine = GetMapHandlerFromStateMachine(__instance);
if ((Object)(object)mapHandlerFromStateMachine == (Object)null || MapHandlerSegmentsField == null || MapHandlerCurrentSegmentField == null)
{
return;
}
Array array = MapHandlerSegmentsField.GetValue(mapHandlerFromStateMachine) as Array;
int num = (int)MapHandlerCurrentSegmentField.GetValue(mapHandlerFromStateMachine);
if (array != null && num >= 0 && num < array.Length)
{
for (int i = 0; i < num; i++)
{
ActivateObject(array.GetValue(i), MapSegmentParentField);
ActivateObject(array.GetValue(i), MapSegmentCampfireField);
}
DisableObject(array.GetValue(num), MapSegmentWallPreviousField);
if (num > 0)
{
DisableObject(array.GetValue(num - 1), MapSegmentWallNextField);
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error in map transition postfix: " + ex));
}
}
private static MapHandler GetMapHandlerFromStateMachine(object stateMachine)
{
if (stateMachine == null)
{
return null;
}
FieldInfo fieldInfo = AccessTools.Field(stateMachine.GetType(), "<>4__this");
object obj = ((fieldInfo != null) ? fieldInfo.GetValue(stateMachine) : null);
if (obj == null)
{
return null;
}
FieldInfo fieldInfo2 = AccessTools.Field(obj.GetType(), "<>4__this");
return (MapHandler)((fieldInfo2 != null) ? /*isinst with value type is only supported in some contexts*/: null);
}
private static void ActivateObject(object mapSegment, FieldInfo field)
{
if (mapSegment != null && !(field == null))
{
object? value = field.GetValue(mapSegment);
GameObject val = (GameObject)((value is GameObject) ? value : null);
if ((Object)(object)val != (Object)null)
{
val.SetActive(true);
}
}
}
private static void DisableObject(object mapSegment, FieldInfo field)
{
if (mapSegment != null && !(field == null))
{
object? value = field.GetValue(mapSegment);
GameObject val = (GameObject)((value is GameObject) ? value : null);
if ((Object)(object)val != (Object)null)
{
val.SetActive(false);
}
}
}
}