using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Lurid_Looming_Lookers;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Lurid Looming Lookers")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Lurid Looming Lookers")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ce43d2ac-cbdc-4a78-b61b-eaabca5ceb3d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Lurid_Looming_Lookers
{
[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[DebuggerNonUserCode]
[CompilerGenerated]
internal class Resource1
{
private static ResourceManager resourceMan;
private static CultureInfo resourceCulture;
[EditorBrowsable(EditorBrowsableState.Advanced)]
internal static ResourceManager ResourceManager
{
get
{
if (resourceMan == null)
{
ResourceManager resourceManager = new ResourceManager("Lurid_Looming_Lookers.Resource1", typeof(Resource1).Assembly);
resourceMan = resourceManager;
}
return resourceMan;
}
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
internal static CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
internal static byte[] whisperaudio
{
get
{
object @object = ResourceManager.GetObject("whisperaudio", resourceCulture);
return (byte[])@object;
}
}
internal Resource1()
{
}
}
}
namespace LuridLoomingLookers
{
[BepInPlugin("tony4twentys.Lurid_Looming_Lookers", "Lurid Looming Lookers", "1.0.0")]
public class LuridLoomingLookersPlugin : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <EnableAllLookersAfterDelay>d__23 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LuridLoomingLookersPlugin <>4__this;
private GameObject <globalLooker>5__1;
private Looker[] <allLookers>5__2;
private Looker[] <>s__3;
private int <>s__4;
private Looker <looker>5__5;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EnableAllLookersAfterDelay>d__23(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<globalLooker>5__1 = null;
<allLookers>5__2 = null;
<>s__3 = null;
<looker>5__5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(2f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<globalLooker>5__1 = GameObject.Find("Map/Global/Looker");
if ((Object)(object)<globalLooker>5__1 != (Object)null)
{
logger.LogInfo((object)"Found Map/Global/Looker");
<allLookers>5__2 = <globalLooker>5__1.GetComponentsInChildren<Looker>(true);
logger.LogInfo((object)$"Found {<allLookers>5__2.Length} Lookers total (including inactive)");
<>s__3 = <allLookers>5__2;
for (<>s__4 = 0; <>s__4 < <>s__3.Length; <>s__4++)
{
<looker>5__5 = <>s__3[<>s__4];
if ((Object)(object)<looker>5__5 != (Object)null)
{
((Component)<looker>5__5).gameObject.SetActive(true);
logger.LogInfo((object)("Enabled Looker: " + ((Object)((Component)<looker>5__5).gameObject).name));
}
<looker>5__5 = null;
}
<>s__3 = null;
<allLookers>5__2 = null;
}
else
{
logger.LogWarning((object)"Could not find Map/Global/Looker");
}
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.FindCampfiresAfterDelay());
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <FindCampfiresAfterDelay>d__24 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LuridLoomingLookersPlugin <>4__this;
private Campfire[] <campfires>5__1;
private Segment <currentSegment>5__2;
private BiomeType <currentBiome>5__3;
private int <i>5__4;
private Campfire <campfire>5__5;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <FindCampfiresAfterDelay>d__24(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<campfires>5__1 = null;
<campfire>5__5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
logger.LogInfo((object)"Looking for campfires and current segment...");
if ((Object)(object)Singleton<MapHandler>.Instance != (Object)null)
{
<currentSegment>5__2 = Singleton<MapHandler>.Instance.GetCurrentSegment();
<currentBiome>5__3 = Singleton<MapHandler>.Instance.GetCurrentBiome();
logger.LogInfo((object)$"Current segment: {<currentSegment>5__2}, Biome: {<currentBiome>5__3}");
}
else
{
logger.LogWarning((object)"MapHandler.Instance is null!");
}
<campfires>5__1 = Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0);
logger.LogInfo((object)$"Found {<campfires>5__1.Length} campfires");
if (<campfires>5__1.Length != 0)
{
<i>5__4 = 0;
while (<i>5__4 < <campfires>5__1.Length)
{
<campfire>5__5 = <campfires>5__1[<i>5__4];
if ((Object)(object)<campfire>5__5 != (Object)null && (Object)(object)((Component)<campfire>5__5).transform != (Object)null)
{
logger.LogInfo((object)$"Campfire {<i>5__4}: {((Object)<campfire>5__5).name} at {((Component)<campfire>5__5).transform.position}, advances to: {<campfire>5__5.advanceToSegment}");
}
<campfire>5__5 = null;
<i>5__4++;
}
}
else
{
logger.LogWarning((object)"No campfires found in scene!");
}
if (<campfires>5__1.Length >= 2)
{
logger.LogInfo((object)"Starting Berrynana dropping process...");
((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.GenerateSegmentLookerPositions(<campfires>5__1));
}
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <GenerateSegmentLookerPositions>d__27 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Campfire[] campfires;
public LuridLoomingLookersPlugin <>4__this;
private Campfire <campfire1>5__1;
private Campfire <campfire2>5__2;
private Vector3 <pos1>5__3;
private Vector3 <pos2>5__4;
private Vector3 <centerPoint>5__5;
private float <segmentLength>5__6;
private int <numItems>5__7;
private List<GameObject> <fallingItems>5__8;
private Vector3 <direction>5__9;
private Vector3 <perpendicular>5__10;
private float <rectWidth>5__11;
private int <i>5__12;
private int <i>5__13;
private float <lineProgress>5__14;
private float <sideOffset>5__15;
private Vector3 <linePosition>5__16;
private Vector3 <sideOffsetVector>5__17;
private Vector3 <randomPos>5__18;
private GameObject <fallingItem>5__19;
private Rigidbody <rb>5__20;
private List<GameObject>.Enumerator <>s__21;
private GameObject <fallingItem>5__22;
private Vector3 <finalPos>5__23;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GenerateSegmentLookerPositions>d__27(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<campfire1>5__1 = null;
<campfire2>5__2 = null;
<fallingItems>5__8 = null;
<fallingItem>5__19 = null;
<rb>5__20 = null;
<>s__21 = default(List<GameObject>.Enumerator);
<fallingItem>5__22 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0226: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
//IL_050f: Unknown result type (might be due to invalid IL or missing references)
//IL_0514: Unknown result type (might be due to invalid IL or missing references)
//IL_051f: Unknown result type (might be due to invalid IL or missing references)
//IL_032a: Unknown result type (might be due to invalid IL or missing references)
//IL_0330: Unknown result type (might be due to invalid IL or missing references)
//IL_0342: Unknown result type (might be due to invalid IL or missing references)
//IL_0347: Unknown result type (might be due to invalid IL or missing references)
//IL_034c: Unknown result type (might be due to invalid IL or missing references)
//IL_0353: Unknown result type (might be due to invalid IL or missing references)
//IL_035e: Unknown result type (might be due to invalid IL or missing references)
//IL_0363: Unknown result type (might be due to invalid IL or missing references)
//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
//IL_03be: Unknown result type (might be due to invalid IL or missing references)
//IL_049f: Unknown result type (might be due to invalid IL or missing references)
//IL_04a9: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
if (!PhotonNetwork.IsMasterClient)
{
logger.LogInfo((object)"Not master client, skipping Berrynana dropping");
return false;
}
_currentSegmentLookerPositions.Clear();
_segmentPositionsReady = false;
<campfire1>5__1 = null;
<campfire2>5__2 = null;
<i>5__12 = 0;
while (<i>5__12 < campfires.Length)
{
if ((Object)(object)campfires[<i>5__12] != (Object)null)
{
if ((Object)(object)<campfire1>5__1 == (Object)null)
{
<campfire1>5__1 = campfires[<i>5__12];
}
else
{
if (!((Object)(object)<campfire2>5__2 == (Object)null))
{
break;
}
<campfire2>5__2 = campfires[<i>5__12];
}
}
<i>5__12++;
}
if ((Object)(object)<campfire1>5__1 == (Object)null || (Object)(object)<campfire2>5__2 == (Object)null)
{
logger.LogWarning((object)"Could not find two valid campfires for Berrynana dropping");
return false;
}
<pos1>5__3 = ((Component)<campfire1>5__1).transform.position;
<pos2>5__4 = ((Component)<campfire2>5__2).transform.position;
<centerPoint>5__5 = new Vector3((<pos1>5__3.x + <pos2>5__4.x) / 2f, Mathf.Max(<pos1>5__3.y, <pos2>5__4.y), (<pos1>5__3.z + <pos2>5__4.z) / 2f);
<segmentLength>5__6 = Vector3.Distance(new Vector3(<pos1>5__3.x, 0f, <pos1>5__3.z), new Vector3(<pos2>5__4.x, 0f, <pos2>5__4.z));
logger.LogInfo((object)"Dropping 120 Berrynana items between campfires:");
logger.LogInfo((object)$" Campfire 1: {<pos1>5__3}");
logger.LogInfo((object)$" Campfire 2: {<pos2>5__4}");
logger.LogInfo((object)$" Center: {<centerPoint>5__5}, Segment length: {<segmentLength>5__6:F1}m");
<numItems>5__7 = 120;
<fallingItems>5__8 = new List<GameObject>();
Vector3 val = <pos2>5__4 - <pos1>5__3;
<direction>5__9 = ((Vector3)(ref val)).normalized;
val = Vector3.Cross(<direction>5__9, Vector3.up);
<perpendicular>5__10 = ((Vector3)(ref val)).normalized;
<rectWidth>5__11 = <segmentLength>5__6 * 0.3f;
<i>5__13 = 0;
while (<i>5__13 < <numItems>5__7)
{
<lineProgress>5__14 = Random.Range(0f, 1f);
<sideOffset>5__15 = Random.Range(-0.5f, 0.5f) * <rectWidth>5__11;
<linePosition>5__16 = <pos1>5__3 + <direction>5__9 * (<lineProgress>5__14 * <segmentLength>5__6);
<sideOffsetVector>5__17 = <perpendicular>5__10 * <sideOffset>5__15;
<randomPos>5__18 = new Vector3(<linePosition>5__16.x + <sideOffsetVector>5__17.x, <centerPoint>5__5.y + 300f, <linePosition>5__16.z + <sideOffsetVector>5__17.z);
<fallingItem>5__19 = PhotonNetwork.Instantiate("0_Items/Berrynana Peel Yellow", <randomPos>5__18, Random.rotation, (byte)0, (object[])null);
if (!((Object)(object)<fallingItem>5__19 == (Object)null))
{
<rb>5__20 = <fallingItem>5__19.GetComponent<Rigidbody>();
if ((Object)(object)<rb>5__20 == (Object)null)
{
<rb>5__20 = <fallingItem>5__19.AddComponent<Rigidbody>();
}
<rb>5__20.mass = 1f;
<fallingItems>5__8.Add(<fallingItem>5__19);
<fallingItem>5__19 = null;
<rb>5__20 = null;
}
<i>5__13++;
}
logger.LogInfo((object)$"Spawned {<fallingItems>5__8.Count} Berrynana items, waiting for them to settle...");
<>2__current = (object)new WaitForSeconds(13f);
<>1__state = 1;
return true;
}
case 1:
<>1__state = -1;
logger.LogInfo((object)"Collecting final positions...");
<>s__21 = <fallingItems>5__8.GetEnumerator();
try
{
while (<>s__21.MoveNext())
{
<fallingItem>5__22 = <>s__21.Current;
if (!((Object)(object)<fallingItem>5__22 == (Object)null))
{
<finalPos>5__23 = <fallingItem>5__22.transform.position;
_currentSegmentLookerPositions.Add(<finalPos>5__23);
PhotonNetwork.Destroy(<fallingItem>5__22);
<fallingItem>5__22 = null;
}
}
}
finally
{
((IDisposable)<>s__21).Dispose();
}
<>s__21 = default(List<GameObject>.Enumerator);
logger.LogInfo((object)$"Collected {_currentSegmentLookerPositions.Count} positions for Looker spawning");
_segmentPositionsReady = true;
<>4__this.SpawnLookersAtPositions(campfires);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <WaitForSegmentLoadAndDetect>d__25 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LuridLoomingLookersPlugin <>4__this;
private Campfire[] <campfires>5__1;
private Segment <currentSegment>5__2;
private BiomeType <currentBiome>5__3;
private int <i>5__4;
private Campfire <campfire>5__5;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitForSegmentLoadAndDetect>d__25(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<campfires>5__1 = null;
<campfire>5__5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>4__this.CleanupSpawnedLookers();
<>2__current = (object)new WaitForSeconds(8f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
logger.LogInfo((object)"Segment load delay complete, detecting new campfires and segment...");
if ((Object)(object)Singleton<MapHandler>.Instance != (Object)null)
{
<currentSegment>5__2 = Singleton<MapHandler>.Instance.GetCurrentSegment();
<currentBiome>5__3 = Singleton<MapHandler>.Instance.GetCurrentBiome();
logger.LogInfo((object)$"New segment: {<currentSegment>5__2}, Biome: {<currentBiome>5__3}");
}
else
{
logger.LogWarning((object)"MapHandler.Instance is null during segment detection!");
}
<campfires>5__1 = Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0);
logger.LogInfo((object)$"Found {<campfires>5__1.Length} campfires in new segment");
if (<campfires>5__1.Length != 0)
{
<i>5__4 = 0;
while (<i>5__4 < <campfires>5__1.Length)
{
<campfire>5__5 = <campfires>5__1[<i>5__4];
if ((Object)(object)<campfire>5__5 != (Object)null && (Object)(object)((Component)<campfire>5__5).transform != (Object)null)
{
logger.LogInfo((object)$"Campfire {<i>5__4}: {((Object)<campfire>5__5).name} at {((Component)<campfire>5__5).transform.position}, advances to: {<campfire>5__5.advanceToSegment}");
}
<campfire>5__5 = null;
<i>5__4++;
}
}
else
{
logger.LogWarning((object)"No campfires found in new segment!");
}
if (_campfiresLitCount >= 4)
{
logger.LogInfo((object)$"Campfire #{_campfiresLitCount} lit - Looker spawning complete! No more Lookers will be spawned.");
return false;
}
if (<campfires>5__1.Length >= 2)
{
logger.LogInfo((object)$"Campfire #{_campfiresLitCount} lit - Starting Berrynana dropping process for new segment...");
((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.GenerateSegmentLookerPositions(<campfires>5__1));
}
else
{
logger.LogWarning((object)$"Campfire #{_campfiresLitCount} lit - Only found {<campfires>5__1.Length} campfires, need 2 for spawning");
}
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private Harmony _harmony;
private static ManualLogSource logger;
public static LuridLoomingLookersPlugin Instance;
public static Dictionary<int, float> _lastInjuryTime = new Dictionary<int, float>();
public const float HIDE_DISTANCE = 1f;
public const float STARE_TIME = 1f;
public const float DOT_PRODUCT = 0.8f;
public const float INJURY_AMOUNT = 0.01f;
public const float INJURY_COOLDOWN = 1f;
public const float CLOSE_INJURY_THRESHOLD = 5f;
public const float MAX_ACTIVE_DISTANCE = 40f;
public static List<Vector3> _currentSegmentLookerPositions = new List<Vector3>();
public static bool _segmentPositionsReady = false;
public static List<GameObject> _spawnedLookers = new List<GameObject>();
public static int _campfiresLitCount = 0;
public static AudioClip whisperClip = null;
private static bool audioLoaded = false;
private void Awake()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
Instance = this;
logger = ((BaseUnityPlugin)this).Logger;
_harmony = new Harmony("tony4twentys.Lurid_Looming_Lookers");
_harmony.PatchAll();
byte[] whisperaudio = Resource1.whisperaudio;
AssetBundle val = AssetBundle.LoadFromMemory(whisperaudio);
whisperClip = val.LoadAsset<AudioClip>("ScoutWhispers");
audioLoaded = true;
SceneManager.sceneLoaded += OnSceneLoaded;
logger.LogInfo((object)"Loaded v1.0.0 - Scene detection ready!");
}
private void Update()
{
if (Input.GetKeyDown((KeyCode)289))
{
TestBerrynanaFallTime();
}
UpdateLookerAudio();
}
private void TestBerrynanaFallTime()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Character.localCharacter == (Object)null || (Object)(object)((Component)Character.localCharacter).transform == (Object)null)
{
logger.LogWarning((object)"Cannot test fall time - no local character found!");
return;
}
Vector3 position = ((Component)Character.localCharacter).transform.position;
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(position.x, position.y + 300f, position.z);
logger.LogInfo((object)$"Spawning test Berrynana at {val} (300m above player at {position})");
if (PhotonNetwork.InRoom)
{
GameObject val2 = PhotonNetwork.Instantiate("0_Items/Berrynana Peel Yellow", val, Random.rotation, (byte)0, (object[])null);
if ((Object)(object)val2 != (Object)null)
{
Rigidbody val3 = val2.GetComponent<Rigidbody>();
if ((Object)(object)val3 == (Object)null)
{
val3 = val2.AddComponent<Rigidbody>();
}
val3.mass = 1f;
logger.LogInfo((object)"Test Berrynana spawned successfully! Press F8 again when it lands to measure fall time.");
}
else
{
logger.LogWarning((object)"Failed to spawn test Berrynana!");
}
}
else
{
logger.LogWarning((object)"Cannot spawn test item - not in a Photon room!");
}
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
logger.LogInfo((object)("Scene loaded: " + ((Scene)(ref scene)).name));
if (IsGameLevelScene(((Scene)(ref scene)).name))
{
logger.LogInfo((object)("Game level detected: " + ((Scene)(ref scene)).name));
((MonoBehaviour)this).StartCoroutine(EnableAllLookersAfterDelay());
}
else
{
logger.LogInfo((object)("Non-game scene: " + ((Scene)(ref scene)).name + " - skipping"));
}
}
private bool IsGameLevelScene(string sceneName)
{
return sceneName.StartsWith("Level_");
}
[IteratorStateMachine(typeof(<EnableAllLookersAfterDelay>d__23))]
private IEnumerator EnableAllLookersAfterDelay()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EnableAllLookersAfterDelay>d__23(0)
{
<>4__this = this
};
}
[IteratorStateMachine(typeof(<FindCampfiresAfterDelay>d__24))]
private IEnumerator FindCampfiresAfterDelay()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <FindCampfiresAfterDelay>d__24(0)
{
<>4__this = this
};
}
[IteratorStateMachine(typeof(<WaitForSegmentLoadAndDetect>d__25))]
public IEnumerator WaitForSegmentLoadAndDetect()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForSegmentLoadAndDetect>d__25(0)
{
<>4__this = this
};
}
private void CleanupSpawnedLookers()
{
int num = 0;
for (int num2 = _spawnedLookers.Count - 1; num2 >= 0; num2--)
{
if ((Object)(object)_spawnedLookers[num2] == (Object)null)
{
_spawnedLookers.RemoveAt(num2);
}
else
{
PhotonNetwork.Destroy(_spawnedLookers[num2]);
num++;
_spawnedLookers.RemoveAt(num2);
}
}
logger.LogInfo((object)$"Cleaned up {num} spawned Lookers from previous segment");
}
[IteratorStateMachine(typeof(<GenerateSegmentLookerPositions>d__27))]
public IEnumerator GenerateSegmentLookerPositions(Campfire[] campfires)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <GenerateSegmentLookerPositions>d__27(0)
{
<>4__this = this,
campfires = campfires
};
}
private void SpawnLookersAtPositions(Campfire[] campfires)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0277: Unknown result type (might be due to invalid IL or missing references)
//IL_027c: Unknown result type (might be due to invalid IL or missing references)
//IL_0280: Unknown result type (might be due to invalid IL or missing references)
//IL_0282: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0359: Unknown result type (might be due to invalid IL or missing references)
//IL_0360: Expected O, but got Unknown
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
if (!_segmentPositionsReady || _currentSegmentLookerPositions.Count == 0)
{
logger.LogWarning((object)"No valid positions available for Looker spawning");
return;
}
logger.LogInfo((object)$"Spawning Lookers at {_currentSegmentLookerPositions.Count} positions...");
Vector3 val = Vector3.zero;
if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)((Component)Character.localCharacter).transform != (Object)null)
{
val = ((Component)Character.localCharacter).transform.position;
}
Campfire val2 = null;
float num = 0f;
foreach (Campfire val3 in campfires)
{
if ((Object)(object)val3 != (Object)null && (Object)(object)((Component)val3).transform != (Object)null)
{
float num2 = Vector3.Distance(val, ((Component)val3).transform.position);
if (num2 > num)
{
num = num2;
val2 = val3;
}
}
}
if ((Object)(object)val2 == (Object)null)
{
logger.LogWarning((object)"Could not find target campfire for rock style!");
return;
}
logger.LogInfo((object)$"Using rock style from campfire furthest from player: {((Object)val2).name} at distance {num:F1}m");
GameObject val4 = null;
float num3 = float.MaxValue;
Looker[] array = Object.FindObjectsByType<Looker>((FindObjectsSortMode)0);
Looker[] array2 = array;
foreach (Looker val5 in array2)
{
if ((Object)(object)val5 != (Object)null && (Object)(object)((Component)val5).transform != (Object)null)
{
float num4 = Vector3.Distance(((Component)val2).transform.position, ((Component)val5).transform.position);
if (num4 < num3)
{
num3 = num4;
val4 = ((Component)val5).gameObject;
}
}
}
if ((Object)(object)val4 == (Object)null)
{
logger.LogWarning((object)"No Lookers found near target campfire! Using first available Looker as fallback.");
if (array.Length == 0)
{
logger.LogError((object)"No existing Lookers found to use as templates!");
return;
}
val4 = ((Component)array[0]).gameObject;
}
else
{
logger.LogInfo((object)$"Found Looker template near target campfire at distance {num3:F1}m");
}
int num5 = 0;
val4.gameObject.SetActive(false);
PunExtensions.GetPhotonView(val4).ViewID = 0;
foreach (Vector3 currentSegmentLookerPosition in _currentSegmentLookerPositions)
{
GameObject val6 = Object.Instantiate<GameObject>(val4, currentSegmentLookerPosition, Quaternion.identity);
if ((Object)(object)val6 == (Object)null)
{
continue;
}
int viewID = PhotonNetwork.AllocateViewID(Object.op_Implicit((Object)(object)val6));
PunExtensions.GetPhotonView(val6).ViewID = viewID;
val6.SetActive(true);
Looker componentInChildren = val6.GetComponentInChildren<Looker>();
if ((Object)(object)componentInChildren != (Object)null)
{
((Behaviour)componentInChildren).enabled = true;
Transform val7 = val6.transform.Find("guy");
if ((Object)(object)val7 != (Object)null)
{
((Component)val7).gameObject.SetActive(true);
logger.LogInfo((object)("Activated guy GameObject for " + ((Object)val6).name));
}
else
{
foreach (Transform item in val6.transform)
{
Transform val8 = item;
if (((Object)((Component)val8).gameObject).name.ToLower().Contains("guy") || ((Object)((Component)val8).gameObject).name.ToLower().Contains("looker") || ((Object)((Component)val8).gameObject).name.ToLower().Contains("visual") || ((Object)((Component)val8).gameObject).name.ToLower().Contains("model"))
{
((Component)val8).gameObject.SetActive(true);
logger.LogInfo((object)("Activated visual child: " + ((Object)val8).name + " for " + ((Object)val6).name));
}
}
}
Animator componentInChildren2 = val6.GetComponentInChildren<Animator>();
if ((Object)(object)componentInChildren2 != (Object)null)
{
((Behaviour)componentInChildren2).enabled = true;
logger.LogInfo((object)("Enabled Animator for " + ((Object)val6).name));
}
Component component = val6.GetComponent("SpineCheck");
if ((Object)(object)component != (Object)null)
{
PropertyInfo property = ((object)component).GetType().GetProperty("enabled");
if (property != null)
{
property.SetValue(component, true);
logger.LogInfo((object)("Enabled SpineCheck for " + ((Object)val6).name));
}
}
else
{
component = val6.GetComponentInChildren(Type.GetType("SpineCheck"));
if ((Object)(object)component != (Object)null)
{
PropertyInfo property2 = ((object)component).GetType().GetProperty("enabled");
if (property2 != null)
{
property2.SetValue(component, true);
logger.LogInfo((object)("Enabled SpineCheck (in child) for " + ((Object)val6).name));
}
}
}
try
{
FieldInfo field = typeof(Looker).GetField("isActive", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(componentInChildren, true);
logger.LogInfo((object)("Manually set isActive=true for " + ((Object)val6).name));
}
}
catch (Exception ex)
{
logger.LogInfo((object)("Could not set isActive field: " + ex.Message));
}
}
((Object)val6).name = $"SpawnedLooker_{num5}";
SetupLookerAudio(val6);
_spawnedLookers.Add(val6);
num5++;
}
logger.LogInfo((object)$"Successfully spawned {num5} Lookers!");
}
private void SetupLookerAudio(GameObject looker)
{
if (audioLoaded && !((Object)(object)whisperClip == (Object)null))
{
AudioSource val = looker.GetComponent<AudioSource>();
if ((Object)(object)val == (Object)null)
{
val = looker.AddComponent<AudioSource>();
}
val.clip = whisperClip;
val.loop = true;
val.playOnAwake = false;
val.spatialBlend = 1f;
val.rolloffMode = (AudioRolloffMode)0;
val.minDistance = 1f;
val.maxDistance = 40f;
val.volume = 0.8f;
val.pitch = Random.Range(0.9f, 1.1f);
val.dopplerLevel = 0f;
logger.LogInfo((object)("Added 3D audio to " + ((Object)looker).name));
}
}
private void UpdateLookerAudio()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
if (!audioLoaded || (Object)(object)whisperClip == (Object)null || (Object)(object)Character.localCharacter == (Object)null)
{
return;
}
Vector3 center = Character.localCharacter.Center;
List<(GameObject, float, AudioSource)> list = new List<(GameObject, float, AudioSource)>();
foreach (GameObject spawnedLooker in _spawnedLookers)
{
if (!((Object)(object)spawnedLooker == (Object)null))
{
AudioSource component = spawnedLooker.GetComponent<AudioSource>();
if (!((Object)(object)component == (Object)null))
{
float item = Vector3.Distance(center, spawnedLooker.transform.position);
list.Add((spawnedLooker, item, component));
}
}
}
list.Sort(((GameObject looker, float distance, AudioSource audioSource) a, (GameObject looker, float distance, AudioSource audioSource) b) => a.distance.CompareTo(b.distance));
for (int i = 0; i < list.Count; i++)
{
var (val, num, val2) = list[i];
if (num <= 40f)
{
if (i < 3)
{
if (!val2.isPlaying)
{
val2.Play();
logger.LogInfo((object)$"Started audio for {((Object)val).name} at distance {num:F1}m (priority {i + 1})");
}
float volume = ((!(num <= 20f)) ? 0.5f : 1f);
val2.volume = volume;
}
else if (val2.isPlaying)
{
val2.Stop();
logger.LogInfo((object)$"Stopped audio for {((Object)val).name} at distance {num:F1}m (priority {i + 1}, too low)");
}
}
else if (val2.isPlaying)
{
val2.Stop();
logger.LogInfo((object)$"Stopped audio for {((Object)val).name} at distance {num:F1}m (out of range)");
}
}
}
}
[HarmonyPatch(typeof(Looker), "Start")]
public static class Looker_Start_Patch
{
private static void Postfix(Looker __instance, ref GameObject ___guy)
{
if ((Object)(object)___guy != (Object)null)
{
___guy.SetActive(true);
Debug.Log((object)("[LuridLoomingLookers] Forced " + ((Object)((Component)__instance).gameObject).name + " guy active"));
}
}
}
[HarmonyPatch(typeof(Looker), "ToggleLookers")]
public static class Looker_ToggleLookers_Patch
{
private static bool Prefix()
{
Debug.Log((object)"[LuridLoomingLookers] Skipped ToggleLookers - keeping all Lookers enabled");
return false;
}
}
[HarmonyPatch(typeof(Looker), "Update")]
public static class Looker_Update_Patch
{
private static void Postfix(Looker __instance, ref bool ___neverReturn, ref bool ___isActive, Transform ___pivot, ref float ___hasLookedAtMeFor, Animator ___anim)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)___pivot != (Object)null) || !((Object)(object)MainCamera.instance != (Object)null))
{
return;
}
float num = Vector3.Distance(((Component)MainCamera.instance).transform.position, ___pivot.position);
if (num < 1f || num > 40f)
{
if (___isActive)
{
___isActive = false;
___anim.SetBool("IsActive", false);
___hasLookedAtMeFor = 0f;
Debug.Log((object)$"[LuridLoomingLookers] {((Object)((Component)__instance).gameObject).name} went inactive (distance: {num:F1}m)");
}
}
else
{
if (!___isActive)
{
___isActive = true;
___anim.SetBool("IsActive", true);
Debug.Log((object)$"[LuridLoomingLookers] {((Object)((Component)__instance).gameObject).name} became active (distance: {num:F1}m)");
}
if ((Object)(object)((Component)__instance).GetComponent<PhotonView>() == (Object)null && ___hasLookedAtMeFor >= 1f)
{
___hasLookedAtMeFor = 0f;
int instanceID = ((Object)__instance).GetInstanceID();
if (LuridLoomingLookersPlugin._lastInjuryTime.ContainsKey(instanceID))
{
float num2 = Time.time - LuridLoomingLookersPlugin._lastInjuryTime[instanceID];
if (num2 < 1f)
{
return;
}
}
Transform transform = ((Component)MainCamera.instance).transform;
Vector3 forward = transform.forward;
Vector3 val = ((Component)__instance).transform.position - transform.position;
float num3 = Vector3.Dot(forward, ((Vector3)(ref val)).normalized);
bool flag = num3 > 0.8f;
bool flag2 = false;
string text = "";
if (num >= 1.5f && num <= 5f)
{
flag2 = true;
text = $"close range ({num:F1}m)";
}
else if (num > 5f && num <= 40f && flag)
{
flag2 = true;
text = $"staring at {num:F1}m (dot: {num3:F2})";
}
if (flag2)
{
Debug.Log((object)("[LuridLoomingLookers] SPAWNED LOOKER CODE RED: " + ((Object)((Component)__instance).gameObject).name + " - " + text));
if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.refs?.afflictions != (Object)null)
{
Character.localCharacter.refs.afflictions.AddStatus((STATUSTYPE)0, 0.01f, false);
LuridLoomingLookersPlugin._lastInjuryTime[instanceID] = Time.time;
Debug.Log((object)$"[LuridLoomingLookers] Applied {0.01f} Injury damage to {Character.localCharacter.characterName}");
}
}
}
}
___neverReturn = false;
}
}
[HarmonyPatch(typeof(Looker), "RPCA_CodeRed")]
public static class Looker_RPCA_CodeRed_Patch
{
private static bool Prefix(Looker __instance, Animator ___anim, ref bool ___neverReturn)
{
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
if (!((Behaviour)__instance).isActiveAndEnabled)
{
Debug.Log((object)("[LuridLoomingLookers] CODE RED ignored on inactive Looker " + ((Object)((Component)__instance).gameObject).name));
return false;
}
int instanceID = ((Object)__instance).GetInstanceID();
float num = 0f;
if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)((Component)__instance).transform != (Object)null)
{
num = Vector3.Distance(((Component)MainCamera.instance).transform.position, ((Component)__instance).transform.position);
}
if (LuridLoomingLookersPlugin._lastInjuryTime.ContainsKey(instanceID))
{
float num2 = Time.time - LuridLoomingLookersPlugin._lastInjuryTime[instanceID];
if (num2 < 1f)
{
Debug.Log((object)$"[LuridLoomingLookers] CODE RED blocked on {((Object)((Component)__instance).gameObject).name} - cooldown active ({num2:F1}s/{1f:F1}s)");
return false;
}
}
Transform transform = ((Component)MainCamera.instance).transform;
Vector3 forward = transform.forward;
Vector3 val = ((Component)__instance).transform.position - transform.position;
float num3 = Vector3.Dot(forward, ((Vector3)(ref val)).normalized);
bool flag = num3 > 0.8f && num < 40f;
bool flag2 = false;
string text = "";
if (num >= 1.5f && num <= 5f)
{
flag2 = true;
text = $"close range ({num:F1}m)";
}
else if (num > 5f && num <= 40f && flag)
{
flag2 = true;
text = $"staring at {num:F1}m (dot: {num3:F2})";
}
if (flag2)
{
Debug.Log((object)("[LuridLoomingLookers] CODE RED triggered on " + ((Object)((Component)__instance).gameObject).name + " - " + text));
if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.refs?.afflictions != (Object)null)
{
Character.localCharacter.refs.afflictions.AddStatus((STATUSTYPE)0, 0.01f, false);
LuridLoomingLookersPlugin._lastInjuryTime[instanceID] = Time.time;
Debug.Log((object)$"[LuridLoomingLookers] Applied {0.01f} Injury damage to {Character.localCharacter.characterName}");
}
}
else
{
Debug.Log((object)$"[LuridLoomingLookers] CODE RED triggered on {((Object)((Component)__instance).gameObject).name} at {num:F1}m - but conditions not met (looking: {flag}, dot: {num3:F2})");
}
return false;
}
}
[HarmonyPatch(typeof(Looker), "RPCA_Switch")]
public static class Looker_RPCA_Switch_Patch
{
private static bool Prefix(Looker __instance)
{
if ((Object)(object)((Component)__instance).GetComponent<PhotonView>() == (Object)null)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Looker), "RPCA_DisableLooker")]
public static class Looker_RPCA_DisableLooker_Patch
{
private static bool Prefix()
{
Debug.Log((object)"[LuridLoomingLookers] Blocked RPCA_DisableLooker - keeping Looker active");
return false;
}
}
[HarmonyPatch(typeof(Debug), "Log", new Type[] { typeof(object) })]
public static class Debug_Log_Patch
{
private static bool Prefix(object message)
{
string text = message?.ToString() ?? "";
if (text.Contains("[LuridLoomingLookers]"))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Debug), "LogWarning", new Type[] { typeof(object) })]
public static class Debug_LogWarning_Patch
{
private static bool Prefix(object message)
{
string text = message?.ToString() ?? "";
if (text.Contains("Received RPC") && text.Contains("but this PhotonView does not exist") && text.Contains("RPCA_Switch"))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
public static class Campfire_Light_Rpc_Patch
{
private static void Postfix(Campfire __instance)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
LuridLoomingLookersPlugin._campfiresLitCount++;
Debug.Log((object)$"[LuridLoomingLookers] Campfire #{LuridLoomingLookersPlugin._campfiresLitCount} lit at {((Component)__instance).transform.position}! Waiting for segment to load...");
LuridLoomingLookersPlugin instance = LuridLoomingLookersPlugin.Instance;
if (instance != null)
{
((MonoBehaviour)instance).StartCoroutine(LuridLoomingLookersPlugin.Instance.WaitForSegmentLoadAndDetect());
}
}
}
}