using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using LethalOtisMod;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("LethalOtis")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalOtis")]
[assembly: AssemblyTitle("LethalOtis")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
public class OtisCurse : NetworkBehaviour
{
[CompilerGenerated]
private sealed class <ShrinkRoutine>d__9 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public Transform targetTransform;
public Vector3 targetScale;
public float duration;
public OtisCurse <>4__this;
private Vector3 <startingScale>5__1;
private float <elapsedTime>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ShrinkRoutine>d__9(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<startingScale>5__1 = targetTransform.localScale;
<elapsedTime>5__2 = 0f;
break;
case 1:
<>1__state = -1;
break;
}
if (<elapsedTime>5__2 < duration)
{
if ((Object)(object)targetTransform == (Object)null)
{
return false;
}
targetTransform.localScale = Vector3.Lerp(<startingScale>5__1, targetScale, <elapsedTime>5__2 / duration);
<elapsedTime>5__2 += Time.deltaTime;
<>2__current = null;
<>1__state = 1;
return true;
}
if ((Object)(object)targetTransform != (Object)null)
{
targetTransform.localScale = targetScale;
}
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 <WaitForMicToStart>d__15 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public OtisCurse <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitForMicToStart>d__15(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
break;
}
if (Microphone.GetPosition(<>4__this.selectedMicDevice) <= 0)
{
<>2__current = null;
<>1__state = 1;
return true;
}
<>4__this.debugMicSource.Play();
Plugin.logger.LogInfo((object)$"Mic Test Started! Playing back at Pitch: {<>4__this.debugMicSource.pitch}");
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();
}
}
[Header("Curse Settings")]
public float shrinkDuration = 60f;
public float targetScale = 0.75f;
public float targetPitch = 1.5f;
public AudioSource headAudioSource;
public AudioClip curseSoundEffect;
private bool playerCursed = false;
public static List<ulong> cursedPlayerIDs = new List<ulong>();
private AudioSource debugMicSource;
private string selectedMicDevice;
private void OnTriggerEnter(Collider other)
{
if (((NetworkBehaviour)this).IsServer)
{
PlayerControllerB componentInParent = ((Component)other).gameObject.GetComponentInParent<PlayerControllerB>();
if ((Object)(object)componentInParent != (Object)null && !cursedPlayerIDs.Contains(componentInParent.playerClientId))
{
cursedPlayerIDs.Add(componentInParent.playerClientId);
ShrinkPlayerClientRpc(componentInParent.playerClientId);
}
}
}
[ClientRpc]
public void ShrinkPlayerClientRpc(ulong playerId)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId];
if (!cursedPlayerIDs.Contains(playerId))
{
cursedPlayerIDs.Add(playerId);
}
((MonoBehaviour)this).StartCoroutine(ShrinkRoutine(((Component)val).transform, Vector3.one * targetScale, shrinkDuration));
val.movementSpeed *= targetScale;
val.jumpForce *= targetScale;
SoundManager.Instance.playerVoicePitchTargets[(uint)playerId] = targetPitch;
SoundManager.Instance.SetPlayerPitch(targetPitch, (int)playerId);
if ((Object)(object)headAudioSource != (Object)null && (Object)(object)curseSoundEffect != (Object)null)
{
headAudioSource.PlayOneShot(curseSoundEffect);
}
Plugin.logger.LogInfo((object)(val.playerUsername + " got hit by Otis!"));
}
[IteratorStateMachine(typeof(<ShrinkRoutine>d__9))]
private IEnumerator ShrinkRoutine(Transform targetTransform, Vector3 targetScale, float duration)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ShrinkRoutine>d__9(0)
{
<>4__this = this,
targetTransform = targetTransform,
targetScale = targetScale,
duration = duration
};
}
private PlayerControllerB GetPlayerById(ulong playerId)
{
GameObject[] allPlayerObjects = StartOfRound.Instance.allPlayerObjects;
foreach (GameObject val in allPlayerObjects)
{
PlayerControllerB component = val.GetComponent<PlayerControllerB>();
if ((Object)(object)component != (Object)null && component.playerClientId == playerId)
{
return component;
}
}
return null;
}
private void LateUpdate()
{
if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)SoundManager.Instance == (Object)null || cursedPlayerIDs.Count <= 0)
{
return;
}
for (int num = cursedPlayerIDs.Count - 1; num >= 0; num--)
{
ulong num2 = cursedPlayerIDs[num];
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[num2];
if ((Object)(object)val == (Object)null || val.disconnectedMidGame)
{
cursedPlayerIDs.RemoveAt(num);
}
else
{
SoundManager.Instance.playerVoicePitchTargets[(uint)num2] = 1.6f;
SoundManager.Instance.SetPlayerPitch(1.6f, (int)num2);
}
}
}
private void StartMicLoopback()
{
if ((Object)(object)debugMicSource == (Object)null)
{
debugMicSource = ((Component)this).gameObject.AddComponent<AudioSource>();
debugMicSource.spatialBlend = 0f;
}
int num = (int)StartOfRound.Instance.localPlayerController.playerClientId;
debugMicSource.pitch = 1.6f;
if (Microphone.devices.Length != 0)
{
selectedMicDevice = Microphone.devices[0];
debugMicSource.clip = Microphone.Start(selectedMicDevice, true, 1, 44100);
debugMicSource.loop = true;
((MonoBehaviour)this).StartCoroutine(WaitForMicToStart());
}
else
{
Plugin.logger.LogWarning((object)"No microphone detected for testing!");
}
}
[IteratorStateMachine(typeof(<WaitForMicToStart>d__15))]
private IEnumerator WaitForMicToStart()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForMicToStart>d__15(0)
{
<>4__this = this
};
}
private void StopMicLoopback()
{
if ((Object)(object)debugMicSource != (Object)null && debugMicSource.isPlaying)
{
debugMicSource.Stop();
Microphone.End(selectedMicDevice);
Plugin.logger.LogInfo((object)"Mic Test Ended.");
}
}
}
public class OtisRoam : NetworkBehaviour
{
private NavMeshAgent agent;
[Header("Roaming Settings")]
public float detectionRadius = 15f;
public float NormalSpeed = 3f;
public float StalkSpeed = 4.5f;
private bool isChasing = false;
private float timeSinceLastSeen = 0f;
private Vector3 lastKnownPosition;
public float giveUpTime = 3f;
public float WanderDistance = 20f;
public float MaxWanderTime = 7.5f;
private float WanderTimer = 0f;
public Animator animator;
private Vector3 previousPosition;
private void Start()
{
if (!((NetworkBehaviour)this).IsServer)
{
return;
}
((MonoBehaviour)this).Invoke("InitializeAgent", 2f);
if ((Object)(object)animator == (Object)null)
{
animator = ((Component)this).GetComponentInChildren<Animator>();
if ((Object)(object)animator != (Object)null)
{
Plugin.logger.LogInfo((object)"Successfully linked Animator!");
}
else
{
Plugin.logger.LogWarning((object)"CRITICAL: No Animator component found!");
}
}
}
private void InitializeAgent()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
agent = ((Component)this).GetComponent<NavMeshAgent>();
Plugin.logger.LogInfo((object)"Otis initialized!");
NavMeshHit val = default(NavMeshHit);
if (NavMesh.SamplePosition(((Component)this).transform.position, ref val, 10f, -1))
{
agent.Warp(((NavMeshHit)(ref val)).position);
agent.speed = 3.5f;
Plugin.logger.LogInfo((object)"Fixing Otis NavMeshAgent! (Might be working though)");
}
}
private void Update()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)animator != (Object)null)
{
float num = Vector3.Distance(((Component)this).transform.position, previousPosition) / Time.deltaTime;
animator.SetFloat("Speed", num);
previousPosition = ((Component)this).transform.position;
}
if (!((NetworkBehaviour)this).IsServer || (Object)(object)agent == (Object)null || !agent.isOnNavMesh)
{
return;
}
PlayerControllerB val = null;
float num2 = detectionRadius;
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val2 in allPlayerScripts)
{
if (!val2.isPlayerDead && val2.isInsideFactory && !OtisCurse.cursedPlayerIDs.Contains(val2.playerClientId))
{
float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
if (num3 < num2)
{
num2 = num3;
val = val2;
}
}
}
if ((Object)(object)val != (Object)null)
{
StalkPlayer(val);
}
else
{
HandleWandering();
}
}
private void StalkPlayer(PlayerControllerB target)
{
//IL_0007: 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_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position;
float num = Vector3.Distance(((Component)this).transform.position, ((Component)target).transform.position);
bool flag = false;
RaycastHit val2 = default(RaycastHit);
if (Physics.Raycast(((Component)this).transform.position, val, ref val2, num, StartOfRound.Instance.collidersAndRoomMask))
{
if ((Object)(object)((Component)((RaycastHit)(ref val2)).collider).gameObject.GetComponentInParent<PlayerControllerB>() != (Object)null)
{
flag = true;
}
}
else
{
flag = true;
}
if (flag)
{
isChasing = true;
timeSinceLastSeen = 0f;
lastKnownPosition = ((Component)target).transform.position;
agent.speed = StalkSpeed;
agent.SetDestination(lastKnownPosition);
}
else if (isChasing)
{
timeSinceLastSeen += Time.deltaTime;
agent.SetDestination(lastKnownPosition);
if (timeSinceLastSeen >= giveUpTime)
{
isChasing = false;
timeSinceLastSeen = 0f;
Plugin.logger.LogInfo((object)"Otis gave up chasing!");
HandleWandering();
}
}
else
{
HandleWandering();
}
}
private void HandleWandering()
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
if (((NetworkBehaviour)this).IsServer && !((Object)(object)agent == (Object)null) && agent.isOnNavMesh)
{
WanderTimer += Time.deltaTime;
if (MaxWanderTime <= WanderTimer || agent.remainingDistance <= agent.stoppingDistance)
{
Vector3 destination = RandomNavSphere(((Component)this).transform.position, WanderDistance, -1);
agent.SetDestination(destination);
agent.speed = NormalSpeed;
WanderTimer = 0f;
}
}
}
private void OnTriggerEnter(Collider other)
{
DoorLock componentInParent = ((Component)other).gameObject.GetComponentInParent<DoorLock>();
if ((Object)(object)componentInParent != (Object)null && !componentInParent.isDoorOpened && !componentInParent.isLocked)
{
componentInParent.OpenDoorAsEnemyServerRpc();
Plugin.logger.LogInfo((object)"Otis opened a door!");
}
}
public static Vector3 RandomNavSphere(Vector3 origin, float dist, int layermask)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: 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_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Random.insideUnitSphere * dist;
val += origin;
NavMeshHit val2 = default(NavMeshHit);
if (NavMesh.SamplePosition(val, ref val2, dist, layermask))
{
return ((NavMeshHit)(ref val2)).position;
}
return origin;
}
}
namespace LethalOtisMod
{
[BepInPlugin("com.bazookaben.LethalOtis", "LethalOtis", "1.2.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.bazookaben.LethalOtis";
public const string PLUGIN_NAME = "LethalOtis";
public const string PLUGIN_VERSION = "1.2.1";
}
public static ManualLogSource logger;
private readonly Harmony harmony = new Harmony("com.BazookaB3n.LethalOtis");
public static AssetBundle ModAssets;
private void Awake()
{
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Expected O, but got Unknown
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Expected O, but got Unknown
logger = ((BaseUnityPlugin)this).Logger;
logger.LogInfo((object)"Plugin com.bazookaben.LethalOtis is loading...");
logger.LogInfo((object)"OTIS WAS HERE! BOOM BEACH TOO!");
logger.LogInfo((object)"Old mod was banned so here we are...");
string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "modassets");
ModAssets = AssetBundle.LoadFromFile(text);
if ((Object)(object)ModAssets == (Object)null)
{
logger.LogError((object)"Failed to load Mod Assets!");
return;
}
harmony.PatchAll();
GameObject val = ModAssets.LoadAsset<GameObject>("Otis");
if ((Object)(object)val == (Object)null)
{
logger.LogError((object)"Failed to load the prefab 'Otis' from the bundle!");
return;
}
NetworkPrefabs.RegisterNetworkPrefab(val);
SpawnableMapObject OtisHazard = new SpawnableMapObject();
OtisHazard.prefabToSpawn = val;
OtisHazard.spawnFacingAwayFromWall = false;
OtisHazard.numberToSpawn = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
{
new Keyframe(0f, 0.3f),
new Keyframe(1f, 1.3f)
});
MapObjects.RegisterMapObject(OtisHazard, (LevelTypes)(-1), (string[])null, (Func<SelectableLevel, AnimationCurve>)((SelectableLevel level) => OtisHazard.numberToSpawn));
logger.LogInfo((object)"Otis successfully registered into enemy spawn pool!");
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class CurseResetPatch
{
[HarmonyPatch("ReviveDeadPlayers")]
[HarmonyPostfix]
private static void ResetAllCurses()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
OtisCurse.cursedPlayerIDs.Clear();
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
val.movementSpeed = 4.6f;
val.jumpForce = 13f;
((Component)val).transform.localScale = Vector3.one;
SoundManager.Instance.playerVoicePitchTargets[(uint)val.playerClientId] = 1f;
SoundManager.Instance.SetPlayerPitch(1f, (int)val.playerClientId);
}
Plugin.logger.LogInfo((object)"The Otis effects have been cleared!");
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}